Anda tidak mencari tepi (= perbatasan antara daerah diperpanjang nilai abu-abu tinggi dan rendah), Anda sedang mencari pegunungan (garis tipis gelap atau lebih terang dari lingkungan mereka), sehingga tepi filter mungkin tidak ideal: Filter tepi akan memberi Anda dua sisi (satu di setiap sisi garis) dan respons rendah di tengah garis:
TAMBAH : Jika diminta menjelaskan perbedaan antara detektor tepi dan detektor ridge lebih jelas. Saya minta maaf sebelumnya jika jawaban ini terlalu panjang.
Detektor tepi (biasanya) adalah operator turunan pertama: Jika Anda membayangkan gambar input sebagai lanskap 3D, detektor tepi mengukur kecuraman lereng di setiap titik lanskap itu:
Jika Anda ingin mendeteksi batas wilayah yang terang atau gelap, ini tidak apa-apa. Tetapi untuk urat pada gambar OP itu akan memberi Anda sama saja: garis besar kiri dan kanan masing-masing urat:
Itu juga menjelaskan "pola garis ganda" dalam hasil detektor tepi Canny:
Jadi, bagaimana Anda mendeteksi garis-garis tipis ini (yaitu bubungan)? Idenya adalah bahwa nilai-nilai piksel dapat (secara lokal) didekati oleh polinomial orde 2, yaitu jika fungsi gambar adalah , maka untuk nilai kecil dan :gxy
g(x,y)≈12x2∂2g∂x2+xy∂2g∂x∂y+12y2∂2g∂y2+x∂g∂x+y∂g∂y+g(0,0)
atau, dalam bentuk matriks:
g(x,y)≈12(xy).⎛⎝⎜∂2g∂x2∂2g∂x∂y∂2g∂x∂y∂2g∂y2⎞⎠⎟.(xy)+(xy).(∂g∂x∂g∂y)+g(0,0)
Matriks turunan urutan kedua disebut " Matriks goni ". Ini menjelaskan struktur urutan kedua yang menarik bagi kami.⎛⎝⎜∂2g∂x2∂2g∂x∂y∂2g∂x∂y∂2g∂y2⎞⎠⎟
Bagian urutan kedua dari fungsi ini dapat diubah menjadi jumlah dari dua parabola diputar oleh beberapa sudut, dengan mendekomposisi matriks Hessian di atas hingga kali rotasi matriks diagonal dari nilai eigen-nya ( Penguraian matriks ). Kami tidak peduli dengan rotasi (kami ingin mendeteksi ridges dalam orientasi apa pun), jadi kami hanya tertarik pada danλ1x2+λ2y2λ1λ2
Bentuk seperti apa yang bisa dimiliki oleh perkiraan fungsi ini? Sebenarnya tidak banyak:
Untuk mendeteksi ridges, kami ingin menemukan area dalam gambar yang terlihat seperti plot terakhir di atas, jadi kami mencari area di mana nilai eigen utama Hessian besar (dibandingkan dengan nilai eigen minor). Cara termudah untuk mendeteksi itu hanya dengan menghitung nilai eigen utama pada setiap piksel - dan itulah yang dilakukan oleh filter ridge di bawah ini.
Sebuah Filter ridge mungkin akan memberikan hasil yang lebih baik. Saya telah mencoba built in Mathematica RidgeFilter
(yang menghitung nilai eigen utama dari matriks Hessian pada setiap piksel) pada gambar Anda:
Seperti yang Anda lihat, hanya ada satu puncak untuk setiap garis gelap tipis. Hasil binarizing dan skeletonizing:
Setelah memangkas kerangka dan mengeluarkan komponen kecil (noise) dari gambar, saya mendapatkan kerangka terakhir ini:
Kode Mathematica lengkap:
ridges = RidgeFilter[ColorNegate@src];
skeleton = SkeletonTransform[Binarize[ridges, 0.007]];
DeleteSmallComponents[Pruning[skeleton, 50], 50]
MENAMBAHKAN:
Saya bukan ahli Matlab, saya tidak tahu apakah ia memiliki filter ridge bawaan, tetapi saya dapat menunjukkan kepada Anda bagaimana menerapkannya "dengan tangan" (sekali lagi, menggunakan Matematica). Seperti yang saya katakan, filter ridge adalah nilai eigen utama dari matriks Hessian. Saya dapat menghitung nilai eigen secara simbolis dalam Mathematica:
eigenvalue=Last[Eigenvalues[(HxxHxyHxyHyy)]]
=>12(Hxx+Hyy+H2xx+4H2xy−2HxxHyy+H2yy−−−−−−−−−−−−−−−−−−−−−−−√)
Jadi yang harus Anda lakukan adalah menghitung turunan kedua , , (menggunakan sobel atau turunan dari filter gaussian) dan masukkan ke dalam ekspresi di atas, dan Anda punya filter ridge Anda. H xy H yyHxxHxyHyy