質問編集履歴

1

プログラムの内容

2021/11/05 02:02

投稿

kodai0505
kodai0505

スコア8

test CHANGED
File without changes
test CHANGED
@@ -1,7 +1,17 @@
1
+ #背景
2
+
3
+ 現在、ベルトコンベヤーで流れてくる椎茸の大きさ判定を行っています。
4
+
5
+ 外接円や外接矩形による椎茸の検出は上手くいくのですが、楕円による検出が上手くいきません。
6
+
7
+
8
+
1
9
  #問題点
2
10
 
3
11
  配列ellipse[0]の値が(nan, inf)の時にcontinueで飛ばしたいのですが、以下のようなコードを書いて実行しても飛ばされませんでした。
4
12
 
13
+ 大まかな内容だとcv2.fitEllipse関数によって椎茸を楕円で検出を行っているのですが、椎茸が検出される前の何も映っていない状況だと以下のようなエラーが返され、検出を続行することが出来ませんでした。そのため何も映っていない状態であればcontinueで飛ばしたいと思いました。
14
+
5
15
  ```python
6
16
 
7
17
  if ellipse[0] == ("nan", "inf"):
@@ -10,4 +20,200 @@
10
20
 
11
21
  ```
12
22
 
23
+ #エラー内容
24
+
25
+ ```python
26
+
27
+ Traceback (most recent call last):
28
+
29
+ File "iro3_ellipse.py", line 72, in <module>
30
+
31
+ frame = cv2.ellipse(frame,ellipse,(255,0,0),2)
32
+
33
+ cv2.error: OpenCV(4.5.3) C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-u4kjpz2z\opencv\modules\imgproc\src\drawing.cpp:1947: error: (-215:Assertion failed) box.size.width >= 0 && box.size.height >= 0 && thickness <= MAX_THICKNESS in function 'cv::ellipse'
34
+
35
+ ```
36
+
37
+
38
+
39
+ #プログラム
40
+
41
+ ```python
42
+
43
+ #楕円
44
+
45
+ import cv2
46
+
47
+ import numpy as np
48
+
49
+ from PIL import Image, ImageFont, ImageDraw
50
+
51
+ import os
52
+
53
+
54
+
55
+ dir = 'movie' # 動画が保存されているディレクトリ
56
+
57
+ path = '3-5.MOV' # ファイル名
58
+
59
+
60
+
61
+ # 画像に文字を入れる関数
62
+
63
+ def telop(img, message,W,H):
64
+
65
+ font_path = 'C:\Windows\Fonts\meiryo.ttc' # Windowsのフォントファイルへのパス
66
+
67
+ font_size = 100 # フォントサイズ
68
+
69
+ font = ImageFont.truetype(font_path, font_size) # PILでフォントを定義
70
+
71
+ img = Image.fromarray(img) # cv2(NumPy)型の画像をPIL型に変換
72
+
73
+ draw = ImageDraw.Draw(img) # 描画用のDraw関数を用意
74
+
75
+
76
+
77
+ w, h = draw.textsize(message, font) # .textsizeで文字列のピクセルサイズを取得
78
+
79
+
80
+
81
+ # テロップの位置positionは画像サイズと文字サイズから決定する
82
+
83
+ # 横幅中央、縦は下
84
+
85
+ position = (int((W - w) / 2), int(H - (font_size * 1.5)))
86
+
87
+
88
+
89
+ # 中央揃え
90
+
91
+ #position = (int((W - w) / 2), int((H - h) / 2))
92
+
93
+
94
+
95
+ # テキストを描画(位置、文章、フォント、文字色(BGR+α)を指定)
96
+
97
+ draw.text(position, message, font=font, fill=(0, 0, 255, 0))
98
+
99
+
100
+
101
+ # PIL型の画像をcv2(NumPy)型に変換
102
+
103
+ img = np.array(img)
104
+
105
+ return img
106
+
107
+
108
+
109
+ in_path = os.path.join(*[dir, path]) # 読み込みパスを作成
110
+
111
+ cap = cv2.VideoCapture(in_path)
112
+
113
+ #cap = cv2.VideoCapture(0)
114
+
115
+ Fs = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) # 動画の全フレーム数を計算
116
+
117
+ fps = cap.get(cv2.CAP_PROP_FPS) # 動画のFPS(フレームレート:フレーム毎秒)を取得
118
+
119
+ W = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) # 動画の横幅を取得
120
+
121
+ H = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 動画の縦幅を取得
122
+
123
+ #fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v') # 動画保存時のfourcc設定(mp4用)
124
+
125
+
126
+
127
+ while True:
128
+
129
+ cv2.namedWindow("img", cv2.WINDOW_NORMAL)
130
+
131
+ cv2.resizeWindow("img", 640, 480)
132
+
133
+ ret, frame = cap.read()
134
+
135
+ if ret == False:
136
+
137
+ break
138
+
139
+ hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
140
+
141
+ lower = np.array([10, 50, 0])
142
+
143
+ upper = np.array([75, 255, 255])
144
+
145
+ binary = cv2.inRange(hsv, lower, upper)
146
+
147
+ #dst = cv2.bitwise_and(frame, frame, mask = frame_mask)
148
+
149
+ # 輪郭抽出
150
+
151
+ contours, hierarchy = cv2.findContours(
152
+
153
+ binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
154
+
155
+ )
156
+
157
+
158
+
159
+ if len(contours) == 0:
160
+
161
+ continue
162
+
163
+
164
+
165
+ # 小さい輪郭は無視する
166
+
167
+ max_contour = max(contours, key=lambda x: cv2.contourArea(x))
168
+
169
+
170
+
171
+ # 外接矩形を描画する
172
+
173
+ #x, y, w, h = cv2.boundingRect(max_contour)
174
+
175
+ #area = round(int(cv2.contourArea(max_contour)),-4)
176
+
177
+ #cv2.rectangle(frame, (x, y), (x + w, y + h), color=(255, 0, 0), thickness=3)
178
+
179
+ ellipse = cv2.fitEllipse(max_contour)
180
+
181
+ print(ellipse[0])
182
+
183
+ if ellipse[0] == ("nan", "inf"):
184
+
185
+ continue
186
+
187
+ frame = cv2.ellipse(frame,ellipse,(255,0,0),2)
188
+
189
+
190
+
191
+ w,h = ellipse[1]
192
+
193
+
194
+
195
+ w,h = int(w),int(h)
196
+
197
+
198
+
199
+ message = '幅:' + str(w) + '高さ:' + str(h)
200
+
201
+ frame = telop(frame, message, W, H)
202
+
203
+
204
+
205
+ cv2.imshow("img", frame)
206
+
207
+ #print(w,h) #コマンドプロンプトでピクセル表示
208
+
209
+ if cv2.waitKey(10) == 27: #ESCキーで切る
210
+
211
+ break
212
+
213
+ cv2.destrayAllWindows()
214
+
215
+ ```
216
+
217
+
218
+
13
219
  素人質問で申し訳ございませんが、ご教授いただけると幸いです。