|
2 | 2 |
|
3 | 3 | # import system modules
|
4 | 4 | import cv2.cv as cv
|
5 |
| -#import cv |
| 5 | +import urllib |
| 6 | +import msvcrt |
| 7 | +import numpy as np |
| 8 | +from numpy import linalg as LA |
| 9 | + |
6 | 10 | global imghsv
|
| 11 | +global x_3d, y_3d, z_3d |
7 | 12 |
|
8 | 13 | # purpose: using HSV thresholds, detects blue, yellow and purple objects in a video stream in three new windows
|
9 | 14 | # 1) a black/white stream showing objects matching threshold values (window "threshold")
|
|
21 | 26 |
|
22 | 27 | # to modify color thresholds, change the cv.Scalar values in the InRange method in the gettresholdedimg function below
|
23 | 28 |
|
| 29 | + |
| 30 | +#The following function takes coordinates from the images and convertes them to 3D spatial positions |
| 31 | +#The calibration constants are in R1, T1, R2, and T2 for cameras 1 (west) and 2 (east) |
| 32 | +#These constants are produced by matlab code that is available here: |
| 33 | +#http://www.vision.caltech.edu/bouguetj/calib_doc/ |
| 34 | +def triang_3D(col_1, row_1, col_2, row_2) : |
| 35 | + global x_3d, y_3d, z_3d |
| 36 | + #R matrix for camera 1 (west side) |
| 37 | + R1 = np.array([[-74.2709, 637.41, -255.7461], [865.2027, 273.6518, -92.0415], [0.1602, 0.3172, -0.9347]]) |
| 38 | + #T matrix for camera 1 |
| 39 | + T1 = np.array([[1.3248e5], [4.1268e4], [505.0954]]) |
| 40 | + P1 = np.hstack((R1, T1)) |
| 41 | + |
| 42 | + #R matrix for camera 2 (east side) |
| 43 | + R2 = np.array([[-20.0487, 179.5963, -666.7510], [751.5431, -397.57, -330.23], [-0.2329, -0.5675, -0.7898]]) |
| 44 | + #T matrix for camera 2 |
| 45 | + T2 = np.array([[3.7547e5], [3.3423e5], [907.6034]]) |
| 46 | + P2 = np.hstack((R2, T2)) |
| 47 | + |
| 48 | + #blimp position from camera 1 |
| 49 | + #col_1 = 411 |
| 50 | + #row_1 = 382 |
| 51 | + #m1 = np.array([ |
| 52 | + #blimp position from camera 2 |
| 53 | + #col_2 = 531 |
| 54 | + #row_2 = 178 |
| 55 | + |
| 56 | + |
| 57 | + #translated from matlab: |
| 58 | + |
| 59 | + #Camera 1 |
| 60 | + invR1 = LA.inv(R1) |
| 61 | + m1T1 = -1*T1 |
| 62 | + C1 = np.dot(invR1, m1T1) |
| 63 | + x0 = C1[0] |
| 64 | + y0 = C1[1] |
| 65 | + z0 = C1[2] |
| 66 | + m1 = np.array([[col_1], [row_1], [1]]); |
| 67 | + M1 = np.dot(LA.pinv(P1), m1) |
| 68 | + x = M1[0]/M1[3] |
| 69 | + y = M1[1]/M1[3] |
| 70 | + z = M1[2]/M1[3] |
| 71 | + a = x-x0 |
| 72 | + b = y-y0 |
| 73 | + c = z-z0 |
| 74 | + |
| 75 | + #Camera 2 |
| 76 | + invR2 = LA.inv(R2) |
| 77 | + m1T2 = -1*T2 |
| 78 | + C2 = np.dot(invR2, m1T2) |
| 79 | + x1 = C2[0] |
| 80 | + y1 = C2[1] |
| 81 | + z1 = C2[2] |
| 82 | + m2 = np.array([[col_2], [row_2], [1]]); |
| 83 | + M2 = np.dot(LA.pinv(P2), m2) |
| 84 | + x = M2[0]/M2[3] |
| 85 | + y = M2[1]/M2[3] |
| 86 | + z = M2[2]/M2[3] |
| 87 | + d = x-x1 |
| 88 | + e = y-y1 |
| 89 | + f = z-z1 |
| 90 | + |
| 91 | + A11 = (a*a + b*b + c*c) |
| 92 | + A12 = -1*(a*d + e*b + f*c) |
| 93 | + A21 = -1*(a*d + e*b + f*c) |
| 94 | + A22 = d*d + e*e + f*f |
| 95 | + A = np.array([[A11, A12], [A21, A22]]) |
| 96 | + A = np.squeeze(A) #get rid of 3rd dimension |
| 97 | + v = np.array([[(x1-x0)*a + (y1-y0)*b + (z1-z0)*c], [(x0-x1)*d + (y0-y1)*e + (z0-z1)*f]]) |
| 98 | + v = np.squeeze(v) #get rid of 3rd dimension |
| 99 | + invA = LA.inv(A) |
| 100 | + r = np.dot(invA,v) |
| 101 | + x_coord = x0+a*r[0] |
| 102 | + y_coord = y0+b*r[0] |
| 103 | + z_coord = z0+c*r[0] |
| 104 | + |
| 105 | + x_3d = x_coord |
| 106 | + y_3d = y_coord |
| 107 | + z_3d = z_coord |
| 108 | + |
| 109 | + |
24 | 110 | def getthresholdedimg(im):
|
25 | 111 |
|
26 | 112 | # this function take RGB image.Then convert it into HSV for easy colour detection
|
@@ -48,107 +134,170 @@ def getthresholdedimg(im):
|
48 | 134 |
|
49 | 135 | return imgthreshold
|
50 | 136 |
|
51 |
| -# capture from m4v |
52 |
| -#capture = cv.CaptureFromFile('/Users/glenaronson/Desktop/blimp_large.m4v') |
53 |
| -capture = cv.CaptureFromFile('C:/Users/Jeremy/Documents/GitHub/blimp_blobs/blimp.m4v') |
54 |
| -#capture = cv.CaptureFromFile("C:\Users\Jeremy\Documents\GitHub\blimp_blobs\blimp.m4v") |
55 |
| -#capture = cv.CaptureFromFile('http://10.129.20.11/snapshot/view0.jpg') |
56 |
| -#capture = cv.CaptureFromFile('rtsp://10.129.20.11/video.sav') |
57 |
| -#http://10.129.20.11/goform/stream?cmd=get&channel=0 |
58 |
| -#capture = cv.CaptureFromCAM(0) |
59 |
| -#capture = cv.CaptureFromFile("C:/Users/Jeremy/Documents/GitHub/blimp_blobs/Untitled 13.avi") |
60 |
| -#capture = cv.CaptureFromFile("Untitled 13.avi") |
61 |
| -frame = cv.QueryFrame(capture) |
62 |
| -frame_size = cv.GetSize(frame) |
63 |
| - |
64 |
| -#frame = cv.LoadImageM("C:/Users/Jeremy/Documents/GitHub/blimp_blobs/test_images/SmallBlimp/(10.129.20.12)_1_2012_08_21_04_12_07.jpg") |
65 |
| -#frame_size = cv.GetSize(frame) |
| 137 | + |
| 138 | +#!!Need to be on the local WID network to be able to grab images from the cameras |
| 139 | +#grab a frame from the east camera, store it to disk |
| 140 | +fname_east = 'C://Users//Jeremy//Documents//blimp//east.jpg' |
| 141 | +url_east = 'http://10.129.20.11/snapshot/view0.jpg' |
| 142 | +urllib.urlretrieve(url_east,fname_east) |
| 143 | + |
| 144 | +#grab a frame from the west camera, store it to disk |
| 145 | +fname_west = 'C://Users//Jeremy//Documents//blimp//west.jpg' |
| 146 | +url_west = 'http://10.129.20.12/snapshot/view0.jpg' |
| 147 | +urllib.urlretrieve(url_west,fname_west) |
| 148 | + |
| 149 | +frame_west = cv.LoadImageM(fname_west,cv.CV_LOAD_IMAGE_COLOR); |
| 150 | +frame_size = cv.GetSize(frame_west) |
66 | 151 |
|
67 | 152 | # blank images to which images are added later
|
68 |
| -test = cv.CreateImage(cv.GetSize(frame),8,3) |
69 |
| -img2 = cv.CreateImage(cv.GetSize(frame),8,3) |
| 153 | +test = cv.CreateImage(cv.GetSize(frame_west),8,3) |
| 154 | +img2 = cv.CreateImage(cv.GetSize(frame_west),8,3) |
70 | 155 |
|
71 | 156 | # three windows that will open upon execution
|
72 |
| -cv.NamedWindow("Real",0) |
| 157 | +cv.NamedWindow("west",cv.CV_WINDOW_AUTOSIZE) |
| 158 | +cv.NamedWindow("east",cv.CV_WINDOW_AUTOSIZE) |
73 | 159 |
|
74 | 160 | # blank lists to store coordinates of blue blob
|
75 | 161 | blue = []
|
76 | 162 |
|
77 |
| - |
78 | 163 | while(1):
|
79 |
| - # captures feed from video in color |
80 |
| - color_image = cv.QueryFrame(capture) |
81 |
| - #color_image = frame |
82 |
| - |
83 |
| - # ?? |
84 |
| - imdraw = cv.CreateImage(cv.GetSize(frame), 8, 3) |
85 |
| - |
86 |
| - # ?? |
87 |
| - cv.SetZero(imdraw) |
88 |
| - cv.Flip(color_image,color_image, 1) |
89 |
| - cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0) |
90 |
| - # ?? |
91 |
| - imgbluethresh = getthresholdedimg(color_image) |
92 |
| - cv.Erode(imgbluethresh, imgbluethresh, None, 3) |
93 |
| - cv.Dilate(imgbluethresh, imgbluethresh, None, 10) |
94 |
| - # ?? |
95 |
| - img2 = cv.CloneImage(imgbluethresh) |
96 |
| - # ?? |
97 |
| - storage = cv.CreateMemStorage(0) |
98 |
| - contour = cv.FindContours(imgbluethresh, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) |
99 |
| - |
100 |
| - # blank list into which points for bounding rectangles around blobs are appended |
101 |
| - points = [] |
102 |
| - |
103 |
| - # this is the new part here. ie use of cv.BoundingRect() |
104 |
| - while contour: |
105 |
| - |
106 |
| - # Draw bounding rectangles |
107 |
| - bound_rect = cv.BoundingRect(list(contour)) |
108 |
| - contour = contour.h_next() |
109 |
| - #print contour # not sure why print contour |
110 |
| - |
111 |
| - # for more details about cv.BoundingRect,see documentation |
112 |
| - pt1 = (bound_rect[0], bound_rect[1]) |
113 |
| - pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) |
114 |
| - points.append(pt1) |
115 |
| - points.append(pt2) |
116 |
| - cv.Rectangle(color_image, pt1, pt2, cv.CV_RGB(255,0,0), 1) |
117 |
| - |
118 |
| - # calculating centroids |
119 |
| - centroidx = cv.Round((pt1[0]+pt2[0])/2) |
120 |
| - centroidy = cv.Round((pt1[1]+pt2[1])/2) |
121 |
| - |
122 |
| - # identifying if blue blobs exist and adding centroids to corresponding lists. |
123 |
| - # note that the lower and upper bounds correspond to the the lower and upper bounds |
124 |
| - # in the getthresholdedimg(im): function earlier in the script. |
125 |
| - # e.g., yellow has a lowerbound of 95 and upper bound of 115 in both sections of code |
126 |
| - if (55 < cv.Get2D(imghsv,centroidy,centroidx)[0] < 155): |
127 |
| - blue.append((centroidx,centroidy)) |
128 |
| - |
129 |
| - # draw colors in windows; exception handling is used to avoid IndexError. |
130 |
| - # after drawing is over, centroid from previous part is removed from list by pop. |
131 |
| - # so in next frame, centroids in this frame become initial points of line to draw |
132 |
| - |
133 |
| - # draw blue box around blue blimp blob |
134 |
| - try: |
135 |
| - cv.Circle(imdraw, blue[1], 5, (255,0,0)) |
136 |
| - cv.Line(imdraw, blue[0], blue[1], (255,0,0), 3, 8, 60) |
137 |
| - blue.pop(0) |
138 |
| - print("centroid x:" + str(centroidx)) |
139 |
| - print("centroid y:" + str(centroidy)) |
140 |
| - print("") |
141 |
| - except IndexError: |
142 |
| - print "no blimp detected" |
143 |
| - |
144 |
| - |
145 |
| - # adds |
146 |
| - cv.Add(test,imdraw,test) |
147 |
| - |
148 |
| - # display windows previously created |
149 |
| - cv.ShowImage("Real", color_image) |
150 |
| - |
151 |
| - if cv.WaitKey(33) == 1048603: |
152 |
| - cv.DestroyWindow("Real") |
153 |
| - break |
| 164 | + urllib.urlretrieve(url_west,fname_west) |
| 165 | + urllib.urlretrieve(url_east,fname_east) |
| 166 | + |
| 167 | + frame_west = cv.LoadImageM(fname_west,cv.CV_LOAD_IMAGE_COLOR); |
| 168 | + frame_east = cv.LoadImageM(fname_east,cv.CV_LOAD_IMAGE_COLOR); |
| 169 | + |
| 170 | + imdraw_west = cv.CreateImage(cv.GetSize(frame_west), 8, 3) |
| 171 | + imdraw_east = cv.CreateImage(cv.GetSize(frame_east), 8, 3) |
| 172 | + |
| 173 | + #process west image |
| 174 | + cv.SetZero(imdraw_west) |
| 175 | + cv.Smooth(frame_west, frame_west, cv.CV_GAUSSIAN, 3, 0) |
| 176 | + imgbluethresh = getthresholdedimg(frame_west) |
| 177 | + cv.Erode(imgbluethresh, imgbluethresh, None, 3) |
| 178 | + cv.Dilate(imgbluethresh, imgbluethresh, None, 10) |
| 179 | + img2 = cv.CloneImage(imgbluethresh) |
| 180 | + storage = cv.CreateMemStorage(0) |
| 181 | + contour = cv.FindContours(imgbluethresh, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) |
| 182 | + # blank list into which points for bounding rectangles around blobs are appended |
| 183 | + points = [] |
| 184 | + while contour: |
| 185 | + |
| 186 | + # Draw bounding rectangles |
| 187 | + bound_rect = cv.BoundingRect(list(contour)) |
| 188 | + contour = contour.h_next() |
| 189 | + #print contour # not sure why print contour |
| 190 | + |
| 191 | + # for more details about cv.BoundingRect,see documentation |
| 192 | + pt1 = (bound_rect[0], bound_rect[1]) |
| 193 | + pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) |
| 194 | + points.append(pt1) |
| 195 | + points.append(pt2) |
| 196 | + cv.Rectangle(frame_west, pt1, pt2, cv.CV_RGB(255,0,0), 1) |
| 197 | + |
| 198 | + # calculating centroids |
| 199 | + centroidx = cv.Round((pt1[0]+pt2[0])/2) |
| 200 | + centroidy = cv.Round((pt1[1]+pt2[1])/2) |
| 201 | + |
| 202 | + # identifying if blue blobs exist and adding centroids to corresponding lists. |
| 203 | + # note that the lower and upper bounds correspond to the the lower and upper bounds |
| 204 | + # in the getthresholdedimg(im): function earlier in the script. |
| 205 | + # e.g., yellow has a lowerbound of 95 and upper bound of 115 in both sections of code |
| 206 | + if (55 < cv.Get2D(imghsv,centroidy,centroidx)[0] < 155): |
| 207 | + blue.append((centroidx,centroidy)) |
| 208 | + |
| 209 | + # draw colors in windows; exception handling is used to avoid IndexError. |
| 210 | + # after drawing is over, centroid from previous part is removed from list by pop. |
| 211 | + # so in next frame, centroids in this frame become initial points of line to draw |
| 212 | + |
| 213 | + # draw blue box around blue blimp blob |
| 214 | + try: |
| 215 | + cv.Circle(imdraw_west, blue[1], 5, (255,0,0)) |
| 216 | + cv.Line(imdraw_west, blue[0], blue[1], (255,0,0), 3, 8, 0) |
| 217 | + blue.pop(0) |
| 218 | + print("west centroid x:" + str(centroidx)) |
| 219 | + print("west centroid y:" + str(centroidy)) |
| 220 | + print("") |
| 221 | + except IndexError: |
| 222 | + print "no blimp detected" |
| 223 | + |
| 224 | + |
| 225 | + # adds |
| 226 | + cv.Add(test,imdraw_west,test) |
| 227 | + |
| 228 | + centx_west = centroidx |
| 229 | + centy_west = centroidy |
| 230 | + |
| 231 | + |
| 232 | + #process east image |
| 233 | + cv.SetZero(imdraw_east) |
| 234 | + cv.Smooth(frame_east, frame_east, cv.CV_GAUSSIAN, 3, 0) |
| 235 | + imgbluethresh = getthresholdedimg(frame_east) |
| 236 | + cv.Erode(imgbluethresh, imgbluethresh, None, 3) |
| 237 | + cv.Dilate(imgbluethresh, imgbluethresh, None, 10) |
| 238 | + img2 = cv.CloneImage(imgbluethresh) |
| 239 | + storage = cv.CreateMemStorage(0) |
| 240 | + contour = cv.FindContours(imgbluethresh, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) |
| 241 | + # blank list into which points for bounding rectangles around blobs are appended |
| 242 | + points = [] |
| 243 | + while contour: |
| 244 | + |
| 245 | + # Draw bounding rectangles |
| 246 | + bound_rect = cv.BoundingRect(list(contour)) |
| 247 | + contour = contour.h_next() |
| 248 | + #print contour # not sure why print contour |
| 249 | + |
| 250 | + # for more details about cv.BoundingRect,see documentation |
| 251 | + pt1 = (bound_rect[0], bound_rect[1]) |
| 252 | + pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) |
| 253 | + points.append(pt1) |
| 254 | + points.append(pt2) |
| 255 | + cv.Rectangle(frame_east, pt1, pt2, cv.CV_RGB(255,0,0), 1) |
| 256 | + |
| 257 | + # calculating centroids |
| 258 | + centroidx = cv.Round((pt1[0]+pt2[0])/2) |
| 259 | + centroidy = cv.Round((pt1[1]+pt2[1])/2) |
| 260 | + |
| 261 | + # identifying if blue blobs exist and adding centroids to corresponding lists. |
| 262 | + # note that the lower and upper bounds correspond to the the lower and upper bounds |
| 263 | + # in the getthresholdedimg(im): function earlier in the script. |
| 264 | + # e.g., yellow has a lowerbound of 95 and upper bound of 115 in both sections of code |
| 265 | + if (55 < cv.Get2D(imghsv,centroidy,centroidx)[0] < 155): |
| 266 | + blue.append((centroidx,centroidy)) |
| 267 | + |
| 268 | + # draw colors in windows; exception handling is used to avoid IndexError. |
| 269 | + # after drawing is over, centroid from previous part is removed from list by pop. |
| 270 | + # so in next frame, centroids in this frame become initial points of line to draw |
| 271 | + |
| 272 | + # draw blue box around blue blimp blob |
| 273 | + try: |
| 274 | + cv.Circle(imdraw_east, blue[1], 5, (255,0,0)) |
| 275 | + cv.Line(imdraw_east, blue[0], blue[1], (255,0,0), 3, 8, 0) |
| 276 | + blue.pop(0) |
| 277 | + print("east centroid x:" + str(centroidx)) |
| 278 | + print("east centroid y:" + str(centroidy)) |
| 279 | + print("") |
| 280 | + except IndexError: |
| 281 | + print "no blimp detected" |
| 282 | + |
| 283 | + |
| 284 | + # adds |
| 285 | + cv.Add(test,imdraw_east,test) |
| 286 | + |
| 287 | + centx_east = centroidx |
| 288 | + centy_east = centroidy |
| 289 | + |
| 290 | + cv.ShowImage("west", frame_west) |
| 291 | + cv.WaitKey(100) |
| 292 | + |
| 293 | + |
| 294 | + cv.ShowImage("east", frame_east) |
| 295 | + cv.WaitKey(100) |
| 296 | + |
| 297 | + triang_3D(centx_west, centy_west, centx_east, centy_east) |
| 298 | + |
| 299 | + print("x_3d: " + str(x_3d)) |
| 300 | + print("y_3d: " + str(y_3d)) |
| 301 | + print("z_3d: " + str(z_3d)) |
| 302 | + |
154 | 303 | ######################################################
|
0 commit comments