回答編集履歴

3

d

2019/11/02 06:08

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -41,8 +41,6 @@
41
41
  ## 追記
42
42
 
43
43
 
44
-
45
- 一番大きい輪郭の面積と面積が一定以上の輪郭だけ残すという処理を記載しました。
46
44
 
47
45
 
48
46
 
@@ -94,31 +92,27 @@
94
92
 
95
93
  rects.append(cv2.boundingRect(cnt))
96
94
 
95
+
97
96
 
97
+ if not rects:
98
98
 
99
- # 面積が大きい順にソートする。
99
+ return None # 1つも検出されなかった場合
100
-
101
- rects = list(sorted(rects, key=lambda x: x[2] * x[3], reverse=True))
102
-
103
- print(rects)
104
100
 
105
101
 
106
102
 
107
- # 一番面積が大きい輪郭
103
+ # 面積が一番大きい長方形を取得する。
108
104
 
105
+ max_rect = max(rects, key=lambda x: x[2] * x[3])
106
+
109
- max_rect = rects[0]
107
+ max_rect_area = max_rect[2] * max_rect[3]
110
108
 
111
109
 
112
110
 
113
- # 一番面積が大きい輪郭以外で面積が一定値以上あるもの
111
+ # 一番面積が大きい輪郭面積が一定値以上ならそれを返す。
114
112
 
115
- rects = list(filter(lambda x: x[2] * x[3] >= 50, rects[1:]))
113
+ # そうでないなら None を返す。
116
114
 
117
- rects += [max_rect]
115
+ return max_rect if max_rect_area > 500 else None
118
-
119
-
120
-
121
- return rects
122
116
 
123
117
 
124
118
 
@@ -132,13 +126,15 @@
132
126
 
133
127
  # 対象の色の領域を探す。
134
128
 
135
- rects = find_rect_of_target_color(img)
129
+ max_rect = find_rect_of_target_color(img)
136
130
 
137
131
 
138
132
 
139
133
  # 矩形を描画する。
140
134
 
135
+ if max_rect:
136
+
141
- for x, y, w, h in rects:
137
+ x, y, w, h = max_rect
142
138
 
143
139
  cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), thickness=2)
144
140
 

2

d

2019/11/02 06:08

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -112,7 +112,7 @@
112
112
 
113
113
  # 一番面積が大きい輪郭以外で面積が一定値以上あるもの
114
114
 
115
- rects = list(filter(lambda x: x[2] * x[3] >= 50, rects[:-1]))
115
+ rects = list(filter(lambda x: x[2] * x[3] >= 50, rects[1:]))
116
116
 
117
117
  rects += [max_rect]
118
118
 

1

d

2019/11/02 04:45

投稿

tiitoi
tiitoi

スコア21956

test CHANGED
@@ -35,3 +35,119 @@
35
35
  cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), thickness=2)
36
36
 
37
37
  ```
38
+
39
+
40
+
41
+ ## 追記
42
+
43
+
44
+
45
+ 一番大きい輪郭の面積と面積が一定以上の輪郭だけ残すという処理を記載しました。
46
+
47
+
48
+
49
+ ```python
50
+
51
+ # -*- coding: utf-8 -*-
52
+
53
+ import cv2
54
+
55
+ import numpy as np
56
+
57
+
58
+
59
+
60
+
61
+ def find_rect_of_target_color(img):
62
+
63
+ # HSV に変換する。
64
+
65
+ hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV_FULL)
66
+
67
+
68
+
69
+ # チャンネルごとに分解する。
70
+
71
+ h, s, v = cv2.split(hsv)
72
+
73
+
74
+
75
+ # マスク画像を作成する。
76
+
77
+ mask = np.zeros_like(h)
78
+
79
+ mask[(h > 240) & ((100 < s) & (s < 200))] = 255
80
+
81
+
82
+
83
+ # 輪郭抽出する。
84
+
85
+ contours, hierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
86
+
87
+
88
+
89
+ # 輪郭の外接矩形を取得する。
90
+
91
+ rects = []
92
+
93
+ for cnt in contours:
94
+
95
+ rects.append(cv2.boundingRect(cnt))
96
+
97
+
98
+
99
+ # 面積が大きい順にソートする。
100
+
101
+ rects = list(sorted(rects, key=lambda x: x[2] * x[3], reverse=True))
102
+
103
+ print(rects)
104
+
105
+
106
+
107
+ # 一番面積が大きい輪郭
108
+
109
+ max_rect = rects[0]
110
+
111
+
112
+
113
+ # 一番面積が大きい輪郭以外で面積が一定値以上あるもの
114
+
115
+ rects = list(filter(lambda x: x[2] * x[3] >= 50, rects[:-1]))
116
+
117
+ rects += [max_rect]
118
+
119
+
120
+
121
+ return rects
122
+
123
+
124
+
125
+
126
+
127
+ # 画像を読み込む。
128
+
129
+ img = cv2.imread("sample.png")
130
+
131
+
132
+
133
+ # 対象の色の領域を探す。
134
+
135
+ rects = find_rect_of_target_color(img)
136
+
137
+
138
+
139
+ # 矩形を描画する。
140
+
141
+ for x, y, w, h in rects:
142
+
143
+ cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), thickness=2)
144
+
145
+
146
+
147
+ cv2.imshow("red", img)
148
+
149
+ cv2.waitKey(0)
150
+
151
+ cv2.destroyAllWindows()
152
+
153
+ ```