Deteksi tepi biasanya dilakukan untuk mendeteksi area gambar dengan nilai gradien tinggi.
Dalam kasus kami, kami dapat dengan kasar melihat gradien sebagai turunan dari fungsi gambar, oleh karena itu besarnya gradien memberi Anda informasi tentang seberapa banyak gambar Anda berubah secara lokal (dalam hal piksel / texels tetangga).
Sekarang, edge adalah seperti yang Anda katakan indikasi diskontinuitas, jadi sekarang kita mendefinisikan gradien jelas bahwa info inilah yang kita butuhkan. Setelah kami menemukan gradien gambar, itu hanya masalah menerapkan ambang batas untuk mendapatkan tepi nilai biner / non-tepi.
Bagaimana Anda menemukan gradien ini benar-benar apa yang Anda minta dan saya belum menjawab :)
Banyak cara! Di sini pasangan :)
Fungsi shader bawaan
Baik hlsl dan glsl menawarkan fungsi turunan. Dalam GLSL Anda memiliki dFdx dan dFdy yang memberi Anda masing-masing informasi gradien dalam arah x dan y. Biasanya fungsi-fungsi ini dievaluasi dalam blok fragmen 2x2.
Kecuali jika Anda tertarik pada satu arah, cara yang baik untuk memiliki hasil yang ringkas yang menunjukkan seberapa kuat gradien di wilayah adalah fwidth yang tidak memberi Anda apa pun selain jumlah nilai absolut dari dFdy dan dFdy.
Anda mungkin tertarik pada keunggulan pada keseluruhan gambar daripada pada saluran tertentu, jadi Anda mungkin ingin mengubah fungsi gambar Anda menjadi luma. Dengan mengingat hal ini, ketika datang ke deteksi tepi shader Anda dapat mencakup sesuatu seperti:
float luminance = dot(yourFinalColour,vec3(0.2126, 0.7152, 0.0722));
float gradient = fwidth(luminance );
float isEdge = gradient > threshold;
Dengan ambang tinggi Anda akan menemukan tepi kasar dan Anda mungkin kehilangan beberapa, sebaliknya, dengan ambang rendah Anda mungkin mendeteksi tepi palsu. Anda harus bereksperimen untuk menemukan ambang yang lebih sesuai dengan kebutuhan Anda.
Alasan mengapa fungsi-fungsi ini layak disebutkan tetapi saya tidak punya waktu untuk itu sekarang, saya kemungkinan akan memperbarui jawaban ini nanti :)
Ruang layar pasca proses
Anda bisa menjadi lebih hebat dari ini, sekarang bidang deteksi Edge dalam pemrosesan gambar sangat besar. Saya bisa mengutip Anda puluhan cara bagus untuk mendeteksi deteksi tepi sesuai dengan kebutuhan Anda, tetapi mari kita tetap sederhana untuk saat ini, jika Anda tertarik, saya dapat mengutip Anda lebih banyak pilihan!
Jadi idenya akan mirip dengan yang di atas, dengan perbedaan bahwa Anda bisa melihat lingkungan yang lebih luas dan menggunakan satu set bobot pada sampel sekitarnya jika Anda mau. Biasanya, Anda menjalankan konvolusi pada gambar Anda dengan kernel yang memberi Anda info gradien yang baik.
Pilihan yang sangat umum adalah kernel Sobel
Yang masing-masing memberi Anda gradien dalam arah x dan y:
GradientMagnitude=(Gradientx)2+(Gradienty)2−−−−−−−−−−−−−−−−−−−−−−−√
Maka Anda bisa mengirik seperti cara yang saya sebutkan di atas.
Kernel ini seperti yang Anda lihat memberi bobot lebih pada pixel pusat, jadi secara efektif menghitung gradien + sedikit smoothing yang secara tradisional membantu (seringkali gambar buram untuk menghilangkan tepi kecil).
Cara di atas berfungsi dengan baik, tetapi jika Anda tidak suka smoothing, Anda bisa menggunakan kernel Prewitt:
(Catatan saya sedang terburu-buru, akan segera menulis teks yang diformat alih-alih gambar!)
Benar-benar ada lebih banyak kernel dan teknik untuk menemukan deteksi tepi dalam proses gambar-y daripada grafis waktu nyata, jadi saya telah mengecualikan metode yang lebih berbelit-belit (pun tidak dimaksudkan) karena mungkin Anda akan baik-baik saja dengan fungsi dFdx / y .