質問するログイン新規登録

回答編集履歴

2

たぶんOK

2020/01/05 09:37

投稿

退会済みユーザー
answer CHANGED
@@ -1,4 +1,170 @@
1
- **2020-01-05追補**
1
+ **2020-01-05追補2**
2
+ ![上--(重心X,矩形Y)、下--根拠](dbedcf3c1baf96774d25eb95f4549952.png)
3
+ 上 (重心X,矩形Y)を青丸で表示
4
+ 下 根拠を図示
5
+
6
+ ```Python3
7
+ import cv2
8
+ import numpy as np
9
+ from matplotlib import pyplot as plt
10
+
11
+
12
+
13
+ src= cv2.imread("kuro1.png")
14
+
15
+
16
+
17
+ #ユニフォーム抽出
18
+ dst1 = cv2.inRange(src, (3,3,3), (10,8,10))
19
+ dst2 = cv2.blur(dst1, ksize=(5,5))
20
+ ret,thresh1 = cv2.threshold(dst2,127,255,cv2.THRESH_BINARY)
21
+
22
+ # ラベリング処理(x座標)
23
+ label = cv2.connectedComponentsWithStats(thresh1)
24
+
25
+ stats = label[2]
26
+ area = stats[:, cv2.CC_STAT_WIDTH] * stats[:, cv2.CC_STAT_HEIGHT]
27
+ top2_idx = area.argsort()[-3:-1] # 2番目、3番めに面積が大きいラベル (1番目は背景なので除く)
28
+
29
+ # オブジェクト情報を項目別に抽出
30
+ data = label[2]
31
+ center = label[3]
32
+
33
+ # ラベリング結果書き出し用に二値画像をカラー変換
34
+ color_src = cv2.cvtColor(thresh1, cv2.COLOR_GRAY2BGR)
35
+
36
+ # オブジェクト情報を利用してラベリング結果を表示
37
+ lst_pos = []
38
+ for i in top2_idx:
39
+ # 各オブジェクトの外接矩形を赤枠で表示
40
+ x0 = data[i][0]
41
+ y0 = data[i][1]
42
+ x1 = data[i][0] + data[i][2]
43
+ y1 = data[i][1] + data[i][3]
44
+ cv2.rectangle(color_src, (x0, y0), (x1, y1), (0, 0, 255))
45
+
46
+ # 各オブジェクトの重心座標をに黄文字で表示
47
+ cv2.putText(color_src, "X: " + str(int(center[i][0])), (x1 - 10, y1 + 15), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255))
48
+
49
+ # 追加コード: 重心座標を書き出す
50
+ # img = thresh1[y0:y1,x0:x1]
51
+ # lst_pos.append((y0,y1,x0,x1,int(center[i][0])))
52
+ lst_pos.append((int(center[i][0]),int(center[i][1])))
53
+
54
+
55
+ # x座標の位置
56
+ cv2.imshow('x',color_src)
57
+
58
+ #「背景」となる画像の取り込み(グレースケール)
59
+ img_src01 = cv2.imread("zero1.png", 0)
60
+
61
+ #「差分」をもった画像の取り込み(グレースケール)
62
+ img_src02 = cv2.imread("kuro1.png", 0)
63
+
64
+ #「背景差分」計算用オブジェクトの作成 
65
+ # bgObj = cv2.bgsegm.createBackgroundSubtractorMOG()
66
+ # 修正点: ただただ手元のOpenCVでエラーが出ないようにするための目的で変更。
67
+ bgObj = cv2.createBackgroundSubtractorMOG2()
68
+
69
+ #差分となっている「前景領域」に対してマスクをかける
70
+ fgmask = bgObj.apply(img_src01)
71
+ fgmask = bgObj.apply(img_src02)
72
+
73
+ # ラベリング処理(y座標)
74
+ label2 = cv2.connectedComponentsWithStats(fgmask)
75
+
76
+ ### 追加した部分1
77
+ stats2 = label2[2]
78
+ area2 = stats2[:, cv2.CC_STAT_WIDTH] * stats2[:, cv2.CC_STAT_HEIGHT]
79
+ top2_idx2 = area2.argsort()[-3:-1] # 2番目、3番めに面積が大きいラベル (1番目は背景なので除く)
80
+
81
+ # オブジェクト情報を項目別に抽出
82
+ data2 = label2[2]
83
+ center2 = label2[3]
84
+
85
+ # ラベリング結果書き出し用に二値画像をカラー変換
86
+ color_src2 = cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR)
87
+
88
+ # 追加コード: 適当に追加
89
+ img_col = cv2.imread("zero1.png")
90
+
91
+ # オブジェクト情報を利用してラベリング結果を表示
92
+ for i in top2_idx2:
93
+ # 各オブジェクトの外接矩形を赤枠で表示
94
+ x0 = data2[i][0]
95
+ y0 = data2[i][1]
96
+ x1 = data2[i][0] + data2[i][2]
97
+ y1 = data2[i][1] + data2[i][3]
98
+ cv2.rectangle(color_src2, (x0, y0), (x1, y1), (0, 0, 255))
99
+
100
+ # 各オブジェクトの重心座標をに黄文字で表示
101
+ cv2.putText(color_src2, "Y: " + str(int(y1)), (x1 - 10, y1 + 30), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255))
102
+
103
+ ##############################################
104
+ # 内外判定
105
+ poly = np.array([[int(x0),int(y0)], [int(x0),int(y1)], [int(x1),int(y1)], [int(x1),int(y0)]])
106
+ for j in range(len(lst_pos)):
107
+
108
+ if cv2.pointPolygonTest( poly, lst_pos[j], False)== 1:
109
+ # print("in")
110
+ # 青で描画
111
+ img_col = cv2.circle(img_col,(lst_pos[j][0],y1), 10, (255,0,0), 2)
112
+ # else:
113
+ # print("out")
114
+ ##############################################
115
+
116
+ cv2.imshow('img_col',img_col)
117
+
118
+ cv2.imshow('y',color_src2)
119
+ ##
120
+ ##
121
+ ### この下からコートの画像に値を点で表したい!!!!!!!!!!!!!!!
122
+ ##
123
+ ##midori=cv2.imread("coat2.png")
124
+ ##
125
+ ### !!!!!!!!!!!新たにここを追加!!!!!!!!!!
126
+ ### この座標部分をどう直したら良いかがわかりません!!!!!!!!!!!
127
+ ##
128
+ ##
129
+ ### 変更点: coatが未定義のため適当に変更
130
+ ### color_src3 = cv2.cvtColor(coat, cv2.COLOR_GRAY2BGR)
131
+ ### coat3=cv2.circle(color_src3,(int(center[i][0]),int(top2_idx2(y1))), 63, (0,0,255), -1)
132
+ ##
133
+ ### 変更点: 画像を適当に読み込み
134
+ ### img_col = cv2.imread("zero1.png")
135
+ ##img_col2 = img_col.copy()
136
+ ##
137
+ ### 変更点: Centerを赤で描画
138
+ ##for i in range(len(center)):
139
+ ## img_col2 = cv2.circle(img_col2,(int(center[i][0]),int(center[i][1])), 3, (0,0,255), -1)
140
+ ##
141
+ ##
142
+ ### 変更点: 矩形の頂点を緑で描画
143
+ ##for i in top2_idx2:
144
+ ## x0 = data2[i][0]
145
+ ## y0 = data2[i][1]
146
+ ## x1 = data2[i][0] + data2[i][2]
147
+ ## y1 = data2[i][1] + data2[i][3]
148
+ ## img_col2 = cv2.circle(img_col2,(int(x0),int(y0)), 3, (0,255,0), -1)
149
+ ## img_col2 = cv2.circle(img_col2,(int(x0),int(y1)), 3, (0,255,0), -1)
150
+ ## img_col2 = cv2.circle(img_col2,(int(x1),int(y0)), 3, (0,255,0), -1)
151
+ ## img_col2 = cv2.circle(img_col2,(int(x1),int(y1)), 3, (0,255,0), -1)
152
+ ##
153
+ ### cv2.imshow("img_col",img_col)
154
+ ##
155
+ ### 変更点: Centerのデバグ用
156
+ ##img_merged = cv2.addWeighted(img_col2, 0.8, color_src, 0.2, 0)
157
+ ##cv2.imshow("img_merged",img_merged)
158
+
159
+ cv2.imwrite("img_col2_merged.png",np.vstack((img_col,img_merged)))
160
+ cv2.waitKey(0)
161
+ cv2.destroyAllWindows()
162
+
163
+ ```
164
+
165
+ ---
166
+
167
+ **2020-01-05追補1**
2
168
  > この画像にプログラムに書かれているラベリング処理を2回した時に求めた
3
169
  > x座標とy座標の値を赤い点として表示させたいです
4
170
  >

1

追補

2020/01/05 09:36

投稿

退会済みユーザー
answer CHANGED
@@ -1,3 +1,154 @@
1
+ **2020-01-05追補**
2
+ > この画像にプログラムに書かれているラベリング処理を2回した時に求めた
3
+ > x座標とy座標の値を赤い点として表示させたいです
4
+ >
5
+ > 赤い点と書いてありますがわかりやすくばつ印などでも良いです
6
+
7
+ プログラム全体の意図が良く掴めていませんが、「座標をプロットする」という点において、希望箇所(!!!の辺り)に対応コードを追加したため、これで解決できると思います。
8
+
9
+ また、赤い点、とありますが、Centerと矩形と両方とも位置を示すラベルと思いますので、色を分けて表示させました。
10
+ ※OpenCVで描画する際にバツより丸の方が実装しやすいため丸で実装しています。
11
+
12
+ ![座標追加イメージ](2ef58c920562a140c496e70be5090202.png)
13
+ 赤: Center
14
+ 緑: 矩形の頂点
15
+
16
+ コメントの
17
+ > `for i in top2_idx2`の部分を
18
+ > `j`に変えてみることで解決したりするのでしょうか?
19
+ については、今回は二重ループの出番がないので使用していません。
20
+ 二重ループで`i`とは別の変数を使いたいときに`j`の出番があります。
21
+
22
+ 今回は!!!の部分にfor文を追加しましたが、ラベル作成時にこの処理もまとめてやってしまった方がfor文が少なくなりますので、より早くそして、バグの発生する余地の少ないコードになると思います。
23
+
24
+ ```Python3
25
+ import cv2
26
+ import numpy as np
27
+ from matplotlib import pyplot as plt
28
+
29
+ src= cv2.imread("kuro1.png")
30
+
31
+ #ユニフォーム抽出
32
+ dst1 = cv2.inRange(src, (3,3,3), (10,8,10))
33
+ dst2 = cv2.blur(dst1, ksize=(5,5))
34
+ ret,thresh1 = cv2.threshold(dst2,127,255,cv2.THRESH_BINARY)
35
+
36
+ # ラベリング処理(x座標)
37
+ label = cv2.connectedComponentsWithStats(thresh1)
38
+
39
+ stats = label[2]
40
+ area = stats[:, cv2.CC_STAT_WIDTH] * stats[:, cv2.CC_STAT_HEIGHT]
41
+ top2_idx = area.argsort()[-3:-1] # 2番目、3番めに面積が大きいラベル (1番目は背景なので除く)
42
+
43
+ # オブジェクト情報を項目別に抽出
44
+ data = label[2]
45
+ center = label[3]
46
+
47
+ # ラベリング結果書き出し用に二値画像をカラー変換
48
+ color_src = cv2.cvtColor(thresh1, cv2.COLOR_GRAY2BGR)
49
+
50
+ # オブジェクト情報を利用してラベリング結果を表示
51
+ for i in top2_idx:
52
+ # 各オブジェクトの外接矩形を赤枠で表示
53
+ x0 = data[i][0]
54
+ y0 = data[i][1]
55
+ x1 = data[i][0] + data[i][2]
56
+ y1 = data[i][1] + data[i][3]
57
+ cv2.rectangle(color_src, (x0, y0), (x1, y1), (0, 0, 255))
58
+
59
+ # 各オブジェクトの重心座標をに黄文字で表示
60
+ cv2.putText(color_src, "X: " + str(int(center[i][0])), (x1 - 10, y1 + 15), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255))
61
+
62
+ cv2.imshow('x',color_src)
63
+
64
+ #「背景」となる画像の取り込み(グレースケール)
65
+ img_src01 = cv2.imread("zero1.png", 0)
66
+
67
+ #「差分」をもった画像の取り込み(グレースケール)
68
+ img_src02 = cv2.imread("kuro1.png", 0)
69
+
70
+ #「背景差分」計算用オブジェクトの作成 
71
+ # bgObj = cv2.bgsegm.createBackgroundSubtractorMOG()
72
+ # 修正点: ただただ手元のOpenCVでエラーが出ないようにするための目的で変更。
73
+ bgObj = cv2.createBackgroundSubtractorMOG2()
74
+
75
+ #差分となっている「前景領域」に対してマスクをかける
76
+ fgmask = bgObj.apply(img_src01)
77
+ fgmask = bgObj.apply(img_src02)
78
+
79
+ # ラベリング処理(y座標)
80
+ label2 = cv2.connectedComponentsWithStats(fgmask)
81
+
82
+ ### 追加した部分1
83
+ stats2 = label2[2]
84
+ area2 = stats2[:, cv2.CC_STAT_WIDTH] * stats2[:, cv2.CC_STAT_HEIGHT]
85
+ top2_idx2 = area2.argsort()[-3:-1] # 2番目、3番めに面積が大きいラベル (1番目は背景なので除く)
86
+
87
+ # オブジェクト情報を項目別に抽出
88
+ data2 = label2[2]
89
+ center2 = label2[3]
90
+
91
+ # ラベリング結果書き出し用に二値画像をカラー変換
92
+ color_src2 = cv2.cvtColor(fgmask, cv2.COLOR_GRAY2BGR)
93
+
94
+ # オブジェクト情報を利用してラベリング結果を表示
95
+ for i in top2_idx2:
96
+ # 各オブジェクトの外接矩形を赤枠で表示
97
+ x0 = data2[i][0]
98
+ y0 = data2[i][1]
99
+ x1 = data2[i][0] + data2[i][2]
100
+ y1 = data2[i][1] + data2[i][3]
101
+ cv2.rectangle(color_src2, (x0, y0), (x1, y1), (0, 0, 255))
102
+
103
+ # 各オブジェクトの重心座標をに黄文字で表示
104
+ cv2.putText(color_src2, "Y: " + str(int(y1)), (x1 - 10, y1 + 30), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 255))
105
+
106
+ cv2.imshow('y',color_src2)
107
+
108
+
109
+ # この下からコートの画像に値を点で表したい!!!!!!!!!!!!!!!
110
+
111
+ midori=cv2.imread("coat2.png")
112
+
113
+ # !!!!!!!!!!!新たにここを追加!!!!!!!!!!
114
+ # この座標部分をどう直したら良いかがわかりません!!!!!!!!!!!
115
+
116
+
117
+ # 変更点: coatが未定義のため適当に変更
118
+ # color_src3 = cv2.cvtColor(coat, cv2.COLOR_GRAY2BGR)
119
+ # coat3=cv2.circle(color_src3,(int(center[i][0]),int(top2_idx2(y1))), 63, (0,0,255), -1)
120
+
121
+ # 変更点: 画像を適当に読み込み
122
+ img_col = cv2.imread("zero1.png")
123
+
124
+ # 変更点: Centerを赤で描画
125
+ for i in range(len(center)):
126
+ img_col = cv2.circle(img_col,(int(center[i][0]),int(center[i][1])), 3, (0,0,255), -1)
127
+
128
+
129
+ # 変更点: 矩形の頂点を緑で描画
130
+ for i in top2_idx2:
131
+ x0 = data2[i][0]
132
+ y0 = data2[i][1]
133
+ x1 = data2[i][0] + data2[i][2]
134
+ y1 = data2[i][1] + data2[i][3]
135
+ img_col = cv2.circle(img_col,(int(x0),int(y0)), 3, (0,255,0), -1)
136
+ img_col = cv2.circle(img_col,(int(x0),int(y1)), 3, (0,255,0), -1)
137
+ img_col = cv2.circle(img_col,(int(x1),int(y0)), 3, (0,255,0), -1)
138
+ img_col = cv2.circle(img_col,(int(x1),int(y1)), 3, (0,255,0), -1)
139
+
140
+ cv2.imshow("img_col",img_col)
141
+
142
+ # 変更点: Centerのデバグ用
143
+ # img_merged = cv2.addWeighted(img_col, 0.8, color_src, 0.2, 0)
144
+ # cv2.imshow("img_merged",img_merged)
145
+
146
+ cv2.waitKey(0)
147
+ cv2.destroyAllWindows()
148
+ ```
149
+
150
+ ---
151
+
1
152
  > 上記の2箇所のラベリング処理の部分のputtextでx座標とy座標を渡しているので
2
153
  > その値を新たな zero1.pngの画像に点として表示したいです
3
154