Menghitung jumlah grup 1s di peta boolean dari numpy.array

16

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:contoh

Dan memprosesnya untuk sel merah (pada dasarnya, mematikan nilai RGB di bawah ambang batas tertentu untuk merah): masukkan deskripsi gambar di sini

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.

Ibrahim C. Kurt
sumber
Pelabelan komponen yang terhubung adalah persis apa yang Anda butuhkan. Saya tidak tahu mengapa Anda berpikir itu berbeda, karena artikel Wikipedia juga memiliki contoh dimulai dengan array 1s dan 0s.
Saya tahu tampilannya mirip (atau mungkin sama), saya tidak bisa sepenuhnya memahami seluruh halaman wikipedia karena bahasa Inggris bukan bahasa ibu saya. Bagian "Algoritma berurutan" pada halaman tampak seperti berurusan dengan 1 dan 0 tetapi saya masih tidak melihat logika di baliknya. Forex, mengapa memulai dengan memeriksa utara, timur laut, barat laut, dan barat?
Masalah ini terpecahkan.
Bagaimana jika sel-sel yang diinginkan tumpang tindih? Bukankah Anda seharusnya mencari fitur melingkar secara khusus sehingga Anda dapat membedakan dua sel yang terlihat terhubung, bukan hanya menemukan gumpalan terus menerus?
endolith
keadaan menjadi jauh lebih rumit ketika gambar imunohistokimia yang Anda miliki memiliki kualitas buruk dalam hal jumlah sel yang tumpang tindih, resolusi, standar deviasi dari nilai-nilai piksel begitu dan begitu ... Saya telah mencoba untuk menulis sebuah program kecil yang berfungsi baik untuk tujuan seperti itu tetapi sepertinya gambar input dan kondisinya sangat penting untuk hasil yang sempurna ..
Ibrahim C. Kurt

Jawaban:

6

Sesuatu dari pendekatan brute force, tetapi dilakukan dengan membalik masalah untuk mengindeks koleksi piksel untuk menemukan daerah, alih-alih rasterisasi pada array.

data = """\
000000011111111000000000000000000000000
000000011111111000000000000000000000000
000000011111111000000000000000000000000
000000001111110000000001000000000110000
000000000111110000000011000000001111100
000000000011100000000000100000011111100
000000000000000000000000000000011111100
000000000000000000000000000000011111110
000000000000000000000000000000111111110
000000000000000000000000000000111111110
000000000000000000000000000000011111100
000000000000000000000000000000001000000
000000000000000000000000000000000000000"""

from collections import namedtuple
Point = namedtuple('Point', 'x y')

def points_adjoin(p1, p2):
    # to accept diagonal adjacency, use this form
    #return -1 <= p1.x-p2.x <= 1 and -1 <= p1.y-p2.y <= 1
    return (-1 <= p1.x-p2.x <= 1 and p1.y == p2.y or
             p1.x == p2.x and -1 <= p1.y-p2.y <= 1)

def adjoins(pts, pt):
    return any(points_adjoin(p,pt) for p in pts)

def locate_regions(datastring):
    data = map(list, datastring.splitlines())
    regions = []
    datapts = [Point(x,y) 
                for y,row in enumerate(data) 
                    for x,value in enumerate(row) if value=='1']
    for dp in datapts:
        # find all adjoining regions
        adjregs = [r for r in regions if adjoins(r,dp)]
        if adjregs:
            adjregs[0].add(dp)
            if len(adjregs) > 1:
                # joining more than one reg, merge
                regions[:] = [r for r in regions if r not in adjregs]
                regions.append(reduce(set.union, adjregs))
        else:
            # not adjoining any, start a new region
            regions.append(set([dp]))
    return regions

def region_index(regs, p):
    return next((i for i,reg in enumerate(regs) if p in reg), -1)

def print_regions(regs):
    maxx = max(p.x for r in regs for p in r)
    maxy = max(p.y for r in regs for p in r)
    allregionpts = reduce(set.union, regs)
    for y in range(-1,maxy+2):
        line = []
        for x in range(-1,maxx+2):
            p = Point(x, y)
            if p in allregionpts:
                line.append(str(region_index(regs, p)))
            else:
                line.append('.')
        print ''.join(line)
    print


# test against data set
regs = locate_regions(data)
print len(regs)
print_regions(regs)

Cetakan:

4
........................................
........00000000........................
........00000000........................
........00000000........................
.........000000.........1.........33....
..........00000........11........33333..
...........000...........2......333333..
................................333333..
................................3333333.
...............................33333333.
...............................33333333.
................................333333..
.................................3......
........................................

sumber
wow ... saya tidak tahu harus berkata apa. Sangat keren. Dan benar-benar berfungsi. Terima kasih Paul.
Begitu banyak pekerjaan dalam hal ini, ketika sudah ada fungsi dalam Scipymelakukan ini, yang mungkin lebih cepat juga ^^ "Tapi mungkin latihan yang bagus dan itu menunjukkan bagaimana melakukan ini secara umum. Saya akan memilih itu.
Zelphir Kaltstahl
13

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.

import scipy
from scipy import ndimage
import matplotlib.pyplot as plt

#flatten to make greyscale, using your second red-black image as input.
im = scipy.misc.imread('blobs.jpg',flatten=1)
#smooth and threshold as image has compression artifacts (jpg)
im = ndimage.gaussian_filter(im, 2)
im[im<10]=0
blobs, number_of_blobs = ndimage.label(im)
print 'Number of blobls:', number_of_blobs

plt.imshow(blobs)
plt.show()

#Output is:
Number of blobls: 30

masukkan deskripsi gambar di sini

Saya tahu
sumber
Terima kasih fraxel. Itu benar-benar berfungsi sebagai solusi cepat dan kotor, tapi mungkin saya harus meningkatkan kualitas gambar, karena seperti yang Anda lihat ada banyak sel yang digabungkan. Jawabannya harus 30 sel. Sekali lagi terima kasih banyak. (sunting: Saya mencoba meningkatkan kualitas resolusi gambar dan kemudian menghapusnya dengan kode Anda tetapi masih menggabungkan banyak sel. Ini harus tentang cara meratakan = 1 atau mengembang berfungsi?)
1
@Ibrahim C. Kurt - Saya telah memperbarui untuk memperbaikinya (saya baru saja memperhatikan!). Masalahnya adalah gambar yang diunggah adalah jpg, jadi ada banyak artefak. Sejumlah kecil smoothing dan thresholding menyelesaikan itu .. Seharusnya berfungsi dengan baik untuk gambar png (saya pikir ...)
tanpa perlu smoothing dan thresholding.
Ini benar-benar berfungsi. Kamu benar. Tanpa perlu modifikasi lebih lanjut, hanya mengubahnya ke png dari jpg sudah cukup. Terima kasih banyak. Saya memiliki lebih dari 2 jawaban sempurna sekarang. Saya tidak tahu harus berbuat apa dan berkata: D
@Ibrahim C. Kurt - lucky you;)
6

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.

(defun flood-fill (picture i j target-color replacement-color)
  ;; http://en.wikipedia.org/wiki/Flood_fill
  (when (= (aref picture i j) target-color)
    (setf (aref picture i j) replacement-color)
    (when (plusp i)
      (flood-fill picture (1- i) j target-color replacement-color))
    (when (< (1+ i) (array-dimension picture 0))
      (flood-fill picture (1+ i) j target-color replacement-color))
    (when (plusp j)
      (flood-fill picture i (1- j) target-color replacement-color))
    (when (< (1+ j) (array-dimension picture 1))
      (flood-fill picture i (1+ j) target-color replacement-color)))
  picture)


(defun count-cells (picture)
  (loop
    :with cell-count = 0
    :for i :from 0 :below (array-dimension picture 0)
    :do (loop
          :for j :from 0 :below (array-dimension picture 1)
          :unless (zerop (aref picture i j))
          :do (progn (incf cell-count)
                     (flood-fill picture i j 1 0)))
    :finally (return cell-count)))




(count-cells
  (make-array '(128 171) :element-type 'bit
              :initial-contents
              #(#171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111000000000000000000001110000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000000000011111100
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111000000000000000000000011111100
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111110
                #171*000000000001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111110
                #171*000000000011111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111110
                #171*000000000011111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111100
                #171*000000000011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
                #171*000000000001111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
                #171*000000000001111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
                #171*000000000000011110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
                #171*000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111000000000000000000011
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111110000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111000000000000000000000111111110000000000000000000
                #171*000000000000000000111111000000000000000000000000000000000000000000000000000000111110000000000000000000000000000000000001111111100001111000000000011111110000000000000000000
                #171*000000000000000000111111100000000000000000000000000000000000000000000000000011111110000000000000000000000000000000000111111111100011111100000000011111100000000000000000000
                #171*000000000000000000111111100000000000000000000000000000000000000000000000000011111110000000000000000000000000000000000111111111110111111110000000000100000000000000000000000
                #171*000000000000000000111111100000000000000000000000000000000000000000000000000011111100000000000000000000000000000000000111111111110111111110000000000000000000000000000000000
                #171*000000000000000000111111100000000000000000000000000000000000000000000000000011111100000000000000000000000000000000000011111111100111111110000000000000000000000000000000000
                #171*000000000000000000111111100000000000000000000000000000000000000000000000000011111100000000000000000000000000000000000001111111100111111110000000000000000000000000000000000
                #171*000000000000000000011111100000000000000000000000000000000000000000000000000011111001110000000000000000000000000000000000011111000011111110000000000000000000000000000000000
                #171*000000000000000000010110000000000000000000000000000000000000000000000000000000000011111000000000000000000000000000000000000000000000111010000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111000000000000000000000000000000000000000000000000000000111100000000000000000000000
                #171*000000000000000000000000000000000000000000000111100000000000000000000000000000000000111100000000000000000000000000000000000000000000000000000011111111100000000000000000000
                #171*100000000000000000000000000000000000000000001111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111100000000000000000000
                #171*111100000000000000000000000000000000000000011111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111100000000000000000000
                #171*111100000000000000000000000000000000000000011111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111100000000000000000000
                #171*111100000000000000000000000000000000000000111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111100000000000000000011
                #171*111100000000000000000000000000000000000000111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011110000000000000000000111
                #171*111100000000000000000000000000000000000000011111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111
                #171*000000000000000000000000000000000000000000011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
                #171*000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111100000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111100000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111100000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000001111111100000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111100000000000000000000000000000000000000000111111000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111100000000000000000000000000000000000000111110000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111100000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111110000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111110000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000011111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000011100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000011000000000000000000000000000000000000000000000000000001111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000001111100000000000000000000000000000000000000000000000000000111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000111111110000000000000000000000000000000000000000011111100000000000000000000000000000000000000000000000000111111000000000000000000000000000000000000000000000
                #171*000000000000000111111111000000000000000000000000000000000000000011111100000000000000000000000000000000000000000000000001111111100000000000000000000000000000000000000000000
                #171*000000000000000111111110000000000000000000000000000000000000000111111110000000000000000000000000000000000000000000000001111111100000000000000000000000000000000000000000000
                #171*000000000000000111111110000000000000000000000000000000000000001111111110000000000000000000000000000000000000000000000001111111110000000000000000001111111000000000000000000
                #171*000000000000000011111110000000000000000000000000000000000000001111111110000000000000000000000000000000000000000000000001111111110000000000000000011111111100000000000000000
                #171*000000000000000001110000000000000000000000000000000000000000000111111110000000000000000000000000000000000000000000000000011111100000000000000000011111111100000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000000000000000000000000000000001111000000000000000000011111111100000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000011111000000000000000000000000000000000000000000000000000000000000000000000000000011111111100000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111100000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111000000000000000000000000000000000000000000001111111000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111100000000000000000000000000000000000000000000100010000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000001111100000000000000000111111110000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000011111111110000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000011111111110000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000011111111110000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111111000000000000011111111110000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000011111110000000000000011111111100000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000001111100000000000000010111111100000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000001111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000011111111110000000000000000000000000000000000000011111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000011111111110000000000000000000000000000000000000111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000011111111110000000000000000000000000000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000001111111110000000000000000000000000000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000001111111000000000000000000000000000000000000001111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000000000000000000000000000000000011111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000011111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000011111100000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000001111111110000000000000110000000000000000000000001111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000001111111110000000000001111100000000000000000000011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000001111111110000000000111111111000000000000000000011111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000111111110000000000111111111000000000000000000111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000111111111000000000111111111100000000000000000111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000011111100001111000111111111100000000000000000111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000111111100111111111100000000000000000011111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000000111111100011111111100000000000000000001110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                #171*000000000000000000000000001111111100011111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)))
--> 30

sumber
Hai Pascal, terima kasih banyak atas jawabannya. Saya melihat program Anda menemukan jawaban yang benar dengan sangat bersih. Masalahnya adalah saya tidak tahu bahasa Common Lisp itu, tetapi saya akan mencoba mencari tahu dan menulis naskah yang sama dengan Python.
3

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