回答編集履歴

1

コード追加

2018/09/17 11:33

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -41,3 +41,99 @@
41
41
  print('number of black pixels', num_black) # number of black pixels 87
42
42
 
43
43
  ```
44
+
45
+
46
+
47
+ ----
48
+
49
+
50
+
51
+ 追記
52
+
53
+
54
+
55
+ 以下のように斜めになっている輪郭線が別々の輪郭であると認識されてしまうのが問題のようで、findContours() のアルゴリズムをいくつか選んでみましたが、うまくいきませんでした。
56
+
57
+ ```
58
+
59
+ □□■□
60
+
61
+ □■□■
62
+
63
+ ■□□□■
64
+
65
+ ```
66
+
67
+
68
+
69
+ 今回のように幅が1ピクセルしかないような輪郭線の場合、findContours は向いていないと思います。膨張演算で線の幅を太くすると、うまくいくと思いますが、右上の小さい穴が消えてしまいますね。
70
+
71
+
72
+
73
+
74
+
75
+ 4連結でラベリングし、背景ラベルを除くことで、一応白い領域の数は取得できました。
76
+
77
+
78
+
79
+ ```python
80
+
81
+ import cv2
82
+
83
+ import numpy as np
84
+
85
+ import matplotlib.pyplot as plt
86
+
87
+
88
+
89
+ # 画像をグレースケール形式で読み込む。
90
+
91
+ src = cv2.imread('ttt.png')
92
+
93
+
94
+
95
+ # 連結成分のラベリングを行う。
96
+
97
+ gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
98
+
99
+ num_labels, labels = cv2.connectedComponents(gray, connectivity=4)
100
+
101
+
102
+
103
+ # ラベリング結果
104
+
105
+ print('number of labels', num_labels)
106
+
107
+ print('number of white region', num_labels - 1) # 背景ラベルを除く
108
+
109
+ print(labels.shape, labels.dtype) # (362, 420) int32
110
+
111
+
112
+
113
+ # ラベルに応じて、色をつけた画像を作成する。
114
+
115
+ dst = np.zeros_like(src)
116
+
117
+ dst[labels == 0] = [255, 255, 0] # 背景ラベル 水色
118
+
119
+ dst[labels == 1] = [0, 255, 0] # ラベル1 緑
120
+
121
+ dst[labels == 2] = [0, 0, 255] # ラベル2 赤
122
+
123
+ dst[labels == 3] = [0, 255, 255] # ラベル3 黄色
124
+
125
+ dst[labels == 4] = [255, 0, 255] # ラベル4 紫
126
+
127
+ dst[labels == 5] = [152, 145, 234] # ラベル5 ピンク
128
+
129
+ dst[labels == 6] = [100, 100, 100] # ラベル6 グレー
130
+
131
+
132
+
133
+ plt.imshow(cv2.cvtColor(dst, cv2.COLOR_BGR2RGB))
134
+
135
+ plt.show()
136
+
137
+ ```
138
+
139
+ ![イメージ説明](8c810534c07d836e44fea9cbfe358fd7.png)