-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVideo_Tracking_position+main
211 lines (180 loc) · 8.95 KB
/
Video_Tracking_position+main
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# %%
# Import the tools needed for the rest of the program
import cv2 as cv
import numpy as np
import time
import math
import matplotlib as mathplotlib
def getRelPos(positions):
# positions is a list of 12 tuples that are the positions at the given time
relDistance = [[] for i in positions]
# print(relDistance)
count = 0
for pos in positions:
# The position of the main circle
x = pos[0]
y = pos[1]
for compare in positions:
# the position of the coord comparing too
xTemp = compare[0]
yTemp = compare[1]
xDist = x - xTemp
yDist = y - yTemp
dist = math.sqrt(float(xDist) ** 2 + float(yDist) ** 2)
dist = round(dist, 2)
relDistance[count].append(dist)
count = count + 1
# print(relDistance)
return relDistance
def main():
start_time = time.time() # Times how long the program runs for
numFrameToSave = 30 # Number of frames to skip [frames]
camerafps = 30 # Frames per second the camera shoots at [frames / second]
interval = numFrameToSave / camerafps # How many seconds apart are each of the inspected frames [seconds]
conversion = 1080 / 20 # PIXELS / UNITS eg [pixels / cm]
units = 'cm'
# %% Sets up the Color Detection and data storage
boundaries = [ # define the list of boundaries for color detection
# ([Blue,Green,Red],[Blue,Green,Red])
# ([108 , 95 , 141] , [138 , 125 , 171]),
# ([74 , 18 , 69] , [104 , 48 , 99]),
# ([63 , 51 , 41] , [93 , 81 , 71]),
# ([92 , 122 , 127] , [122 , 152 , 157]),
# ([12 , 14 , 139] , [42 , 44 , 169]),
# ([18 , 62 , 0] , [48 , 92 , 25]),
# ([0 , 119 , 139] , [26 , 149 , 169]),
# ([17 , 53 , 147] , [47 , 83 , 177]),
# ([128 , 56 , 0] , [158 , 86 , 26]),
# ([95 , 22 , 0] , [125 , 52 , 24]),
# ([0 , 108 , 70] , [27 , 138 , 100])
([146, 129, 186], [176, 159, 216]),
]
# Names of the Colors
colors = ['Rose', 'Purple', 'Light Grey', 'Light Yellow', 'Red', 'Green',
'Yellow', 'Orange', 'Turqouise', 'Indigo', 'Lime']
centerPoints = [[] for i in range(12)]
# Creates list of list to store location of centerpoint the 12 is How many circles we have
RadList = [] # Creates list to store length of radius
vidcap = cv.VideoCapture('MovingTest1Circle.MOV') # Imports the Video and reads the file
success, image = vidcap.read()
# print("I am in success")
indexcounter = 0 # Index counter is so we can access the previous location to calculate the speed
count = 0 # Count to determine what frames to skip
# %%
while success: # check success here might break your program
success, image = vidcap.read() # success might be false and image might be None
# check success here
if not success:
break
# on every numFrameToSave
if count % numFrameToSave == 1:
cv.imwrite("frame.jpg", image) # Writes the current frame to frame.jpg
image = cv.imread("frame.jpg") # Reads the current frame------May be able to skip this step
circleNum = 0
print('\n')
print('Frame Number:', count)
print('-----------------------')
# allows a frame number to be saved in case there is something fishy going on
if count == 300:
cv.imwrite("TroubleShootFrame.jpg", image)
# %%
# loop over the boundaries
for (lower, upper) in boundaries:
# create NumPy arrays from the boundaries
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")
# find the colors within the specified boundaries and apply
# the mask
mask = cv.inRange(image, lower, upper) # Creates the mask to apply over the color boundary
output = cv.bitwise_and(image, image,
mask=mask) # combines the mask and the original image and saves as output
cv.imwrite('temp.png', output) # Saves the output as a temp.png
filename = "temp.png" # Loads the temp.png as 'filename' to be used for Hough
# %%
# Hough transform
src = cv.imread(filename, cv.IMREAD_COLOR) # Reads the file name and stores it as src in Color
gray = cv.cvtColor(src,
cv.COLOR_BGR2GRAY) # Converts the src to a gray scale picture for the Hough Transform
gray = cv.medianBlur(gray, 5)
circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 3, 10000, param1=300, param2=15,
minRadius=100, maxRadius=200)
# %% If we find a Circle
if circles is not None:
circles = np.uint16(np.around(circles))
# Converts the output of Hough Transform into the data we want
holder = circles[0, :] # Stores circles in a placeholding variable in [pixels]
xcenter = int(holder[:, 0]) / conversion # The x-center in [cm]
ycenter = int(holder[:, 1]) / conversion # The y-center in [cm]
radius = int(holder[:, 2]) / conversion # The radius (Not sure why, but why not) in [cm]
center = [xcenter, ycenter]
centerPoints[circleNum].append(center)
# Calculates the speed of the object over the last time interval
if len(centerPoints[0]) >= 1:
previousLocation = (centerPoints[circleNum])[indexcounter - 1]
xprevious = previousLocation[0]
yprevious = previousLocation[1]
distance = math.sqrt(
(xcenter - xprevious) ** 2 + (ycenter - yprevious) ** 2)
# Distance the circle traveled in [cm]
speed = distance / interval
# %% If we dont find a circle
# Uses the information from the previous location found:
# Could add that it 'guesses the location' based on previous speed
# Next generation could use a kalman filter
else:
previousLocation = (centerPoints[circleNum])[indexcounter - 1]
# If the program does not detect a circle, it uses the last data point and stores that as the center
xcenter = previousLocation[0]
ycenter = previousLocation[1]
raidus = 0
distance = 0
speed = 0
center = [xcenter, ycenter]
centerPoints[circleNum].append(center)
# %% Regardless of circle or not
# Prints the Relevant information so we know it isn't too messed up
print(colors[circleNum], '\t', )
print('%.2f, %.2f %s' % (xcenter, ycenter, units))
print('Previous %.2f %.2f %s' % (xprevious, yprevious, units))
print('Radius: %.2f %s' % (radius, units))
print('Distance %.2f %s' % (distance, units))
print('Circles Found: ', len(holder[:, 0]))
print('Speed: %.2f %s / second' % (speed, units))
RadList.append(radius)
circleNum = circleNum + 1
# Circle number loops over the boundaries to change what number circle is being identified
indexcounter = indexcounter + 1
# Should be outside of the for loop in boundaries
# changes what number picture we are looking at count / numberofframestoskip
# %%
if cv.waitKey(10) == 27:
break
count += 1
# # %% What to do at the end of the program
# print('\n\n\n')
# print('Time Ellapsed: %.2f seconds' % (time.time() - start_time))
#
# # %% Prompt to graph the scatter plots of the circles
# answer = str(input('Do you wish to Plot the graphs y/n: '))
# number_of_colors = len(boundaries)
#
#
# if answer == 'y':
# dataPoints = len(centerPoints[0])
#
# xValues = np.zeros((number_of_colors, dataPoints))
# yValues = np.zeros((number_of_colors, dataPoints))
# index = 0;
#
# for counter1 in range(number_of_colors):
# for counter2 in range(dataPoints):
# xValues[counter1][counter2] = ((centerPoints[counter1])[counter2])[0]
# yValues[counter1][counter2] = ((centerPoints[counter1])[counter2])[1]
#
# title = colors[counter1]
# mathplotlib.pyplot.plot(xValues[0], yValues[0], '-o')
# mathplotlib.pyplot.title(title)
# mathplotlib.pyplot.xlim((0, 30))
# mathplotlib.pyplot.ylim((0, 30))
if __name__ == "__main__":
main()