Làm thế nào một người áp dụng FFT chính xác trong khử nhiễu hình ảnh


8

Tôi đang viết chương trình (widget Qt / c ++) để loại bỏ nhiễu khỏi hình ảnh. Là phương pháp khử nhiễu, tôi chọn phương thức không cục bộ . Phương pháp này có chất lượng hình ảnh được khôi phục đáng kinh ngạc (đó là lý do tại sao nó là phương pháp khử nhiễu duy nhất trong OpenCV), nhưng có chi phí tính toán rất lớn , vì vậy tôi đã thực hiện rất nhiều biến thể sửa đổi của phương pháp này (một số với đa luồng, một số thuật toán). Nhưng, tôi đang gặp vấn đề với cái này, liên quan đến FFT

Tôi đã làm theo tất cả các bước của bài viết này (chỉ một trang, 1430) và tất cả đều hoạt động hoàn hảo, ngoại trừ phần FFT, chỉ có 2 dòng về nó trong bài báo và tôi không thể hiểu, làm thế nào một người nên sử dụng fft

Vấn đề này đã làm phiền tôi trong nhiều tháng, bất kỳ trợ giúp hoặc hiểu biết nào sẽ được đánh giá cao.

Phiên bản rút gọn của câu hỏi: Làm thế nào tôi có thể nhận được sự khác biệt bình phương tổng của hai mảng trên hình ảnh (một ở trên cùng và một ở giữa, các giá trị là màu sắc) một cách nhanh chóng? (O (n ^ 2) là chi phí rất lớn, có rất nhiều loại hoạt động này, trên các trạng thái, có thể được thực hiện thông qua FFT với O (n * log n) (nói rằng 2 mảng này tạo thành tích chập tròn bằng cách nào đó) )

nhập mô tả hình ảnh ở đây


Cuối cùng bạn đã làm gì để tính toán FFT? Ngay cả khi FFT được tính toán trước, phép nhân điểm cộng và cộng tất cả các phần tử vá sẽ mấtO(|P|) thời gian ở đâu |P|là kích thước của miếng vá. Làm thế nào bạn vượt qua điều này?
cà ri

Câu trả lời:


5

Thủ thuật bên trong bài báo như sau:

  1. Những gì bạn muốn tính toán là iW|I(x+i)I(y+i)|2, Ở đâu I là một hình ảnh, xy hai pixel nhiễu và i là phần bù 2D được sử dụng để xác định một bản vá.
  2. Mở rộng biểu thức mang lại: iI2(x+i)+iI2(y+i)2iI(x+i)I(y+i)=A+B2C.
  3. AB được tính bằng cách sử dụng một hình ảnh tích phân bình phương, tức là một hình ảnh tích hợp từ hình ảnh gốc bình phương.
  4. C là sự kết hợp giữa hai bản vá tập trung vào xy. Do đó, nó có thể được tính toán trong miền Fourier, nơi nó trở thành phép nhân. Bạn nhận được giá trị củaC bằng cách tính toán biến đổi Fourier của bản vá xung quanh x, các bản vá xung quanh y, nhân đôi các kết quả này và lấy biến đổi Fourier ngược của kết quả đa ứng dụng.

Biến đổi Fourier rõ ràng là một biến đổi 2D vì bạn đang làm việc với dữ liệu 2D. Những gì bạn có được cho một bản vá nhất định là một mảng 2D của các giá trị phức tạp.

Ghi chú bổ sung

Theo tôi bài viết này không phải là chiến lược tăng tốc NL tốt nhất. Các thử nghiệm tôi đã thực hiện từ năm 2007/2008 cho thấy rằng việc lựa chọn trước các bản vá là tốt hơn (cả về tốc độ và chất lượng của kết quả). Tôi đã bắt đầu viết blog về những điều này ở đây , nhưng tiếc là tôi đang tìm thời gian để hoàn thành bài viết.

Các bài báo gốc NL có nghĩa là các bài viết đề cập đến việc triển khai theo chiều ngang có thể thú vị. Về cơ bản có 2 cách để thực hiện NL-nghĩa là:

  1. viết một vòng lặp khử cho mọi pixel trong ảnh
  2. viết một vòng lặp khử nhiễu cho mỗi bản vá, sau đó chiếu lại các bản vá để tạo thành một hình ảnh.

Sự bất lịch sự đầu tiên là cách tiếp cận ban đầu, bởi vì vào năm 2005, bộ nhớ và CPU đa lõi rất tốn kém. Mặt khác, tôi đã chọn số 2 trên phần cứng gần đây trong 2 năm qua. Nó phụ thuộc vào kích thước hình ảnh điển hình của bạn và nếu bạn muốn có thể tính toán các biến đổi miền như DFT / DCT (như trong bài báo được đề xuất và trong BM3D).


Cảm ơn rất nhiều về câu trả lời của bạn, đó chính xác là những gì tôi cần, tất cả đã sẵn sàng và hoạt động từ lâu, ngoại trừ mục thứ 4 trong danh sách đó, nhưng bây giờ thì rõ ràng hơn nhiều. Mặc dù có thêm một câu hỏi, nếu bạn không phiền: điều gì sẽ trả về biến đổi Fourier của patch x hoặc y? Mảng, vectơ, hoặc giá trị đơn? Và những gì được yêu cầu để sử dụng biến đổi nghịch đảo? Trở thành tôi đang suy nghĩ về việc tính toán trước fft cho mỗi pixel (các bản vá tập trung xung quanh nó) và viết kết quả vào mảng 2d trước khi khử nhiễu và sau đó chỉ sử dụng các ma trận đó để lấy fft nghịch đảo, nhưng tôi không biết liệu điều này có đủ cho nghịch đảo fft không
Shf

oh, và tôi nên sử dụng fd 2d, hay dịch patch sang mảng 1d? bằng cách này, tôi đã lên kế hoạch để ghi sau khi thực hiện patchwise này anyway, cảm ơn cho một lời khuyên :) cái gì đó tương tự như điều này cũng một thời gian dài ago- ipol.im/pub/art/2011/bcm_nlm
SHF

Tôi đã cập nhật câu trả lời.
sansuiso

ok, vì vậy tôi có thể tính toán trước FFT cho các bản vá, tập trung xung quanh mỗi pixel trước khi đóng gói mặc dù nó sẽ chiếm rất nhiều bộ nhớ (m n size_of_patch size_of_patch sizeof (gấp đôi)), nhưng khi tôi sẽ tính trọng số, tôi vẫn cần phải nhân lên 2 các mảng phức tạp và sau đó thực hiện nghịch đảo fft trên mảng 2d đã nhận, nó thậm chí còn nhiều hơn O (n ^ 2) nếu tôi không nhầm
Shf

2
Câu trả lời hay, nhưng làm thế nào bạn có được điều đó Clà một tổ hợp? Cách nó được viết nó là một sản phẩm từng yếu tố khôn ngoan. Đâu là tích chập?
TheGrapeBeyond
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.