forked from Jus973/baseball-hit-trax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
103 lines (91 loc) · 4.18 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import cv2
import numpy as np
#random variables being assigned, there's a lambda in there too for pixel distance calculations for velo aware fill (kinda buggy)
prevCircle = None
circ1 = None
dist = lambda x1, y1, x2, y2: (x1-x2)**2 + (y1-y2)**2
deltax = 0
deltay = 0
deltas = 0
deltalist = {}
#source file
cap = cv2.VideoCapture("backview.MOV")
#object detector creation
object_detector = cv2.createBackgroundSubtractorMOG2(history=1000, varThreshold=10)
framenum = 0
#Frame Iteration
while True:
framenum+=1
ret, frame = cap.read()
height, width, _ = frame.shape
#Object Detection masking
objectmask = object_detector.apply(frame)
_, objectmask = cv2.threshold(objectmask, 254, 255, cv2.THRESH_BINARY)
nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(objectmask, None, None, None, 8, cv2.CV_32S)
areas = stats[1:, cv2.CC_STAT_AREA]
#spot removal (removes little artifacts from the camera for more cohesive shapes)
result = np.zeros((labels.shape), np.uint8)
for i in range(0, nlabels - 1):
if areas[i] >= 100:
result[labels == i + 1] = 255
objectmask = result
#color masking to remove all non-whites
lower_white = np.array([0,0,80])
upper_white = np.array([255,75,255])
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
colormask = cv2.inRange(hsv, lower_white, upper_white)
res = cv2.bitwise_and(frame, frame, mask = objectmask)
res = cv2.bitwise_and(res, res, mask = colormask)
cv2.imshow("objMask", objectmask)
cv2.imshow('colormask', colormask)
frame = res
key = cv2.waitKey(30)
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('grey', grayFrame)
#guassian blur to smooth out the image
blurFrame = cv2.GaussianBlur(grayFrame, (17,17),0)
cv2.imshow('bin', frame)
#Hough circle detection, math is too mathy, hard to explain/understand
circles = cv2.HoughCircles(blurFrame, cv2.HOUGH_GRADIENT, 1, 500, param1=50, param2=30, minRadius=1, maxRadius=25)
chosen = None
#weeds out all the circles to find the most accurate one
if circles is not None:
circles = np.uint16(np.around(circles))
chosen = None
for i in circles[0, :]:
if prevCircle is None: chosen = i
if prevCircle is not None:
if dist(chosen[0], chosen[1], i[0], i[1])<+ dist(chosen[0], chosen[1], prevCircle[0], prevCircle[1]):
chosen = i
print(chosen[0], chosen[1])
cv2.circle(frame, (chosen[0], chosen[1]), 1, (0, 100, 100), 3)
cv2.circle(frame, (chosen[0], chosen[1]), chosen[2], (255, 0, 255), 3)
#if no circles are found, velo aware fill fills the frame with probably circle locations
#only for visualization purposes, if the computer isn't completely sure, it won't export the circles
if (circ1 is not None) and (chosen is not None):
if (circ1[0] != chosen[0]) or (circ1[1] != chosen[1]) or (circ1[2] != chosen[2]):
deltax = int(chosen[0]) - int(circ1[0])
deltay = int(chosen[1]) - int(circ1[1])
deltas = int(chosen[2]) - int(circ1[2])
#false positive weeding
if deltas<50 and deltas>-50 and deltax > -50 and deltax < 50 and deltay < 50 and deltay > -50:
deltalist[framenum] = [[int(chosen[0]), int(chosen[1]), int(chosen[2])], [deltax, deltay, deltas]]
print(framenum)
print(deltalist[framenum])
with open("sig_frames.txt", 'a') as sigframes:
output_text = str(framenum) + ', ' + str(deltalist[framenum])
sigframes.write(output_text)
sigframes.write('\n')
bbox = (int(chosen[0])-int(chosen[2]), int(chosen[1])-int(chosen[2]), int(chosen[0])+int(chosen[2]), int(chosen[1])+int(chosen[2]))
elif circ1 is not None:
cv2.circle(frame, (circ1[0], circ1[1]), 1, (0, 100, 100), 3)
cv2.circle(frame, (circ1[0], circ1[1]), circ1[2], (255, 0, 255), 3)
circ1[0] += deltax
circ1[1] += deltay
circ1[2] += deltas
if chosen is not None:
circ1 = chosen
cv2.imshow("circles", frame)
cap.release()
cv2.destroyAllWindows()
print(deltalist)