Terrarium

いわゆる掃き溜めの ありふれた有象無象

2値画像中のある円領域内の画素数をカウントしたい

コーディング中…

既存論文の実装のために,2値画像中のある円領域内の画素数をカウントする必要が出てきた. 円領域…ということで愚直に実装してみたところ

# imgが画像(numpy array)
# p_x, p_yが円を囲む正方形領域の左上の点
# lengthが円領域の直径
c_x = length / 2 + p_x
c_y = length / 2 + p_y
radius = length / 2

count = 0
for x, y in itertools.product(range(p_x, p_x+length), range(p_y, p_y+length)):
    if ((x - c_x)**2 + (y - c_y)**2 <= radius**2) and img[x][y] > 0:
        count += 1

… 終わらない… 5分経っても終わらない…

調べてみた

こうなることはある程度予測できていたので調べてみた. すると次のStackOverflowのページがヒットした.

stackoverflow.com

np.ogridというものを使っているらしいが時間がないのであとで調べようということで,次のように実装し直した. createCircularMaskTrueFalseによるマスクを返してくれるので,正方形領域であるwindowを抽出したあとでそのマスクをかける. あとはただのnp.arrayなのでnp.count_nonzeroを実行すればカウントできる.

def createCircularMask(h, w, center=None, radius=None):
    if center is None: # use the middle of the image
        center = [int(w/2), int(h/2)]
    if radius is None: # use the smallest distance between the center and image walls
        radius = min(center[0], center[1], w-center[0], h-center[1])
    Y, X = np.ogrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y-center[1])**2)

    mask = dist_from_center <= radius
    return mask

c_x = length / 2
c_y = length / 2
radius = length / 2
count = 0

window = img[p_x: p_x+length, p_y: p_y+length]
window = window[createCircularMask(length, length)]
count = np.count_nonzero(window)

すぐに結果が返ってきた. やはりnumpyは偉大ですね.