質問編集履歴

3

コードの編集

2020/08/24 02:54

投稿

gurou
gurou

スコア8

test CHANGED
File without changes
test CHANGED
@@ -12,175 +12,431 @@
12
12
 
13
13
  現在は以下のコードで動画検出を行っています
14
14
 
15
+ ```python# -*- coding: utf-8 -*-
16
+
17
+ """
18
+
19
+ Class definition of YOLO_v3 style detection model on image and video
20
+
21
+ """
22
+
23
+
24
+
15
- ```python
25
+ import colorsys
16
-
26
+
17
- import sys
27
+ import os
18
-
28
+
19
- import argparse
29
+ from timeit import default_timer as timer
30
+
31
+
20
32
 
21
33
  import numpy as np
22
34
 
23
-
24
-
25
- from yolo import YOLO, detect_video
26
-
27
- from PIL import Image
28
-
29
-
30
-
31
- def detect_img(yolo):
35
+ from keras import backend as K
36
+
37
+ from keras.models import load_model
38
+
39
+ from keras.layers import Input
40
+
41
+ from PIL import Image, ImageFont, ImageDraw
42
+
43
+
44
+
45
+ from yolo3.model import yolo_eval, yolo_body, tiny_yolo_body
46
+
47
+ from yolo3.utils import letterbox_image
48
+
49
+ import os
50
+
51
+ from keras.utils import multi_gpu_model
52
+
53
+
54
+
55
+ class YOLO(object):
56
+
57
+ _defaults = {
58
+
59
+ "model_path": 'C:/Users/0000526465/keras-yolo3/logs/000/trained_weights_final.h5',
60
+
61
+ "anchors_path": 'model_data/yolo_anchors.txt',
62
+
63
+ "classes_path": 'model_data/my_classes.txt',
64
+
65
+ "score" : 0.3,
66
+
67
+ "iou" : 0.45,
68
+
69
+ "model_image_size" : (320,320),
70
+
71
+ "gpu_num" : 1,
72
+
73
+ }
74
+
75
+
76
+
77
+ @classmethod
78
+
79
+ def get_defaults(cls, n):
80
+
81
+ if n in cls._defaults:
82
+
83
+ return cls._defaults[n]
84
+
85
+ else:
86
+
87
+ return "Unrecognized attribute name '" + n + "'"
88
+
89
+
90
+
91
+ def __init__(self, **kwargs):
92
+
93
+ self.__dict__.update(self._defaults) # set up default values
94
+
95
+ self.__dict__.update(kwargs) # and update with user overrides
96
+
97
+ self.class_names = self._get_class()
98
+
99
+ self.anchors = self._get_anchors()
100
+
101
+ self.sess = K.get_session()
102
+
103
+ self.boxes, self.scores, self.classes = self.generate()
104
+
105
+
106
+
107
+ def _get_class(self):
108
+
109
+ classes_path = os.path.expanduser(self.classes_path)
110
+
111
+ with open(classes_path) as f:
112
+
113
+ class_names = f.readlines()
114
+
115
+ class_names = [c.strip() for c in class_names]
116
+
117
+ return class_names
118
+
119
+
120
+
121
+ def _get_anchors(self):
122
+
123
+ anchors_path = os.path.expanduser(self.anchors_path)
124
+
125
+ with open(anchors_path) as f:
126
+
127
+ anchors = f.readline()
128
+
129
+ anchors = [float(x) for x in anchors.split(',')]
130
+
131
+ return np.array(anchors).reshape(-1, 2)
132
+
133
+
134
+
135
+ def generate(self):
136
+
137
+ model_path = os.path.expanduser(self.model_path)
138
+
139
+ assert model_path.endswith('.h5'), 'Keras model or weights must be a .h5 file.'
140
+
141
+
142
+
143
+ # Load model, or construct model and load weights.
144
+
145
+ num_anchors = len(self.anchors)
146
+
147
+ num_classes = len(self.class_names)
148
+
149
+ is_tiny_version = num_anchors==6 # default setting
150
+
151
+ try:
152
+
153
+ self.yolo_model = load_model(model_path, compile=False)
154
+
155
+ except:
156
+
157
+ self.yolo_model = tiny_yolo_body(Input(shape=(None,None,3)), num_anchors//2, num_classes) \
158
+
159
+ if is_tiny_version else yolo_body(Input(shape=(None,None,3)), num_anchors//3, num_classes)
160
+
161
+ self.yolo_model.load_weights(self.model_path) # make sure model, anchors and classes match
162
+
163
+ else:
164
+
165
+ assert self.yolo_model.layers[-1].output_shape[-1] == \
166
+
167
+ num_anchors/len(self.yolo_model.output) * (num_classes + 5), \
168
+
169
+ 'Mismatch between model and given anchor and class sizes'
170
+
171
+
172
+
173
+ print('{} model, anchors, and classes loaded.'.format(model_path))
174
+
175
+
176
+
177
+ # Generate colors for drawing bounding boxes.
178
+
179
+ hsv_tuples = [(x / len(self.class_names), 1., 1.)
180
+
181
+ for x in range(len(self.class_names))]
182
+
183
+ self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
184
+
185
+ self.colors = list(
186
+
187
+ map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)),
188
+
189
+ self.colors))
190
+
191
+ np.random.seed(10101) # Fixed seed for consistent colors across runs.
192
+
193
+ np.random.shuffle(self.colors) # Shuffle colors to decorrelate adjacent classes.
194
+
195
+ np.random.seed(None) # Reset seed to default.
196
+
197
+
198
+
199
+ # Generate output tensor targets for filtered bounding boxes.
200
+
201
+ self.input_image_shape = K.placeholder(shape=(2, ))
202
+
203
+ if self.gpu_num>=2:
204
+
205
+ self.yolo_model = multi_gpu_model(self.yolo_model, gpus=self.gpu_num)
206
+
207
+ boxes, scores, classes = yolo_eval(self.yolo_model.output, self.anchors,
208
+
209
+ len(self.class_names), self.input_image_shape,
210
+
211
+ score_threshold=self.score, iou_threshold=self.iou)
212
+
213
+ return boxes, scores, classes
214
+
215
+
216
+
217
+ def detect_image(self, image):
218
+
219
+ start = timer()
220
+
221
+
222
+
223
+ if self.model_image_size != (None, None):
224
+
225
+ assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
226
+
227
+ assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
228
+
229
+ boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
230
+
231
+ else:
232
+
233
+ new_image_size = (image.width - (image.width % 32),
234
+
235
+ image.height - (image.height % 32))
236
+
237
+ boxed_image = letterbox_image(image, new_image_size)
238
+
239
+ image_data = np.array(boxed_image, dtype='float32')
240
+
241
+
242
+
243
+ print(image_data.shape)
244
+
245
+ image_data /= 255.
246
+
247
+ image_data = np.expand_dims(image_data, 0) # Add batch dimension.
248
+
249
+
250
+
251
+ out_boxes, out_scores, out_classes = self.sess.run(
252
+
253
+ [self.boxes, self.scores, self.classes],
254
+
255
+ feed_dict={
256
+
257
+ self.yolo_model.input: image_data,
258
+
259
+ self.input_image_shape: [image.size[1], image.size[0]],
260
+
261
+ K.learning_phase(): 0
262
+
263
+ })
264
+
265
+
266
+
267
+ print('Found {} boxes for {}'.format(len(out_boxes), 'img'))
268
+
269
+
270
+
271
+ font = ImageFont.truetype(font='font/FiraMono-Medium.otf',
272
+
273
+ size=np.floor(3e-2 * image.size[1] + 0.5).astype('int32'))
274
+
275
+ thickness = (image.size[0] + image.size[1]) // 300
276
+
277
+
278
+
279
+ for i, c in reversed(list(enumerate(out_classes))):
280
+
281
+ predicted_class = self.class_names[c]
282
+
283
+ box = out_boxes[i]
284
+
285
+ score = out_scores[i]
286
+
287
+
288
+
289
+ label = '{} {:.2f}'.format(predicted_class, score)
290
+
291
+ draw = ImageDraw.Draw(image)
292
+
293
+ label_size = draw.textsize(label, font)
294
+
295
+
296
+
297
+ top, left, bottom, right = box
298
+
299
+ top = max(0, np.floor(top + 0.5).astype('int32'))
300
+
301
+ left = max(0, np.floor(left + 0.5).astype('int32'))
302
+
303
+ bottom = min(image.size[1], np.floor(bottom + 0.5).astype('int32'))
304
+
305
+ right = min(image.size[0], np.floor(right + 0.5).astype('int32'))
306
+
307
+ print(label, (left, top), (right, bottom))
308
+
309
+
310
+
311
+ if top - label_size[1] >= 0:
312
+
313
+ text_origin = np.array([left, top - label_size[1]])
314
+
315
+ else:
316
+
317
+ text_origin = np.array([left, top + 1])
318
+
319
+
320
+
321
+ # My kingdom for a good redistributable image drawing library.
322
+
323
+ for i in range(thickness):
324
+
325
+ draw.rectangle(
326
+
327
+ [left + i, top + i, right - i, bottom - i],
328
+
329
+ outline=self.colors[c])
330
+
331
+ draw.rectangle(
332
+
333
+ [tuple(text_origin), tuple(text_origin + label_size)],
334
+
335
+ fill=self.colors[c])
336
+
337
+ draw.text(text_origin, label, fill=(0, 0, 0), font=font)
338
+
339
+ del draw
340
+
341
+
342
+
343
+ end = timer()
344
+
345
+ print(end - start)
346
+
347
+ return image
348
+
349
+
350
+
351
+ def close_session(self):
352
+
353
+ self.sess.close()
354
+
355
+
356
+
357
+ def detect_video(yolo, video_path, output_path=""):
358
+
359
+ import cv2
360
+
361
+ vid = cv2.VideoCapture(video_path)
362
+
363
+ if not vid.isOpened():
364
+
365
+ raise IOError("Couldn't open webcam or video")
366
+
367
+ video_FourCC = int(vid.get(cv2.CAP_PROP_FOURCC))
368
+
369
+ video_fps = vid.get(cv2.CAP_PROP_FPS)
370
+
371
+ video_size = (int(vid.get(cv2.CAP_PROP_FRAME_WIDTH)),
372
+
373
+ int(vid.get(cv2.CAP_PROP_FRAME_HEIGHT)))
374
+
375
+ isOutput = True if output_path != "" else False
376
+
377
+ if isOutput:
378
+
379
+ print("!!! TYPE:", type(output_path), type(video_FourCC), type(video_fps), type(video_size))
380
+
381
+ out = cv2.VideoWriter(output_path, video_FourCC, video_fps, video_size)
382
+
383
+ accum_time = 0
384
+
385
+ curr_fps = 0
386
+
387
+ fps = "FPS: ??"
388
+
389
+ prev_time = timer()
32
390
 
33
391
  while True:
34
392
 
35
- img = input('Input image filename:')
393
+ return_value, frame = vid.read()
36
-
37
- try:
394
+
38
-
39
- image = Image.open(img)
395
+ image = Image.fromarray(frame)
40
-
41
- except:
396
+
42
-
43
- print('Open Error! Try again!')
44
-
45
- continue
46
-
47
- else:
48
-
49
- r_image = yolo.detect_image(image)
397
+ image = yolo.detect_image(image)
50
-
51
-
52
-
398
+
53
- print(type(r_image))
399
+ result = np.asarray(image)
400
+
54
-
401
+ curr_time = timer()
402
+
403
+ exec_time = curr_time - prev_time
404
+
405
+ prev_time = curr_time
406
+
407
+ accum_time = accum_time + exec_time
408
+
409
+ curr_fps = curr_fps + 1
410
+
411
+ if accum_time > 1:
412
+
413
+ accum_time = accum_time - 1
414
+
415
+ fps = "FPS: " + str(curr_fps)
416
+
55
- import cv2
417
+ curr_fps = 0
418
+
56
-
419
+ cv2.putText(result, text=fps, org=(3, 15), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
420
+
421
+ fontScale=0.50, color=(255, 0, 0), thickness=2)
422
+
57
- cv2.imwrite("out.jpg", np.asarray(r_image)[..., ::-1])
423
+ cv2.namedWindow("result", cv2.WINDOW_NORMAL)
424
+
58
-
425
+ cv2.imshow("result", result)
426
+
427
+ if isOutput:
428
+
59
- r_image.show()
429
+ out.write(result)
430
+
60
-
431
+ if cv2.waitKey(1) & 0xFF == ord('q'):
432
+
61
-
433
+ break
62
434
 
63
435
  yolo.close_session()
64
436
 
65
437
 
66
438
 
67
- FLAGS = None
439
+
68
-
69
-
70
-
71
- if __name__ == '__main__':
72
-
73
- # class YOLO defines the default value, so suppress any default here
74
-
75
- parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
76
-
77
- '''
78
-
79
- Command line options
80
-
81
- '''
82
-
83
- parser.add_argument(
84
-
85
- '--model', type=str,
86
-
87
- help='path to model weight file, default ' + YOLO.get_defaults("model_path")
88
-
89
- )
90
-
91
-
92
-
93
- parser.add_argument(
94
-
95
- '--anchors', type=str,
96
-
97
- help='path to anchor definitions, default ' + YOLO.get_defaults("anchors_path")
98
-
99
- )
100
-
101
-
102
-
103
- parser.add_argument(
104
-
105
- '--classes', type=str,
106
-
107
- help='path to class definitions, default ' + YOLO.get_defaults("classes_path")
108
-
109
- )
110
-
111
-
112
-
113
- parser.add_argument(
114
-
115
- '--gpu_num', type=int,
116
-
117
- help='Number of GPU to use, default ' + str(YOLO.get_defaults("gpu_num"))
118
-
119
- )
120
-
121
-
122
-
123
- parser.add_argument(
124
-
125
- '--image', default=False, action="store_true",
126
-
127
- help='Image detection mode, will ignore all positional arguments'
128
-
129
- )
130
-
131
- '''
132
-
133
- Command line positional arguments -- for video detection mode
134
-
135
- '''
136
-
137
- parser.add_argument(
138
-
139
- "--input", nargs='?', type=str,required=False,default='./path2your_video',
140
-
141
- help = "Video input path"
142
-
143
- )
144
-
145
-
146
-
147
- parser.add_argument(
148
-
149
- "--output", nargs='?', type=str, default="",
150
-
151
- help = "[Optional] Video output path"
152
-
153
- )
154
-
155
-
156
-
157
- FLAGS = parser.parse_args()
158
-
159
-
160
-
161
- if FLAGS.image:
162
-
163
- """
164
-
165
- Image detection mode, disregard any remaining command line arguments
166
-
167
- """
168
-
169
- print("Image detection mode")
170
-
171
- if "input" in FLAGS:
172
-
173
- print(" Ignoring remaining command line arguments: " + FLAGS.input + "," + FLAGS.output)
174
-
175
- detect_img(YOLO(**vars(FLAGS)))
176
-
177
- elif "input" in FLAGS:
178
-
179
- detect_video(YOLO(**vars(FLAGS)), FLAGS.input, FLAGS.output)
180
-
181
- else:
182
-
183
- print("Must specify at least video_input_path. See usage with --help.")
184
440
 
185
441
 
186
442
 

2

コードの修正

2020/08/24 02:54

投稿

gurou
gurou

スコア8

test CHANGED
File without changes
test CHANGED
@@ -11,8 +11,6 @@
11
11
 
12
12
 
13
13
  現在は以下のコードで動画検出を行っています
14
-
15
-
16
14
 
17
15
  ```python
18
16
 
@@ -183,3 +181,7 @@
183
181
  else:
184
182
 
185
183
  print("Must specify at least video_input_path. See usage with --help.")
184
+
185
+
186
+
187
+ ```

1

コードの追加

2020/08/20 06:12

投稿

gurou
gurou

スコア8

test CHANGED
File without changes
test CHANGED
@@ -7,3 +7,179 @@
7
7
  なんとなくフレームレートの事をさしているということはわかりましたが
8
8
 
9
9
  11とは良いのでしょうか。悪いのでしょうか。
10
+
11
+
12
+
13
+ 現在は以下のコードで動画検出を行っています
14
+
15
+
16
+
17
+ ```python
18
+
19
+ import sys
20
+
21
+ import argparse
22
+
23
+ import numpy as np
24
+
25
+
26
+
27
+ from yolo import YOLO, detect_video
28
+
29
+ from PIL import Image
30
+
31
+
32
+
33
+ def detect_img(yolo):
34
+
35
+ while True:
36
+
37
+ img = input('Input image filename:')
38
+
39
+ try:
40
+
41
+ image = Image.open(img)
42
+
43
+ except:
44
+
45
+ print('Open Error! Try again!')
46
+
47
+ continue
48
+
49
+ else:
50
+
51
+ r_image = yolo.detect_image(image)
52
+
53
+
54
+
55
+ print(type(r_image))
56
+
57
+ import cv2
58
+
59
+ cv2.imwrite("out.jpg", np.asarray(r_image)[..., ::-1])
60
+
61
+ r_image.show()
62
+
63
+
64
+
65
+ yolo.close_session()
66
+
67
+
68
+
69
+ FLAGS = None
70
+
71
+
72
+
73
+ if __name__ == '__main__':
74
+
75
+ # class YOLO defines the default value, so suppress any default here
76
+
77
+ parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
78
+
79
+ '''
80
+
81
+ Command line options
82
+
83
+ '''
84
+
85
+ parser.add_argument(
86
+
87
+ '--model', type=str,
88
+
89
+ help='path to model weight file, default ' + YOLO.get_defaults("model_path")
90
+
91
+ )
92
+
93
+
94
+
95
+ parser.add_argument(
96
+
97
+ '--anchors', type=str,
98
+
99
+ help='path to anchor definitions, default ' + YOLO.get_defaults("anchors_path")
100
+
101
+ )
102
+
103
+
104
+
105
+ parser.add_argument(
106
+
107
+ '--classes', type=str,
108
+
109
+ help='path to class definitions, default ' + YOLO.get_defaults("classes_path")
110
+
111
+ )
112
+
113
+
114
+
115
+ parser.add_argument(
116
+
117
+ '--gpu_num', type=int,
118
+
119
+ help='Number of GPU to use, default ' + str(YOLO.get_defaults("gpu_num"))
120
+
121
+ )
122
+
123
+
124
+
125
+ parser.add_argument(
126
+
127
+ '--image', default=False, action="store_true",
128
+
129
+ help='Image detection mode, will ignore all positional arguments'
130
+
131
+ )
132
+
133
+ '''
134
+
135
+ Command line positional arguments -- for video detection mode
136
+
137
+ '''
138
+
139
+ parser.add_argument(
140
+
141
+ "--input", nargs='?', type=str,required=False,default='./path2your_video',
142
+
143
+ help = "Video input path"
144
+
145
+ )
146
+
147
+
148
+
149
+ parser.add_argument(
150
+
151
+ "--output", nargs='?', type=str, default="",
152
+
153
+ help = "[Optional] Video output path"
154
+
155
+ )
156
+
157
+
158
+
159
+ FLAGS = parser.parse_args()
160
+
161
+
162
+
163
+ if FLAGS.image:
164
+
165
+ """
166
+
167
+ Image detection mode, disregard any remaining command line arguments
168
+
169
+ """
170
+
171
+ print("Image detection mode")
172
+
173
+ if "input" in FLAGS:
174
+
175
+ print(" Ignoring remaining command line arguments: " + FLAGS.input + "," + FLAGS.output)
176
+
177
+ detect_img(YOLO(**vars(FLAGS)))
178
+
179
+ elif "input" in FLAGS:
180
+
181
+ detect_video(YOLO(**vars(FLAGS)), FLAGS.input, FLAGS.output)
182
+
183
+ else:
184
+
185
+ print("Must specify at least video_input_path. See usage with --help.")