OpenCV – 連結成分のラベリングを行う cv2.connectedComponents の使い方

目次

概要

OpenCV で 2 値画像の連結成分のラベリングを行う cv2.connectedComponents() の使い方について解説します。

連結成分のラベリング

連結成分のラベリング (connected component labeling) とは、2 値画像の繋がっている非 0 の画素ごとにラベルを割り当てる処理です。

連結成分のラベリング

cv2.connectedComponents

# アルゴリズムを指定しない場合
retval, labels = cv2.connectedComponents(image[, labels[, connectivity[, ltype]]])
# アルゴリズムを指定する場合
retval, labels = cv2.connectedComponentsWithAlgorithm(image, connectivity, ltype, ccltype[, labels])

公式リファレンス: cv2.connectedComponents

引数
名前 デフォルト値
image ndarray
2値画像 (1チャンネル)
connectivity int, {4, 8} 8
接続していると判定する基準
  • 4: 4連結
  • 8: 8連結
ltype int, {cv2.CV_32S, cv2.CV_CV_16U} cv2.CV_32S
ラベリング結果の型
ccltype ConnectedComponentsAlgorithmsTypes
  • cv2.CCL_WU: 4, 8連結の場合は SAUF アルゴリズムを使用する。
  • cv2.CCL_DEFAULT: 8連結の場合は BBDT アルゴリズム、4連結の場合は SAUF アルゴリズムを使用する。
  • cv2.CCL_GRANA: 8連結の場合は BBDT アルゴリズム、4連結の場合は SAUF アルゴリズムを使用する。
返り値
名前 説明
retval ラベル数
labels ラベリング結果

sample.jpg

In [1]:
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 画像を読み込む。
img = cv2.imread("sample.jpg")

# グレースケールに変換する。
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 2値化する
ret, bin_img = cv2.threshold(gray, 20, 255, cv2.THRESH_BINARY)

# 連結成分のラベリングを行う。
n_labels, labels = cv2.connectedComponents(bin_img)

# ラベル数
print("number of labels:", n_labels)

fig, ax = plt.subplots(figsize=(7, 7))
ax.imshow(labels)

plt.show()
number of labels: 6

cv2.connectedComponentsWithStats

こちらの関数は、ラベリング結果と一緒に重心や大きさなどの構造情報も返します。

# アルゴリズムを指定しない場合
retval, labels, stats, centroids = cv2.connectedComponentsWithStats(
    image[, labels[, stats[, centroids[, connectivity[, ltype]]]]])
# アルゴリズムを指定する場合
retval, labels, stats, centroids = cv2.connectedComponentsWithStatsWithAlgorithm(
    image, connectivity, ltype, ccltype[, labels[, stats[, centroids]]])

公式リファレンス: cv2.connectedComponentsWithStats

引数
名前 デフォルト値
image ndarray
2値画像 (1チャンネル)
connectivity int, {4, 8} 8
接続していると判定する基準
  • 4: 4連結
  • 8: 8連結
ltype int, {cv2.CV_32S, cv2.CV_CV_16U} cv2.CV_32S
ラベリング結果の型
ccltype ConnectedComponentsAlgorithmsTypes
  • cv2.CCL_WU: 4, 8連結の場合は SAUF アルゴリズムを使用する。
  • cv2.CCL_DEFAULT: 8連結の場合は BBDT アルゴリズム、4連結の場合は SAUF アルゴリズムを使用する。
  • cv2.CCL_GRANA: 8連結の場合は BBDT アルゴリズム、4連結の場合は SAUF アルゴリズムを使用する。
返り値
名前 説明
retval ラベル数
labels ラベリング結果
stats 各ラベルの構造情報
centroids 重心

stats(ラベル数, 5) の NumPy 配列です。 各行には、そのラベルの (左上の x 座標, 左上の y 座標, 幅, 高さ, 面積) の情報が格納されています。

In [2]:
# 連結成分のラベリングを行う。
retval, labels, stats, centroids = cv2.connectedComponentsWithStats(bin_img)

for i, row in enumerate(stats):
    print(f"ラベル {i}")
    print(f"* 左上の座標: ({row[cv2.CC_STAT_LEFT]}, {row[cv2.CC_STAT_TOP]})")
    print(f"* 大きさ: ({row[cv2.CC_STAT_WIDTH]}, {row[cv2.CC_STAT_HEIGHT]})")
    print(f"* 面積: {row[cv2.CC_STAT_AREA]}")
ラベル 0
* 左上の座標: (0, 0)
* 大きさ: (420, 362)
* 面積: 126715
ラベル 1
* 左上の座標: (182, 44)
* 大きさ: (63, 62)
* 面積: 2016
ラベル 2
* 左上の座標: (256, 96)
* 大きさ: (88, 87)
* 面積: 3872
ラベル 3
* 左上の座標: (144, 166)
* 大きさ: (118, 117)
* 面積: 10910
ラベル 4
* 左上の座標: (286, 247)
* 大きさ: (83, 83)
* 面積: 3486
ラベル 5
* 左上の座標: (25, 251)
* 大きさ: (71, 71)
* 面積: 5041

stats(ラベル数, 2) の NumPy 配列です。 各行には、そのラベルの重心が格納されています。

In [3]:
for i, row in enumerate(centroids):
    print(f"ラベル: {i}, 座標: ({row[0]:.2f}, {row[1]:.2f})")
ラベル: 0, 座標: (210.01, 172.93)
ラベル: 1, 座標: (215.46, 74.50)
ラベル: 2, 座標: (299.50, 139.00)
ラベル: 3, 座標: (202.01, 224.00)
ラベル: 4, 座標: (327.25, 274.33)
ラベル: 5, 座標: (60.00, 286.00)

参考文献

コメント

コメントする

目次