Teknik pemrosesan gambar apa yang dapat digunakan untuk mengimplementasikan aplikasi yang mendeteksi pohon Natal yang ditampilkan dalam gambar berikut?
Saya mencari solusi yang akan bekerja pada semua gambar ini. Oleh karena itu, pendekatan yang membutuhkan pelatihan pengklasifikasi haar cascade atau pencocokan templat tidak terlalu menarik.
Saya mencari sesuatu yang dapat ditulis dalam bahasa pemrograman apa pun , asalkan hanya menggunakan teknologi Open Source . Solusinya harus diuji dengan gambar yang dibagikan pada pertanyaan ini. Ada 6 gambar input dan jawabannya harus menampilkan hasil pemrosesan masing-masing. Akhirnya, untuk setiap gambar keluaran harus ada garis merah menggambar untuk mengelilingi pohon yang terdeteksi.
Bagaimana cara Anda mendeteksi pohon secara terprogram dalam gambar-gambar ini?
sumber
Jawaban:
Saya memiliki pendekatan yang menurut saya menarik dan sedikit berbeda dari yang lain. Perbedaan utama dalam pendekatan saya, dibandingkan dengan yang lain, adalah bagaimana langkah segmentasi gambar dilakukan - saya menggunakan algoritma pengelompokan DBSCAN dari scikit-learn Python; itu dioptimalkan untuk menemukan bentuk agak amorf yang mungkin belum tentu memiliki pusat massa tunggal yang jelas.
Di tingkat atas, pendekatan saya cukup sederhana dan dapat dipecah menjadi sekitar 3 langkah. Pertama saya menerapkan ambang batas (atau sebenarnya, logika "atau" dua ambang batas yang berbeda dan berbeda). Seperti banyak jawaban lain, saya berasumsi bahwa pohon Natal akan menjadi salah satu objek yang lebih terang di tempat kejadian, jadi ambang pertama hanyalah uji kecerahan monokrom sederhana; setiap piksel dengan nilai di atas 220 pada skala 0-255 (di mana hitam 0 dan putih 255) disimpan ke gambar biner hitam-putih. Ambang kedua mencoba mencari lampu merah dan kuning, yang terutama menonjol di pohon-pohon di kiri atas dan kanan bawah dari enam gambar, dan menonjol dengan latar belakang biru-hijau yang lazim di sebagian besar foto. Saya mengkonversi gambar rgb ke ruang hsv, dan mensyaratkan bahwa rona kurang dari 0,2 pada skala 0,0-1,0 (sesuai kira-kira dengan batas antara kuning dan hijau) atau lebih besar dari 0,95 (sesuai dengan batas antara ungu dan merah) dan juga saya membutuhkan warna-warna cerah, jenuh: saturasi dan nilai keduanya harus di atas 0,7. Hasil dari dua prosedur ambang secara logis "atau" -ed bersama, dan matriks yang dihasilkan dari gambar biner hitam-putih ditunjukkan di bawah ini:
Anda dapat dengan jelas melihat bahwa setiap gambar memiliki satu kelompok besar piksel yang secara kasar sesuai dengan lokasi setiap pohon, ditambah beberapa gambar juga memiliki beberapa kelompok kecil lainnya yang terkait dengan lampu di jendela beberapa bangunan, atau ke adegan latar belakang di cakrawala. Langkah selanjutnya adalah membuat komputer mengenali bahwa ini adalah cluster yang terpisah, dan beri label setiap piksel dengan benar dengan nomor ID keanggotaan cluster.
Untuk tugas ini saya memilih DBSCAN . Ada perbandingan visual yang cukup bagus tentang bagaimana biasanya perilaku DBSCAN, relatif terhadap algoritma pengelompokan lainnya, tersedia di sini . Seperti yang saya katakan sebelumnya, itu baik dengan bentuk amorf. Output dari DBSCAN, dengan masing-masing cluster diplot dalam warna yang berbeda, ditunjukkan di sini:
Ada beberapa hal yang perlu diperhatikan ketika melihat hasil ini. Pertama adalah bahwa DBSCAN mengharuskan pengguna untuk menetapkan parameter "proximity" untuk mengatur perilakunya, yang secara efektif mengontrol bagaimana dipisahkannya sepasang titik agar algoritma dapat mendeklarasikan cluster terpisah baru daripada menggumpalkan titik uji ke cluster yang sudah ada sebelumnya. Saya menetapkan nilai ini menjadi 0,04 kali ukuran sepanjang diagonal setiap gambar. Karena ukuran gambar bervariasi dari kira-kira VGA hingga HD 1080, definisi skala-relatif ini sangat penting.
Hal lain yang patut dicatat adalah bahwa algoritma DBSCAN seperti yang diterapkan dalam scikit-learn memiliki batas memori yang cukup menantang untuk beberapa gambar yang lebih besar dalam sampel ini. Oleh karena itu, untuk beberapa gambar yang lebih besar, saya benar-benar harus "memusnahkan" (yaitu, pertahankan hanya setiap piksel ke-3 atau ke-4 dan jatuhkan yang lain) setiap cluster agar tetap dalam batas ini. Sebagai hasil dari proses pemusnahan ini, piksel jarang individu yang tersisa sulit dilihat pada beberapa gambar yang lebih besar. Oleh karena itu, hanya untuk tujuan tampilan, piksel kode warna pada gambar di atas telah secara efektif "dilatasi" hanya sedikit sehingga lebih menonjol. Ini murni operasi kosmetik demi narasi; meskipun ada komentar yang menyebutkan pelebaran ini dalam kode saya,
Setelah cluster diidentifikasi dan diberi label, langkah ketiga dan terakhir mudah: Saya cukup mengambil cluster terbesar di setiap gambar (dalam hal ini, saya memilih untuk mengukur "ukuran" dalam hal jumlah total piksel anggota, meskipun orang bisa baru saja dengan mudah menggunakan beberapa jenis metrik yang mengukur tingkat fisik) dan menghitung convex hull untuk cluster tersebut. Lambung cembung kemudian menjadi batas pohon. Enam lambung cembung yang dihitung melalui metode ini ditunjukkan di bawah ini dalam warna merah:
Kode sumber ditulis untuk Python 2.7.6 dan itu tergantung pada numpy , scipy , matplotlib dan scikit-learn . Saya sudah membaginya menjadi dua bagian. Bagian pertama bertanggung jawab atas pemrosesan gambar yang sebenarnya:
dan bagian kedua adalah skrip tingkat pengguna yang memanggil file pertama dan menghasilkan semua plot di atas:
sumber
scipy.ndimage.filters.maximum_filter()
tempat yang sama dengan tempat saya menggunakan ambang.EDIT CATATAN: Saya mengedit posting ini untuk (i) memproses setiap gambar pohon secara terpisah, seperti yang diminta dalam persyaratan, (ii) untuk mempertimbangkan kecerahan dan bentuk objek untuk meningkatkan kualitas hasil.
Di bawah ini disajikan pendekatan yang mempertimbangkan kecerahan dan bentuk objek. Dengan kata lain, ia mencari objek dengan bentuk seperti segitiga dan dengan kecerahan yang signifikan. Itu diimplementasikan di Jawa, menggunakan kerangka kerja pemrosesan gambar Marvin .
Langkah pertama adalah ambang warna. Tujuannya di sini adalah untuk memfokuskan analisis pada objek dengan kecerahan yang signifikan.
gambar output:
Kode sumber:
Pada langkah kedua, titik paling terang pada gambar dilebarkan untuk membentuk bentuk. Hasil dari proses ini adalah kemungkinan bentuk objek dengan kecerahan yang signifikan. Menerapkan segmentasi pengisian banjir, bentuk terputus terdeteksi.
gambar output:
Kode sumber:
Seperti yang ditunjukkan pada gambar output, banyak bentuk terdeteksi. Dalam masalah ini, hanya ada beberapa titik terang dalam gambar. Namun, pendekatan ini diimplementasikan untuk menangani skenario yang lebih kompleks.
Pada langkah berikutnya setiap bentuk dianalisis. Algoritma sederhana mendeteksi bentuk dengan pola yang mirip dengan segitiga. Algoritma ini menganalisis objek bentuk garis demi garis. Jika pusat massa masing-masing garis bentuk hampir sama (diberi ambang batas) dan massa bertambah seiring y bertambah, objek memiliki bentuk seperti segitiga. Massa garis bentuk adalah jumlah piksel dalam garis yang termasuk dalam bentuk itu. Bayangkan Anda mengiris objek secara horizontal dan menganalisis setiap segmen horizontal. Jika mereka terpusat satu sama lain dan panjangnya bertambah dari segmen pertama ke yang terakhir dalam pola linier, Anda mungkin memiliki objek yang menyerupai segitiga.
Kode sumber:
Akhirnya, posisi setiap bentuk mirip dengan segitiga dan dengan kecerahan yang signifikan, dalam hal ini pohon Natal, disorot dalam gambar aslinya, seperti yang ditunjukkan di bawah ini.
gambar hasil akhir:
kode sumber akhir:
Keuntungan dari pendekatan ini adalah fakta bahwa ia mungkin akan bekerja dengan gambar yang mengandung objek bercahaya lain karena menganalisis bentuk objek.
Selamat Natal!
EDIT CATATAN 2
Ada diskusi tentang kesamaan gambar output dari solusi ini dan beberapa yang lain. Bahkan, mereka sangat mirip. Namun pendekatan ini tidak hanya mensegmentasi objek. Ini juga menganalisis bentuk objek dalam beberapa hal. Itu dapat menangani beberapa objek bercahaya dalam adegan yang sama. Faktanya, pohon Natal tidak perlu menjadi yang paling terang. Saya hanya membahasnya untuk memperkaya diskusi. Ada bias dalam sampel yang hanya mencari objek paling terang, Anda akan menemukan pohon. Tetapi, apakah kita benar-benar ingin menghentikan diskusi pada titik ini? Pada titik ini, seberapa jauh komputer benar-benar mengenali objek yang menyerupai pohon Natal? Mari kita coba untuk menutup celah ini.
Di bawah ini disajikan hasil hanya untuk menjelaskan hal ini:
masukan gambar
keluaran
sumber
Ini solusi sederhana dan bodoh saya. Ini didasarkan pada asumsi bahwa pohon itu akan menjadi hal yang paling terang dan besar dalam gambar.
Langkah pertama adalah mendeteksi piksel paling terang dalam gambar, tetapi kita harus melakukan pembedaan antara pohon itu sendiri dan salju yang memantulkan cahayanya. Di sini kami mencoba untuk mengecualikan salju yang menerapkan filter yang sangat sederhana pada kode warna:
Lalu kami menemukan setiap piksel "cerah":
Akhirnya kami bergabung dengan dua hasil:
Sekarang kita mencari objek terang terbesar:
Sekarang kita hampir selesai, tetapi masih ada beberapa ketidaksempurnaan karena salju. Untuk memotongnya, kami akan membuat topeng menggunakan lingkaran dan persegi panjang untuk memperkirakan bentuk pohon untuk menghapus potongan yang tidak diinginkan:
Langkah terakhir adalah menemukan kontur pohon kami dan menggambarnya di gambar aslinya.
Maaf, tetapi saat ini saya memiliki koneksi yang buruk sehingga tidak mungkin bagi saya untuk mengunggah gambar. Saya akan coba melakukannya nanti.
Selamat Natal.
EDIT:
Berikut beberapa gambar hasil akhir:
sumber
./christmas_tree ./*.png
. Mereka dapat sebanyak yang Anda inginkan, hasilnya akan ditampilkan satu demi satu dengan menekan tombol apa saja. Apakah ini salah?<img src="http://i.stack.imgur.com/nmzwj.png" width="210" height="150">
mengubahSaya menulis kode di Matlab R2007a. Saya menggunakan k-means untuk mengekstrak pohon natal secara kasar. Saya akan menunjukkan hasil antara saya hanya dengan satu gambar, dan hasil akhir dengan semua enam.
Pertama, saya memetakan ruang RGB ke ruang Lab, yang dapat meningkatkan kontras merah di saluran b-nya:
Selain fitur dalam ruang warna, saya juga menggunakan fitur tekstur yang relevan dengan lingkungan daripada setiap piksel itu sendiri. Di sini saya secara linear menggabungkan intensitas dari 3 saluran asli (R, G, B). Alasan mengapa saya diformat dengan cara ini adalah karena pohon-pohon natal di gambar semua memiliki lampu merah pada mereka, dan kadang-kadang pencahayaan hijau / kadang-kadang biru juga.
Saya menerapkan pola biner lokal 3X3 pada
I0
, menggunakan piksel tengah sebagai ambang, dan memperoleh kontras dengan menghitung perbedaan antara nilai intensitas piksel rata-rata di atas ambang batas dan nilai rata-rata di bawahnya.Karena saya memiliki total 4 fitur, saya akan memilih K = 5 dalam metode pengelompokan saya. Kode untuk k-means ditunjukkan di bawah ini (ini dari kursus pembelajaran mesin Dr. Andrew Ng. Saya mengambil kursus sebelumnya, dan saya menulis kode sendiri dalam tugas pemrogramannya).
Karena program ini berjalan sangat lambat di komputer saya, saya hanya menjalankan 3 iterasi. Biasanya kriteria berhenti adalah (i) waktu iterasi setidaknya 10, atau (ii) tidak ada perubahan pada centroid lagi. Untuk pengujian saya, meningkatkan iterasi dapat membedakan latar belakang (langit dan pohon, langit dan bangunan, ...) lebih akurat, tetapi tidak menunjukkan perubahan drastis dalam ekstraksi pohon natal. Juga perhatikan k-means tidak kebal terhadap inisialisasi centroid acak, sehingga menjalankan program beberapa kali untuk membuat perbandingan direkomendasikan.
Setelah k-means, wilayah berlabel dengan intensitas maksimum
I0
dipilih. Dan penelusuran batas digunakan untuk mengekstraksi batas. Bagi saya, pohon natal terakhir adalah yang paling sulit untuk diekstraksi karena kontras dalam gambar itu tidak cukup tinggi seperti pada lima pohon pertama. Masalah lain dalam metode saya adalah bahwa saya menggunakanbwboundaries
fungsi di Matlab untuk melacak batas, tetapi kadang-kadang batas-batas bagian dalam juga dimasukkan karena Anda dapat mengamati dalam hasil 3, 5, 6. Sisi gelap di dalam pohon natal tidak hanya gagal untuk dikelompokkan dengan sisi yang diterangi, tetapi mereka juga menyebabkan begitu banyak batasan batin kecil yang ditelusuri (imfill
tidak bertambah banyak). Secara keseluruhan, algoritma saya masih memiliki banyak ruang perbaikan.Beberapa publikasi menunjukkan bahwa mean-shift mungkin lebih kuat daripada k-means, dan banyak algoritma berbasis grafik-cut juga sangat kompetitif pada segmentasi batas yang rumit. Saya menulis algoritma mean-shift sendiri, sepertinya lebih baik mengekstrak wilayah tanpa cukup cahaya. Tetapi pergeseran berarti sedikit lebih tersegmentasi, dan beberapa strategi penggabungan diperlukan. Itu berjalan jauh lebih lambat daripada k-berarti di komputer saya, saya takut saya harus menyerah. Saya berharap dapat melihat orang lain akan mengirimkan hasil yang sangat baik di sini dengan algoritma modern yang disebutkan di atas.
Namun saya selalu percaya pemilihan fitur adalah komponen kunci dalam segmentasi gambar. Dengan pemilihan fitur yang tepat yang dapat memaksimalkan margin antara objek dan latar belakang, banyak algoritma segmentasi pasti akan berfungsi. Algoritme yang berbeda dapat meningkatkan hasil dari 1 hingga 10, tetapi pemilihan fitur dapat meningkatkannya dari 0 hingga 1.
Selamat Natal !
sumber
Ini adalah posting terakhir saya menggunakan pendekatan pemrosesan gambar tradisional ...
Di sini saya entah bagaimana menggabungkan dua proposal saya yang lain, mencapai hasil yang lebih baik . Sebenarnya saya tidak bisa melihat bagaimana hasil ini bisa lebih baik (terutama ketika Anda melihat gambar bertopeng yang dihasilkan metode ini).
Inti dari pendekatan ini adalah kombinasi dari tiga asumsi utama :
Dengan asumsi ini, metode ini berfungsi sebagai berikut:
Berikut adalah kode dalam MATLAB (sekali lagi, skrip memuat semua gambar jpg di folder saat ini dan, sekali lagi, ini masih jauh dari sepotong kode yang dioptimalkan):
Hasil
Hasil resolusi tinggi masih tersedia di sini!
Bahkan lebih banyak percobaan dengan gambar tambahan dapat ditemukan di sini.
sumber
Langkah solusi saya:
Dapatkan saluran R (dari RGB) - semua operasi yang kami lakukan di saluran ini:
Buat Wilayah Bunga (ROI)
Saluran R ambang batas dengan nilai min 149 (gambar kanan atas)
Melebarkan wilayah hasil (gambar kiri tengah)
Mendeteksi eges dalam roi yang dihitung. Pohon memiliki banyak sisi (gambar kanan tengah)
Dilatasi hasilnya
Melaju dengan radius lebih besar (gambar kiri bawah)
Pilih objek (berdasarkan wilayah) terbesar - ini adalah wilayah hasil
ConvexHull (pohon adalah cembung poligon) (gambar kanan bawah)
Bounding box (gambar kanan bawah - kotak grren)
Selangkah demi selangkah:
Hasil pertama - paling sederhana tetapi tidak dalam perangkat lunak sumber terbuka - "Adaptive Vision Studio + Adaptive Vision Library": Ini bukan open source tetapi sangat cepat untuk prototipe:
Seluruh algoritme untuk mendeteksi pohon natal (11 blok):
Langkah berikutnya. Kami menginginkan solusi open source. Ubah filter AVL menjadi filter OpenCV: Di sini saya melakukan sedikit perubahan misalnya Deteksi Tepi menggunakan filter cvCanny, untuk menghormati roi, saya melakukan penggandaan gambar wilayah dengan gambar tepi, untuk memilih elemen terbesar yang saya gunakan findContours + contourArea tetapi gagasannya sama.
https://www.youtube.com/watch?v=sfjB3MigLH0&index=1&list=UUpSRrkMHNHiLDXgylwhWNQQ
Saya tidak dapat menampilkan gambar dengan langkah perantara sekarang karena saya hanya dapat menempatkan 2 tautan.
Ok sekarang kita menggunakan filter openSource tetapi itu belum sepenuhnya open source. Langkah terakhir - port ke kode c ++. Saya menggunakan OpenCV dalam versi 2.4.4
Hasil akhir kode c ++ adalah:
kode c ++ juga cukup pendek:
sumber
std::max_element()
panggilan? Saya ingin menghargai jawaban Anda juga. Saya pikir saya punya gcc 4.2.... solusi kuno lain - murni berdasarkan pada pemrosesan HSV :
Sepatah kata tentang heuristik dalam pemrosesan HSV:
Tentu saja seseorang dapat bereksperimen dengan berbagai kemungkinan lain untuk menyempurnakan pendekatan ini ...
Berikut adalah kode MATLAB untuk melakukan trik (peringatan: kode ini jauh dari dioptimalkan !!! Saya menggunakan teknik yang tidak disarankan untuk pemrograman MATLAB hanya untuk dapat melacak apa pun dalam proses-ini dapat sangat dioptimalkan):
Hasil:
Dalam hasil saya menunjukkan gambar bertopeng dan kotak pembatas.
sumber
Beberapa pendekatan pemrosesan gambar kuno ...
Idenya didasarkan pada asumsi bahwa gambar menggambarkan pohon terang pada latar belakang yang biasanya lebih gelap dan lebih halus (atau latar depan dalam beberapa kasus). Area pohon yang terang lebih "energik" dan memiliki intensitas yang lebih tinggi .
Prosesnya adalah sebagai berikut:
Apa yang Anda dapatkan adalah topeng biner dan kotak pembatas untuk setiap gambar.
Berikut adalah hasil menggunakan teknik naif ini:
Kode pada MATLAB berikut: Kode ini berjalan pada folder dengan gambar JPG. Memuat semua gambar dan mengembalikan hasil yang terdeteksi.
sumber
Menggunakan pendekatan yang sangat berbeda dari apa yang saya lihat, saya membuat phpskrip yang mendeteksi pohon natal dengan lampu mereka. Hasilnya adalah selalu segitiga simetris, dan jika perlu nilai numerik seperti sudut ("kegemukan") pohon.
Ancaman terbesar terhadap algoritma ini jelas adalah lampu di sebelah (dalam jumlah besar) atau di depan pohon (masalah yang lebih besar hingga optimasi lebih lanjut). Sunting (ditambahkan): Apa yang tidak bisa dilakukan: Cari tahu apakah ada pohon natal atau tidak, temukan beberapa pohon natal dalam satu gambar, mendeteksi pohon cristmas dengan benar di tengah Las Vegas, mendeteksi pohon natal yang sangat bengkok, terbalik atau dicincang ...;)
Tahapan yang berbeda adalah:
Penjelasan tanda:
Kode sumber:
Gambar-gambar:
Bonus: Weihnachtsbaum dari Jerman, dari Wikipedia http://commons.wikimedia.org/wiki/File:Weihnachtsbaum_R%C3%B6merberg.jpg
sumber
Saya menggunakan python dengan opencv.
Algoritma saya berjalan seperti ini:
Kode:
Jika saya mengubah kernel dari (25,5) menjadi (10,5) saya mendapatkan hasil yang lebih bagus di semua pohon tetapi di kiri bawah,
algoritma saya berasumsi bahwa pohon memiliki lampu di atasnya, dan di pohon kiri bawah, bagian atas memiliki lebih sedikit cahaya daripada yang lain.
sumber