Saya sekarang berurusan dengan beberapa pemrosesan gambar di Python via PIL (Python Image Library). Tujuan utama saya adalah menghitung jumlah sel berwarna dalam gambar imunohistokimia. Saya tahu bahwa ada program yang relevan, perpustakaan, fungsi dan tutorial tentang hal itu, dan saya memeriksa hampir semuanya. Tujuan utama saya adalah menulis kode secara manual dari awal, sebanyak mungkin. Karenanya saya mencoba untuk menghindari menggunakan banyak perpustakaan dan fungsi eksterior. Saya telah menulis sebagian besar program. Jadi, inilah yang terjadi selangkah demi selangkah:
Program mengambil file gambar:
Dan memprosesnya untuk sel merah (pada dasarnya, mematikan nilai RGB di bawah ambang batas tertentu untuk merah):
Dan menciptakan peta boolean itu, (akan menempel bagian dari itu karena besar) yang pada dasarnya hanya menempatkan 1 di mana pun ia bertemu dengan piksel merah pada gambar kedua yang diproses di atas.
22222222222222222222222222222222222222222
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000111111110000000000000000000000002
20000000011111100000000000000000001100002
20000000001111100000000000000000011111002
20000000000110000000000000000000011111002
20000000000000000000000000000000111111002
20000000000000000000000000000000111111102
20000000000000000000000000000001111111102
20000000000000000000000000000001111111102
20000000000000000000000000000000111111002
20000000000000000000000000000000010000002
20000000000000000000000000000000000000002
22222222222222222222222222222222222222222
Saya sengaja membuat bingkai seperti itu di perbatasan dengan 2s untuk membantu saya menghitung jumlah grup 1s di peta boolean itu.
Pertanyaan saya kepada kalian adalah, kenapa saya bisa menghitung jumlah sel (grup 1s) dalam peta boolean seperti itu secara efisien? Saya telah menemukan http://en.wikipedia.org/wiki/Connected-component_labeling yang terlihat sangat terkait dan mirip, tetapi sejauh yang saya lihat, ini berada pada tingkat piksel. Milik saya berada di tingkat boolean. Hanya 1s dan 0s.
Terima kasih banyak.
Jawaban:
Sesuatu dari pendekatan brute force, tetapi dilakukan dengan membalik masalah untuk mengindeks koleksi piksel untuk menemukan daerah, alih-alih rasterisasi pada array.
Cetakan:
sumber
Scipy
melakukan ini, yang mungkin lebih cepat juga ^^ "Tapi mungkin latihan yang bagus dan itu menunjukkan bagaimana melakukan ini secara umum. Saya akan memilih itu.Anda dapat menggunakan
ndimage.label
, yang merupakan cara yang bagus untuk melakukan ini. Ini mengembalikan array baru, dengan setiap fitur memiliki nilai unik, dan jumlah fitur. Anda juga dapat menentukan elemen koneksi.sumber
Berikut ini adalah algoritma yang O (jumlah total piksel + jumlah piksel sel). Kami hanya memindai gambar untuk piksel sel, dan ketika kami menemukannya, kami mengisi sel untuk menghapusnya.
Implementasi dalam Common Lisp, tetapi Anda akan dapat menerjemahkannya ke Python secara sepele.
sumber
Lebih banyak komentar yang diperluas daripada jawaban:
Seperti @interjay telah mengisyaratkan, dalam gambar biner, yaitu satu di mana hanya 2 warna hadir, piksel mengambil nilai 1 atau 0. Ini mungkin atau mungkin tidak benar dalam format representasi gambar yang Anda gunakan tetapi itu benar dalam representasi 'konseptual' gambar Anda; jangan biarkan detail implementasi membingungkan Anda tentang masalah ini. Salah satu detail implementasi adalah penggunaan 2s Anda di sekitar batas gambar - cara yang masuk akal untuk mengidentifikasi zona mati di sekitar gambar, tetapi tidak secara kualitatif memengaruhi biner-ness gambar.
Adapun pemeriksaan N, NE, NW dan W piksel: ini ada hubungannya dengan konektivitas piksel dalam pembentukan komponen. Setiap piksel (batalkan kasus khusus perbatasan) memiliki 8 tetangga (N, S, E, W, NE, NW, SE, SW) tetapi yang mana yang merupakan kandidat untuk dimasukkan dalam komponen yang sama? Kadang-kadang komponen yang hanya bertemu di sudut (NE, NW, SE, SW) tidak dianggap terhubung, kadang-kadang mereka.
Anda harus memutuskan apa yang sesuai untuk aplikasi Anda. Saya sarankan Anda bekerja, dengan tangan, beberapa operasi dari algoritma sekuensial, memeriksa tetangga yang berbeda untuk setiap piksel, untuk merasakan apa yang sedang terjadi.
sumber