質問編集履歴
2
インデントの修正
test
CHANGED
File without changes
|
test
CHANGED
@@ -288,6 +288,10 @@
|
|
288
288
|
|
289
289
|
|
290
290
|
|
291
|
+
```Python
|
292
|
+
|
293
|
+
|
294
|
+
|
291
295
|
import time
|
292
296
|
|
293
297
|
import math
|
@@ -544,7 +548,7 @@
|
|
544
548
|
|
545
549
|
|
546
550
|
|
547
|
-
|
551
|
+
```
|
548
552
|
|
549
553
|
|
550
554
|
|
1
出力画像の提示
test
CHANGED
File without changes
|
test
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
|
20
20
|
|
21
|
-
### 該当のソースコード
|
21
|
+
### 該当のソースコード1
|
22
22
|
|
23
23
|
|
24
24
|
|
@@ -282,18 +282,288 @@
|
|
282
282
|
|
283
283
|
|
284
284
|
|
285
|
+
|
286
|
+
|
287
|
+
### 該当のソースコード2
|
288
|
+
|
289
|
+
|
290
|
+
|
291
|
+
import time
|
292
|
+
|
293
|
+
import math
|
294
|
+
|
295
|
+
import cv2
|
296
|
+
|
297
|
+
import sympy
|
298
|
+
|
299
|
+
import numpy as np
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
def isCourt(p):#ボール座標がコートの中にあるかを判定
|
304
|
+
|
305
|
+
from sympy.geometry import Point, Polygon
|
306
|
+
|
307
|
+
poly = Polygon((520,178), (895,178), (1065,600), (360,600))
|
308
|
+
|
309
|
+
point=p
|
310
|
+
|
311
|
+
return poly.encloses_point(point)
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
def dilation(dilationSize,kernelSize,img):#膨張処理
|
316
|
+
|
317
|
+
kernel=np.ones((kernelSize,kernelSize),np.uint8)
|
318
|
+
|
319
|
+
element=cv2.getStructuringElement(cv2.MORPH_RECT,(2*dilationSize+1,2*dilationSize+1),(dilationSize,dilationSize))
|
320
|
+
|
321
|
+
dilation_img = cv2.dilate(img,kernel,element)
|
322
|
+
|
323
|
+
|
324
|
+
|
325
|
+
return dilation_img
|
326
|
+
|
327
|
+
|
328
|
+
|
329
|
+
def detect(gray_diff):#
|
330
|
+
|
331
|
+
retval, black_diff = cv2.threshold(gray_diff, 30, 255, cv2.THRESH_BINARY)
|
332
|
+
|
333
|
+
img=black_diff
|
334
|
+
|
335
|
+
|
336
|
+
|
337
|
+
dilation_img=dilation(18,20,img)
|
338
|
+
|
339
|
+
|
340
|
+
|
341
|
+
img2=dilation_img.copy()
|
342
|
+
|
343
|
+
img2=cv2.cvtColor(img2,cv2.COLOR_GRAY2RGB)
|
344
|
+
|
345
|
+
|
346
|
+
|
347
|
+
contours, hierarchy = cv2.findContours(dilation_img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE,offset=(xmin,ymin))
|
348
|
+
|
349
|
+
|
350
|
+
|
351
|
+
|
352
|
+
|
353
|
+
|
354
|
+
|
355
|
+
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
|
360
|
+
|
361
|
+
temp=[]
|
362
|
+
|
363
|
+
p_array=[]
|
364
|
+
|
365
|
+
area_array=[]
|
366
|
+
|
367
|
+
ball_p=[]
|
368
|
+
|
369
|
+
for i in range(len(contours)):
|
370
|
+
|
371
|
+
|
372
|
+
|
373
|
+
count=len(contours[i])
|
374
|
+
|
375
|
+
temp.append(count)
|
376
|
+
|
377
|
+
area = cv2.contourArea(contours[i])#面積計算
|
378
|
+
|
379
|
+
area_array.append(area)
|
380
|
+
|
381
|
+
x=0.0
|
382
|
+
|
383
|
+
y=0.0
|
384
|
+
|
385
|
+
for j in range(count):
|
386
|
+
|
387
|
+
x+=contours[i][j][0][0]
|
388
|
+
|
389
|
+
y+=contours[i][j][0][1]
|
390
|
+
|
391
|
+
|
392
|
+
|
393
|
+
x/=count
|
394
|
+
|
395
|
+
y/=count
|
396
|
+
|
397
|
+
x=int(x)
|
398
|
+
|
399
|
+
y=int(y)
|
400
|
+
|
401
|
+
p_array.append([x,y])
|
402
|
+
|
403
|
+
|
404
|
+
|
405
|
+
if(area<1000):#面積が一定以下
|
406
|
+
|
407
|
+
if(isCourt([x,y])):#コート内かどうか
|
408
|
+
|
409
|
+
cv2.drawContours(img2,contours,i,(0,255,255),2)#黄
|
410
|
+
|
411
|
+
ball_p=[x,y]
|
412
|
+
|
413
|
+
return img2,p_array,area_array,ball_p
|
414
|
+
|
415
|
+
|
416
|
+
|
417
|
+
xmin,xmax=360,1065
|
418
|
+
|
419
|
+
ymin,ymax=178,600
|
420
|
+
|
421
|
+
|
422
|
+
|
423
|
+
VIDEO_DATA = "Nishikori (錦織) VS Tsonga (ツォンガ).mp4"
|
424
|
+
|
425
|
+
ESC_KEY = 0x1b
|
426
|
+
|
427
|
+
DURATION = 1.0
|
428
|
+
|
429
|
+
cv2.namedWindow("motion")
|
430
|
+
|
431
|
+
video = cv2.VideoCapture(VIDEO_DATA)
|
432
|
+
|
433
|
+
|
434
|
+
|
435
|
+
fps = video.get(cv2.CAP_PROP_FPS)
|
436
|
+
|
437
|
+
height = video.get(cv2.CAP_PROP_FRAME_HEIGHT)
|
438
|
+
|
439
|
+
width = video.get(cv2.CAP_PROP_FRAME_WIDTH)
|
440
|
+
|
441
|
+
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
|
442
|
+
|
443
|
+
|
444
|
+
|
445
|
+
out = cv2.VideoWriter('output.avi',fourcc,20.0, (int(width), int(height)))
|
446
|
+
|
447
|
+
|
448
|
+
|
449
|
+
|
450
|
+
|
451
|
+
end_flag, frame_next = video.read()#read() 1つ1つのフレームを読み込む
|
452
|
+
|
453
|
+
detframe=frame_next[ymin:ymax,xmin:xmax]
|
454
|
+
|
455
|
+
height, width, channels = detframe.shape
|
456
|
+
|
457
|
+
motion_history = np.zeros((height, width), np.float32)
|
458
|
+
|
459
|
+
frame_pre = detframe.copy()
|
460
|
+
|
461
|
+
|
462
|
+
|
463
|
+
p=[]
|
464
|
+
|
465
|
+
a=[]
|
466
|
+
|
467
|
+
ball=[]
|
468
|
+
|
469
|
+
|
470
|
+
|
471
|
+
|
472
|
+
|
473
|
+
while(end_flag):
|
474
|
+
|
475
|
+
color_diff = cv2.absdiff(detframe, frame_pre)# フレーム間の差分計算
|
476
|
+
|
477
|
+
gray_diff = cv2.cvtColor(color_diff, cv2.COLOR_BGR2GRAY)# グレースケール変換
|
478
|
+
|
479
|
+
retval, black_diff = cv2.threshold(gray_diff, 100, 1, cv2.THRESH_BINARY)#
|
480
|
+
|
481
|
+
|
482
|
+
|
483
|
+
proc_time = time.time()# プロセッサ処理時間(sec)を取得
|
484
|
+
|
485
|
+
cv2.motempl.updateMotionHistory(black_diff, motion_history, proc_time, DURATION)# モーション履歴画像の更新
|
486
|
+
|
487
|
+
hist_color = np.array(np.clip((motion_history - (proc_time - DURATION)) / DURATION, 0, 1) * 255, np.uint8)# 古いモーションの表示を経過時間に応じて薄くする
|
488
|
+
|
489
|
+
hist_gray = cv2.cvtColor(hist_color, cv2.COLOR_GRAY2BGR)# グレースケール変換
|
490
|
+
|
491
|
+
img,p_temp,a_temp,ball_temp=detect(gray_diff)
|
492
|
+
|
493
|
+
|
494
|
+
|
495
|
+
|
496
|
+
|
497
|
+
p.append(p_temp)
|
498
|
+
|
499
|
+
a.append(a_temp)
|
500
|
+
|
501
|
+
if(len(ball_temp)>0):
|
502
|
+
|
503
|
+
ball.append(ball_temp)
|
504
|
+
|
505
|
+
|
506
|
+
|
507
|
+
ball_array=np.array(ball)
|
508
|
+
|
509
|
+
court_array=np.array([[520,178], [895,178], [1065,600], [360,600]])
|
510
|
+
|
511
|
+
img = cv2.polylines(img,[ball_array],False,(0,255,255))
|
512
|
+
|
513
|
+
img=cv2.polylines(img,[court_array],True,(0,255,0))
|
514
|
+
|
515
|
+
|
516
|
+
|
517
|
+
cv2.imshow("motion", img)# モーション画像を表示
|
518
|
+
|
519
|
+
out.write(img)
|
520
|
+
|
521
|
+
|
522
|
+
|
523
|
+
if cv2.waitKey(20) == ESC_KEY:# Escキー押下で終了
|
524
|
+
|
525
|
+
break
|
526
|
+
|
527
|
+
|
528
|
+
|
529
|
+
|
530
|
+
|
531
|
+
frame_pre = detframe.copy()
|
532
|
+
|
533
|
+
end_flag, frame_next = video.read()
|
534
|
+
|
535
|
+
|
536
|
+
|
537
|
+
|
538
|
+
|
539
|
+
cv2.destroyAllWindows()
|
540
|
+
|
541
|
+
out.release()
|
542
|
+
|
543
|
+
video.release()
|
544
|
+
|
545
|
+
|
546
|
+
|
547
|
+
|
548
|
+
|
549
|
+
|
550
|
+
|
285
551
|
### 試したこと
|
286
552
|
|
287
553
|
|
288
554
|
|
289
|
-
|
555
|
+
ソースコード1では下記のような映像が表示されました。![イメージ説明](84276eec31262131c211704f5c0772fb.png)
|
290
|
-
|
291
|
-
|
556
|
+
|
292
|
-
|
293
|
-
|
557
|
+
ボールの軌道をトラッキングしたかったのですがノイズが多いためコート内のものだけを
|
294
|
-
|
558
|
+
|
295
|
-
|
559
|
+
差分処理しようと考え、ソースコード2のように修正しました。
|
296
|
-
|
560
|
+
|
297
|
-
|
561
|
+
ソースコード2では下記のような画像が表示されました。
|
562
|
+
|
298
|
-
|
563
|
+
![イメージ説明](78037a8d773cd9f14b42dd05d87ddf64.png)
|
564
|
+
|
565
|
+
理想としてはコート内の差分処理をきれいに行った後、ボールのサイズ以下の
|
566
|
+
|
567
|
+
もののみの差分処理を行うことで、きれいにボールのトラッキングをしたいです。
|
568
|
+
|
299
|
-
|
569
|
+
お力添えの方よろしくお願い致します。
|