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