Câu hỏi Nội suy song tuyến để phóng to hình ảnh bitmap


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

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 phải thực hiện nội suy tuyến tính trên mảng. Tôi không hiểu toán học đằng sau nó (ngay cả sau khi trải qua bài viết wiki 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 một liên kết đến một thuật toán nội suy song tuyến hiện có trên một mảng 1-D? 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?


7
2018-01-10 19:06


gốc


Bạn đã được giao nhiệm vụ viết của riêng bạn, mặc dù? - Drew Dormann
Không phải là nội suy song tuyến theo định nghĩa có nghĩa là cho mảng 2D? - Phonon
@Phonon: Dành cho hình ảnh 2 chiều. Nhưng một hình ảnh 2-D có thể được ánh xạ lên một mảng 1-D (rất hiếm khi tìm thấy các ứng dụng C ++ sử dụng các mảng 2-D thực). - Ben Voigt
@BenVoigt Rất đúng, nhưng nó vẫn là một ma trận khái niệm. - Phonon
Bạn có hiểu toán học đằng sau nội suy tuyến tính đơn giản không? Nếu bạn hiểu điều đó, bạn sẽ hiểu điều này với một chút suy nghĩ. Nó không phức tạp như bạn nghĩ ... - Tim Kemp


Các câu trả lời:


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ở. Cho một số vị trí một mà 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 tôi chỉ 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 ta có thể tấn công vấn đề tìm kiếm f (a, b) bất cứ gì a, b bằng cách làm 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 phép nội suy song tuyến, chúng ta lại 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 dự án của chúng tôi (a, b) sang hai bên và đầu tiên tính hai đường nội suy (một chiều!).

  • f (a, yj) Ở đâu yj được tổ chức liên tục
  • f (a, yj + 1) Ở đâu yj + 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, f (a, yj) và f (a, yj + 1)và phù hợp với 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 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.


37
2018-01-10 20:15



Hình ảnh tuyệt vời và độc đáo giải thích - pezcode
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


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

Xem hình ảnh trong VÍ DỤ RESAGE RESIZE.

Các f(x,y)=... công thức trong bài viết này trên Wikipedia cung cấp cho bạn một phương pháp để tính màu f của pixel được chèn:

enter image description here

Đối với mỗi pixel được chèn, bạn kết hợp màu 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 điểm ảnh được chèn vào và các điểm ảnh ban đầu xung quanh, nó càng gần với một điểm ảnh, màu sắc của chúng càng gần hơn:

enter image description here

Các điểm ảnh ban đầu được hiển thị dưới dạng 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 một yếu tố không tách rời, các 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 các pixel ban đầu và chỉ cần chèn thêm các pixel giữa chúng.


9
2018-01-10 19:45





Không được treo lên trên thực tế là 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ột 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 về giá trị tại 1.4. Bạn sẽ cho tôi một kết hợp trọng số của các giá trị tại 1 và 2: (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. Nói bạn muốn (1.4, 2.8). Lấy các nội suy 1D giữa (1, 2)<->(2,2) và (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.

Điều này nên đơn giản để làm cho ồ ạt song song. 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.


3
2018-01-10 19:49