2012-01-10 44 views
7

Tôi là sinh viên và tôi đã được giao nhiệm vụ tối ưu hóa phép nội suy song tuyến của hình ảnh bằng cách gọi song song từ CUDA.Nội suy song song để phóng to hình ảnh bitmap

Hình ảnh được cung cấp dưới dạng định dạng .bmp 24 bit. Tôi đã có một người đọc cho .bmp và đã lưu trữ các điểm ảnh trong một mảng.

Bây giờ tôi cần thực hiện nội suy song tuyến trên mảng. Tôi không hiểu toán học đằng sau nó (ngay cả sau khi trải qua wiki article và các kết quả khác của Google). Bởi vì điều này tôi không thể đưa ra một thuật toán.

Có ai có thể giúp tôi với liên kết đến thuật toán nội suy song tuyến hiện có trên mảng 1-D không? Hoặc có lẽ liên kết đến một thư viện xử lý hình ảnh nguồn mở sử dụng nội suy song tuyến và lưỡng tính để chia tỷ lệ hình ảnh?

+2

Bạn đã được giao nhiệm vụ tự viết của riêng mình? –

+4

Không phải là nội suy tuyến tính theo định nghĩa có nghĩa là đối với mảng 2D? – Phonon

+0

Mục tiêu chính của tôi là tối ưu hóa nó thông qua CUDA. Vậy việc chia tỷ lệ hình ảnh được thực hiện thông qua bilinear chỉ là một bước trung gian. Nên chỉnh sửa bài đăng của tôi. Giáo sư muốn kết quả tối ưu hóa, vì vậy phần còn lại tùy thuộc vào tôi. Với thuật toán, sau đó tôi có thể chuyển sang gọi CUDA để thực hiện nó với tính song song để tăng tốc nó.:) – f0rfun

Trả lời

37

Cách dễ nhất để hiểu nội suy tuyến tính là hiểu nội suy tuyến tính trong 1D.

Con số đầu tiên này sẽ cho bạn hồi tưởng về toán trung học cơ sở. Với một số vị trí a mà tại đó chúng tôi muốn biết f (a), chúng tôi lấy các giá trị "được biết" lân cận và phù hợp với một đường thẳng giữa chúng.

Linear interpolation in 1D.

Vì vậy, chúng ta chỉ cần sử dụng các phương trình trung học cũ y = mx + b và y-y1 = m (x-x1). Không có gì lạ mắt.

Về cơ bản, chúng tôi chuyển khái niệm này sang 2-D để có được nội suy song tuyến. Chúng tôi có thể tấn công vấn đề tìm kiếm f (a, b) cho bất kỳ a, b bằng cách thực hiện ba nội suy. Nghiên cứu kỹ hình tiếp theo. Không bị đe dọa bởi tất cả các nhãn. Nó thực sự khá đơn giản.

Bilinear interpolation as three 1D interpolations.

Đối với một suy Bilinear, chúng tôi một lần nữa sử dụng các điểm lân cận. Bây giờ có bốn trong số chúng, vì chúng ta đang ở dạng 2D. Bí quyết là để tấn công vấn đề một chiều tại một thời điểm.

Chúng tôi chiếu (a, b) vào các cạnh và tính toán hai dòng nội suy (một chiều!) Đầu tiên.

  • f (a, y j) nơi y j được tổ chức liên tục
  • f (a, y j + 1) nơi y j + 1 được giữ không đổi.

Bây giờ, chỉ có một bước cuối cùng. Bạn lấy hai điểm bạn tính toán, f (a, y j) f (a, y j + 1), và phù hợp với một ranh giới giữa chúng. Đó là màu xanh lam từ trái sang phải trong biểu đồ, đi qua f (a, b). Nội suy dọc theo dòng cuối cùng này cung cấp cho bạn câu trả lời cuối cùng.

Tôi sẽ để lại toán cho trường hợp 2-D cho bạn. Nó không khó nếu bạn làm việc từ sơ đồ. Và tự mình trải qua nó sẽ giúp bạn thực sự học được những gì đang xảy ra.

Một lưu ý nhỏ cuối cùng, không quan trọng bạn chọn hai bên nào cho hai nội suy đầu tiên. Bạn có thể chọn đỉnh và đáy, và sau đó thực hiện đường nội suy thứ ba giữa hai cái đó. Câu trả lời sẽ giống nhau.

+0

Những hình ảnh tuyệt vời và được giải thích một cách độc đáo – pezcode

+0

Cảm ơn bạn! Điều này, và câu trả lời của @ Alex với nhau đã thực sự mang tính hướng dẫn về cách hoạt động của nội suy song tuyến. – blahman

9

Khi bạn phóng to hình ảnh bằng cách chia tỷ lệ các cạnh thành một yếu tố không thể tách rời, bạn có thể coi kết quả là hình ảnh gốc có thêm pixel được chèn giữa các pixel ban đầu.

Xem ảnh trong IMAGE RESIZE EXAMPLE.

Các f(x,y)=... thức trong this article in Wikipedia mang đến cho bạn một phương pháp để tính toán màu f của một điểm ảnh chèn vào:

enter image description here

Đối với mỗi điểm chèn bạn kết hợp các màu sắc của 4 pixel gốc (Q11, Q12, Q21, Q22) xung quanh nó. Sự kết hợp phụ thuộc vào khoảng cách giữa các điểm ảnh chèn vào và các điểm ảnh ban đầu xung quanh, gần gũi hơn nó là một trong số họ, màu sắc của họ gần gũi hơn bao gồm:

enter image description here

Các điểm ảnh ban đầu được hiển thị như màu đỏ. Pixel được chèn được hiển thị dưới dạng màu xanh lục.

Đó là ý tưởng.

Nếu bạn mở rộng các cạnh bằng yếu tố không tách rời, công thức vẫn giữ, nhưng bây giờ bạn cần phải tính toán lại tất cả các màu pixel vì bạn không thể lấy pixel gốc và chỉ cần chèn thêm pixel giữa chúng.

3

Không bị treo trên thực tế là các mảng 2D trong C thực sự là mảng 1D. Đó là một chi tiết thực hiện. Về mặt toán học, bạn vẫn sẽ cần phải suy nghĩ về mảng 2D.

Suy nghĩ về nội suy tuyến tính trên mảng 1D. Bạn biết giá trị tại 0, 1, 2, 3, ... Bây giờ giả sử tôi hỏi bạn giá trị tại 1.4. Bạn sẽ cho tôi một kết hợp có trọng số của các giá trị tại 12: (1 - 0.4)*A[1] + 0.4*A[2]. Đơn giản, phải không?

Bây giờ bạn cần mở rộng sang 2D. Không vấn đề gì. Nội suy 2D có thể được phân tách thành hai nội suy 1D, trong trục x và sau đó là trục y. Giả sử bạn muốn (1.4, 2.8). Nhận nội suy 1D giữa (1, 2)<->(2,2)(1,3)<->(2,3). Đó là bước trục x của bạn. Bây giờ 1D nội suy giữa chúng với các trọng số thích hợp cho y = 2.8.

Việc này đơn giản để thực hiện song song một cách ồ ạt. Chỉ cần tính từng pixel nội suy một cách riêng biệt. Với quyền truy cập bộ nhớ được chia sẻ vào hình ảnh gốc, bạn sẽ chỉ thực hiện đọc, do đó không có sự cố đồng bộ hóa.