|
6 | 6 | cv2.namedWindow("Adjust") #Adjust help us to find the right threshold values for better accuracy using slider window.
|
7 | 7 | cv2.createTrackbar("min","Adjust",110,255, lambda x: None)
|
8 | 8 |
|
| 9 | +def distance(x1,x2,y1,y2): |
| 10 | + return (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) |
| 11 | + |
| 12 | +def exit(): |
| 13 | + cap.release() |
| 14 | + cv2.destroyAllWindows() |
| 15 | + |
9 | 16 | text = 'Left'
|
10 | 17 | while True:
|
11 | 18 | ret ,frame = cap.read() #Reading each frame.
|
12 |
| - frame = cv2.resize(frame, (640,480), interpolation=cv2.INTER_AREA) |
13 |
| - cropped = frame[100:400,100:500] |
14 |
| - cropped = cv2.flip(cropped,1) |
15 |
| - temp = cropped |
| 19 | + frame = cv2.resize(frame, (640,480), interpolation=cv2.INTER_AREA) #Resizing |
| 20 | + cropped = frame[100:400,100:500] #Cropping the frame |
| 21 | + cropped = cv2.flip(cropped,1) #Flipping the frame vertically |
| 22 | + temp = cropped #Temp is our original image |
16 | 23 | cropped = cv2.cvtColor(cropped, cv2.COLOR_BGR2GRAY)
|
17 |
| - mi = cv2.getTrackbarPos("min","Adjust") |
| 24 | + mi = cv2.getTrackbarPos("min","Adjust") #Getting the values from the trackbar |
18 | 25 |
|
19 |
| - _,threshold = cv2.threshold(cropped,mi,255,cv2.THRESH_BINARY) |
20 |
| - kernal = np.zeros([10,10],np.uint8) |
21 |
| - threshold = cv2.erode(threshold,kernal) |
22 |
| - contours,_=cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) |
| 26 | + _,threshold = cv2.threshold(cropped,mi,255,cv2.THRESH_BINARY)#Converting image to binary (1's and 0's only) |
| 27 | + kernal = np.zeros([10,10],np.uint8) #creating a square of 10X10 of zeroes |
| 28 | + threshold = cv2.erode(threshold,kernal) #using this square to remove noise from the threshold |
| 29 | + contours,_=cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #Finding contours or areas with same color |
23 | 30 |
|
24 |
| - for cnt in contours : |
25 |
| - area = cv2.contourArea(cnt) |
| 31 | + for cnt in contours : #iterating through each contour |
| 32 | + area = cv2.contourArea(cnt) |
26 | 33 | if area > 400 : #Selecting Contours only with area greater then 400
|
27 |
| - approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True) |
| 34 | + approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True) #Reducing the number of edges/vertices or approximating the contour |
28 | 35 | approx_area = cv2.contourArea(approx)
|
29 | 36 | if(len(approx)==7): #As an arrow has seven edges, hence we are selecting the polygon with 7 edges
|
30 |
| - n = approx.ravel() |
| 37 | + n = approx.ravel() #Converts 2d array into 1d array |
31 | 38 | x1 = n[0] #First Co-ordinate always point to the topmost vertex
|
32 | 39 | y1 = n[1]
|
33 | 40 | x2 = n[2]
|
34 | 41 | y2 = n[3]
|
35 | 42 | x3 = n[6]
|
36 | 43 | y3 = n[7]
|
37 |
| - distance1 = (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2) |
38 |
| - distance2 = (x1 - x3)*(x1 - x3) + (y1 - y3)*(y1 - y3) |
| 44 | + distance1 = distance(x1,x2,y1,y2) |
| 45 | + distance2 = distance(x1,x3,y1,y3) |
39 | 46 | ratio = distance1/distance2 #Ratio will help us to determine the orientation or angle of the arrow
|
40 | 47 | if(2500<approx_area<25000 and (0.2<ratio<0.3 or ratio <0.1)):
|
41 |
| - cv2.drawContours(temp,[approx],0,(0,0,255),5) |
| 48 | + cv2.drawContours(temp,[approx],0,(0,0,255),5) #Outlining the detected arrow with red color |
42 | 49 |
|
43 |
| - x = approx.ravel()[0] |
44 |
| - y = approx.ravel()[1] |
| 50 | + x = approx.ravel()[0] #x co-ordinate of the top-most vertex (could be the tip or the end of the arrow) |
| 51 | + y = approx.ravel()[1] #y co-ordinate of the top-most vertex (could be the tip or the end of the arrow) |
45 | 52 |
|
46 |
| - if(0.2 < distance1/distance2 < 0.3): #Finding the tip of the arrow with the help of the ratios |
| 53 | + if(0.2 < distance1/distance2 < 0.3): #Finding the tip of the arrow with the help of the ratios of the distances |
47 | 54 | cv2.putText(temp,"Arrow tip",(x,y),font,0.5,(0,0,255))
|
48 |
| - endx = (n[6]+n[8])/2 |
49 |
| - endy = (n[7]+n[9])/2 |
50 | 55 | topx = x1
|
51 | 56 | topy = y1
|
52 |
| - length = np.sqrt((topx-endx)*(topx-endx) + (topy-endy)*(topy-endy)) |
| 57 | + endx = (n[6]+n[8])/2 |
| 58 | + endy = (n[7]+n[9])/2 |
| 59 | + length = np.sqrt(distance(topx,endx,topy,endy)) |
53 | 60 | y_v = endy-length
|
54 |
| - if((topx-endx)==0): |
| 61 | + if((topx-endx)==0):#Denominator becomes zero |
55 | 62 | print(0)
|
56 | 63 | else:
|
57 | 64 | tan = (topy - y_v)/(topx - endx)
|
58 | 65 | print(np.arctan(tan)*57.3*2) #Basic cirle property to print the angles ( between 90 and -90)
|
59 | 66 |
|
60 |
| - else : |
| 67 | + else: |
61 | 68 | cv2.putText(temp,"Arrow end",(x,y),font,0.5,(0,0,255))
|
62 | 69 | if(distance1/distance2 <0.1):
|
63 |
| - endx = (n[2]+n[0])/2 |
64 |
| - endy = (n[3]+n[1])/2 |
65 | 70 | topx = n[8]
|
66 | 71 | topy = n[9]
|
67 |
| - length = np.sqrt((topx-endx)*(topx-endx) + (topy-endy)*(topy-endy)) |
| 72 | + endx = (n[2]+n[0])/2 |
| 73 | + endy = (n[3]+n[1])/2 |
| 74 | + length = np.sqrt(distance(topx,endx,topy,endy)) |
68 | 75 | y_v = endy - length
|
69 |
| - if((topx-endx)==0): |
| 76 | + if((topx-endx)==0):#Denominator becomes zero |
70 | 77 | print(180)
|
71 | 78 | else:
|
72 | 79 | tan = (topy - y_v)/(topx - endx)
|
|
76 | 83 | topy = n[7]
|
77 | 84 | endx = (n[12]+n[0])/2
|
78 | 85 | endy = (n[13]+n[1])/2
|
79 |
| - length = np.sqrt((topx-endx)*(topx-endx) + (topy-endy)*(topy-endy)) |
| 86 | + length = np.sqrt(distance(topx,endx,topy,endy)) |
80 | 87 | y_v = endy - length
|
81 |
| - if((topx-endx)==0): |
| 88 | + if((topx-endx)==0):#Denominator becomes zero |
82 | 89 | print(180)
|
83 | 90 | else:
|
84 | 91 | tan = (topy - y_v)/(topx - endx)
|
85 | 92 | print(np.arctan(tan*57.3)*2)
|
86 | 93 |
|
87 |
| - cv2.imshow('temp',temp) |
88 |
| - cv2.imshow('threshold',threshold) |
89 |
| - #print(text) |
90 |
| - if cv2.waitKey(1) & 0xFF == ord('q'): |
| 94 | + cv2.imshow('temp',temp) #Displaying original image |
| 95 | + cv2.imshow('threshold',threshold) #Displaying threshold image |
| 96 | + if cv2.waitKey(1) & 0xFF == ord('q'): #Program will quite when q is pressed |
91 | 97 | break
|
92 |
| - |
93 |
| -cap.release() |
94 |
| -cv2.destroyAllWindows() |
| 98 | +exit() |
0 commit comments