-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtarget_dist_vidxyz.py
188 lines (146 loc) · 5.38 KB
/
target_dist_vidxyz.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
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
# code to analyze x y z distance to red target from downloaded video
# uses image processing to create bounding box on red feature
import numpy as np
import cv2
import os
import time
import csv
import os.path
from os import path
import matplotlib
import tkinter
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import pandas as pd
# use ggplot style for more sophisticated visuals
plt.style.use('ggplot')
def live_plotter(x_vec,y1_data, z_data, line1, identifier='',pause_time=0.1):
if line1==[]:
# this is the call to matplotlib that allows dynamic plotting
plt.ion()
fig = plt.figure(figsize=(13,6))
ax = fig.add_subplot(111,projection='3d')
# create a variable for the line so we can later update it
line1, = ax.plot(x_vec,y1_data,z_data,'.',alpha=0.8)
#update plot label/title
plt.ylabel('dy')
plt.xlabel('dx')
ax.set_zlabel('dz')
ax.set_zlim(-1,1)
plt.title('Title: {}'.format(identifier))
plt.show()
# after the figure, axis, and line are created, we only need to update the y-data
line1.set_data(x_vec,y1_data)
line1.set_3d_properties(z_data,'z')
# adjust limits if new data goes beyond bounds
# if np.min(y1_data)<=line1.axes.get_ylim()[0] or np.max(y1_data)>=line1.axes.get_ylim()[1]:
# plt.ylim([np.min(y1_data)-np.std(y1_data),np.max(y1_data)+np.std(y1_data)])
plt.ylim([-1,1])
plt.xlim([-1,1])
# this pauses the data so the figure/axis can catch up - the amount of pause can be altered above
plt.pause(pause_time)
# return line so we can update it again in the next iteration
return line1
def nothing(x):
pass
def depth_calc(w, dpx, W, p):
# w = width of target in pixels, W = width of camera frame in pixels, p is pixel to meter conversion factor
cam_angle = 110*np.pi/180
# alpha = 2*np.arctan(w/W*np.tan(cam_angle/2))
# L = w*p/(2*np.tan(alpha/2))
w = p*w #width of target in meters
beta = np.arctan(2*(w/2+dpx)/W*np.tan(cam_angle/2))
L = (w/2+dpx)*p/np.tan(beta)
return L
os.chdir('drone_tracking/videos')
# deleting data from before
filename = "distance.csv"
if path.exists(filename):
f = open(filename,"w+")
f.close()
# creating file
fieldnames = ["dx","dy","dz"]
with open('distance.csv','w') as newFile:
writer = csv.DictWriter(newFile, fieldnames=fieldnames)
writer.writeheader()
cap = cv2.VideoCapture('red_highup.mp4')
if (cap.isOpened()==False):
print("Error opening video stream or file")
cv2.namedWindow("Trackbars")
cv2.createTrackbar("L-H", "Trackbars", 125, 180, nothing)
cv2.createTrackbar("L-S", "Trackbars", 85, 255, nothing)
cv2.createTrackbar("L-V", "Trackbars", 94, 255, nothing)
cv2.createTrackbar("U-H", "Trackbars", 180, 180, nothing)
cv2.createTrackbar("U-S", "Trackbars", 255, 255, nothing)
cv2.createTrackbar("U-V", "Trackbars", 255, 255, nothing)
cnt_found = False
line1 = []
while(cap.isOpened()):
ret, frame = cap.read()
width = cap.get(3)
height = cap.get(4)
# used to slow down to set trackbars
# time.sleep(0.1)
#using hsv color space to detect colors
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
l_h = cv2.getTrackbarPos("L-H","Trackbars")
l_s = cv2.getTrackbarPos("L-S","Trackbars")
l_v = cv2.getTrackbarPos("L-V","Trackbars")
u_h = cv2.getTrackbarPos("U-H","Trackbars")
u_s = cv2.getTrackbarPos("U-S","Trackbars")
u_v = cv2.getTrackbarPos("U-V","Trackbars")
lower_red = np.array([l_h, l_s, l_v])
upper_red = np.array([u_h, u_s, u_v])
# lower_red = np.array([125,85,95])
# upper_red = np.array([180,255,255])
mask = cv2.inRange(hsv, lower_red,upper_red)
# removing mask noise
kernel= np.ones((5,5), np.uint8)
mask = cv2.erode(mask, kernel)
#contours detection
if int(cv2.__version__[0]) > 3:
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
else:
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
wmax = 0
for cnt in contours:
x,y,w,h = cv2.boundingRect(cnt)
frame = cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
# cv2.drawContours(frame, [cnt], 0, (0, 0, 0), 5)
# wamt to only analyze largest contour
if w>wmax:
wmax = w
# want to save center coordinate of bounding box
x_c = x+w/2
y_c = y+h/2
# calibration of real distances
calx = 0.295/w
caly = 0.23/h
# center of camera pos
x_cam_c = width/2
y_cam_c = height/2
dx = (x_c - x_cam_c)*calx
dy = -(y_c - y_cam_c)*caly
dz = depth_calc(w,dx/calx,width,calx)
cnt_found = True
if cnt_found :
with open('distance.csv', 'a') as newFile:
writer = csv.DictWriter(newFile,fieldnames = fieldnames)
info = {
"dx": dx,
"dy": dy,
"dz": dz
}
writer.writerow(info)
data = pd.read_csv('distance.csv')
xc = data['dx']
yc = data['dy']
zc = data['dz']
# line1 = live_plotter(xc,yc,zc,line1)
cv2.imshow("Frame", frame)
cv2.imshow("Mask", mask)
# if esc key is pressed leave loop
if cv2.waitKey(1) == 27:
break
cap.release()
cv2.destroyAllWindows()