質問編集履歴

2

インデントの修正

2021/12/10 03:09

投稿

mituo
mituo

スコア0

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

出力画像の提示

2021/12/10 03:09

投稿

mituo
mituo

スコア0

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
- 範囲指定についてxmin,xmax,ymin,ymax指定を行い、74行のframe_next=video.read()
555
+ ソースコード1で下記ような映像が表示されました。![イメージ説明](84276eec31262131c211704f5c0772fb.png)
290
-
291
- の後にdetframe=frame_next[ymin:ymax,xmin:xmax]の宣言を行い、それ以降の
556
+
292
-
293
- frame_next全てdetframeに置き換えました。しし、実行結果は画面が小さくなった
557
+ ボールの軌道トラッキングしたかったのですがノイズが多いためコート内のものだけを
294
-
558
+
295
- だけでした。
559
+ 差分処理ようと考え、ソースコード2のように修正しました。
296
-
560
+
297
- サイズの設定についてサイトを見てもわかりせんでした。
561
+ ソースコード2で下記ような画像が表示されました。
562
+
298
-
563
+ ![イメージ説明](78037a8d773cd9f14b42dd05d87ddf64.png)
564
+
565
+ 理想としてはコート内の差分処理をきれいに行った後、ボールのサイズ以下の
566
+
567
+ もののみの差分処理を行うことで、きれいにボールのトラッキングをしたいです。
568
+
299
- 解決策の方よろしくお願いします。
569
+ お力添えの方よろしくお願いします。