Bagaimana cara lowpass filter dengan hanya mengurangi data puncak?

16

Saya memiliki gambar 2D, yang ingin saya saring lowpass, dengan batasan / kualitas metrik ini:

  1. Saya tidak bisa "menambahkan" cahaya ke gambar, sehingga setiap piksel dalam hasil harus <= piksel yang sesuai dalam input.
  2. Frekuensi cutoff lowpass harus menjadi parameter, untuk bereksperimen
  3. Menerapkan filter ini berulang kali tidak boleh mengubah hasilnya secara signifikan.
  4. Waktu yang diperlukan untuk menjalankan algoritma ini (5 menit untuk gambar 5MPix tampak masuk akal)
  5. Meminimalkan jumlah cahaya yang disaring.

Berikut adalah beberapa pendekatan yang telah saya coba, bersama dengan kekurangannya:

  1. Filter Gaussian seperti biasa, lalu tarik hasilnya ke bawah untuk mematuhi kendala 1. Ini sangat sesuai dengan 3 poin pertama, tetapi mengurangi lebih banyak cahaya daripada yang diperlukan.

  2. Pasangkan parabola "ke atas" melalui titik "rendah" dan parabola "ke bawah" untuk melicinkannya. Ini berfungsi baik dalam 1D, tetapi menerapkannya pertama secara horizontal, kemudian secara vertikal menghasilkan hasil yang buruk dalam 2D. Butuh waktu lebih lama, tetapi tidak terlalu lama untuk aplikasi saya. Namun, menerapkan filter ini secara berulang akan mengubah hasilnya secara drastis. Jika input (1D) adalah parabola "ke bawah" yang sempurna (yang seharusnya tidak disaring sama sekali), itu akan digantikan oleh 2 parabola "ke atas" yang duduk di awal / akhir.

  3. Menggunakan beberapa bentuk 2D "dasar" lainnya dan penyelesaian linear untuk menemukan parameter yang optimal. Ini hanya ide saat ini, belum diimplementasikan / diuji.

Domain pengalaman saya dalam pemrosesan sinyal hampir secara eksklusif pemrosesan gambar, jadi saya berharap dapat menemukan alternatif untuk masalah ini dengan masukan dari para ahli yang aktif di bidang pemrosesan sinyal lainnya.

perbarui 2011/08/18

Berdasarkan reaksi saat ini, saya memutuskan untuk membuat hal-hal sedikit lebih jelas dengan menambahkan grafik dari input yang khas dan hasil dari 3 pendekatan yang saya jelaskan awalnya + saran yang saya terima sejauh ini. Untuk perbandingan mudah, saya hanya menggunakan filter 1D dalam contoh-contoh ini.

Memasukan data: Memasukan data

Filter Gaussian + menurunkannya untuk memenuhi persyaratan (1).
Anda dapat melihat bahwa menurunkannya menghasilkan pengurangan cahaya yang tidak perlu di sisi kanan. gaussian difilter

Parabolas
Sejauh yang saya ketahui, ini cukup bagus, sayangnya tidak diterjemahkan dengan sempurna ke dalam 2D ​​dengan menerapkan pertama horisontal, kemudian vertikal. Dalam hal ini, Anda juga melihat saya dapat mengevaluasi parabola yang dipasang dalam resolusi floating point, yang merupakan manfaat kecil, tetapi tidak mutlak diperlukan. pemasangan parabola

Erosi
skala abu- abu Berdasarkan saran dari rwong, saya mencoba erosi skala abu-abu. Saya menggunakan elemen penataan dengan bentuk parabola yang sama dengan parabola "pas" saya. Hasilnya hampir persis sama, jadi ini terlihat menjanjikan. Namun, masih ada beberapa masalah: 1. Elemen penataan saya tidak "cukup besar" (meskipun sudah 801 piksel lebar) 1. Saya hanya memiliki parabola "ke atas", tidak ada "parabola ke bawah untuk memperlancar transisi dari satu parabola selanjutnya. erosi abu-abu

Penyaringan median
Hanya termasuk untuk kelengkapan, itu tidak benar-benar apa yang saya inginkan. filter median

data mentah
Saya menempelkan data input mentah + berbagai perintah python ke pastebin, sehingga Anda dapat bereksperimen dengan data yang sama juga.
http://pastebin.com/ASnJ9M0p

Pieter-Jan Busschaert
sumber
1
Bisakah Anda jelaskan lebih banyak tentang batasan 1 dan 5? Mereka tampaknya bertentangan (pada pandangan pertama).
Peter K.
Saya mungkin salah paham apa yang Anda maksud dengan "algoritma ini", tetapi 5 menit untuk 5 MP sepertinya banyak untuk menerapkan filter lowpass.
bjoernz

Jawaban:

8

Memang ada versi 2D untuk upaya Anda # 2 - ini secara teori serupa, tetapi tidak dapat diuraikan menjadi dua operasi 1D. Silakan baca tentang "pemfilteran morfologi grayscale 2D". Ini lebih cepat daripada pemasangan kurva.

Pemfilteran median mungkin juga berguna jika Anda mencoba menghilangkan bintik-bintik. Bentuk yang lebih maju dari penyaringan median adalah "penyaringan ordinal".

Dalam semua kasus, persyaratan # 1 dapat dipenuhi secara sepele dengan mengambil minimum pixelwise antara output dan input. Ini adalah kriteria kualitas yang penting, tetapi tidak akan membatasi pilihan algoritma.


Pemfilteran Gaussian (dan sejumlah filter bermanfaat lainnya) dapat didekomposisi (pertama dari operasi 2D ke 1D, kemudian melalui transformasi Fourier), tetapi ada banyak teknik pemrosesan gambar berguna lainnya yang tidak dapat diuraikan, yang membuatnya lambat tetapi tidak berkurang kegunaannya.

rwong
sumber
Hai, terima kasih atas pointer ke pemfilteran morfologis abu-abu. Deskripsi pada wikipedia tampaknya menarik dan saya akan menyelidiki itu. Namun, dalam tautan Anda ke dokumentasi OpenCV, saya hanya melihat filter morfologis normal, bukan yang abu-abu. Saya pasti akan memeriksa opsi ini dan memberi tahu Anda hasilnya. Terima kasih.
Pieter-Jan Busschaert
6
Apakah saran rwong tentang penyaringan median membantu sama sekali? Menjelaskan lebih banyak tentang apa yang ingin Anda capai dengan menghadirkan contoh sederhana data dan contoh "palsu" tentang apa yang ingin Anda keluarkan mungkin membantu.
Peter K.
Saya memperbarui pertanyaan saya dengan data sampel + hasil dari berbagai saran. Saya harap semuanya lebih jelas sekarang.
Pieter-Jan Busschaert
2

Saya sarankan menggunakan spline smoothing.

Inilah cara Anda dapat melakukan ini menggunakan Matlab dengan fungsi smoothing spline yang kuat SMOOTHN dari Matlab File Exchange (yang berisi kode sumber lengkap, sehingga Anda dapat mengimplementasikannya kembali di tempat lain jika diperlukan). Perhatikan bahwa ia berfungsi dengan data n-dimensi juga:

%# - get inputlist from pastebin

%# - smoothen data. Lower factor means less smooth
smoothingFactor = 1000;
smoothData = smoothn(inputlist,smoothingFactor);

%# - shift down
smoothData = smoothData - max(inputlist-smoothData);

%# - show results
plot(inputlist,'b'),hold on,plot(smoothData,'r')

masukkan deskripsi gambar di sini

Jonas
sumber
Terima kasih atas saran Anda, saya akan menyelidikinya. Dari grafik Anda, sepertinya saya membutuhkan smoothingFactor yang jauh lebih tinggi daripada contoh Anda. Tepi curam di sekitar x = 700 tidak dihapus dan akan terlihat jelas. Juga benjolan awal dalam x = [0, 400] tidak dihapus sama sekali. Tidakkah menurut Anda ini akan memiliki masalah yang sama dengan pendekatan (low-pass filter + move down) lainnya? Anda dapat melihat global offset antara kedua grafik, yang mungkin bahkan akan meningkat ketika saya menggunakan smoothingFactor yang lebih tinggi.
Pieter-Jan Busschaert
@ Pieter-JanBusschaert: Oh, saya pikir puncak pertama itu entah bagaimana berguna bagi Anda. Bagaimanapun, semua low-pass-filter + move-down akan mengalami kesulitan dengan kenaikan curam di ~ 650: Mereka akan membuat bagian ini lebih rata, dan dengan demikian kurva harus banyak digerakkan. Median Filter diikuti oleh smoothing spline sedikit membantu.
Jonas