Skip to content
This repository was archived by the owner on Dec 22, 2023. It is now read-only.

Commit 2676434

Browse files
authored
Update Arrow.py
Added Additional comments for better explanation.
1 parent 35727b6 commit 2676434

File tree

1 file changed

+41
-37
lines changed
  • Scripts/Miscellaneous/Arrow_Angle_detector

1 file changed

+41
-37
lines changed

Scripts/Miscellaneous/Arrow_Angle_detector/Arrow.py

+41-37
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,74 @@
66
cv2.namedWindow("Adjust") #Adjust help us to find the right threshold values for better accuracy using slider window.
77
cv2.createTrackbar("min","Adjust",110,255, lambda x: None)
88

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+
916
text = 'Left'
1017
while True:
1118
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
1623
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
1825

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
2330

24-
for cnt in contours :
25-
area = cv2.contourArea(cnt)
31+
for cnt in contours : #iterating through each contour
32+
area = cv2.contourArea(cnt)
2633
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
2835
approx_area = cv2.contourArea(approx)
2936
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
3138
x1 = n[0] #First Co-ordinate always point to the topmost vertex
3239
y1 = n[1]
3340
x2 = n[2]
3441
y2 = n[3]
3542
x3 = n[6]
3643
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)
3946
ratio = distance1/distance2 #Ratio will help us to determine the orientation or angle of the arrow
4047
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
4249

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)
4552

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
4754
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
5055
topx = x1
5156
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))
5360
y_v = endy-length
54-
if((topx-endx)==0):
61+
if((topx-endx)==0):#Denominator becomes zero
5562
print(0)
5663
else:
5764
tan = (topy - y_v)/(topx - endx)
5865
print(np.arctan(tan)*57.3*2) #Basic cirle property to print the angles ( between 90 and -90)
5966

60-
else :
67+
else:
6168
cv2.putText(temp,"Arrow end",(x,y),font,0.5,(0,0,255))
6269
if(distance1/distance2 <0.1):
63-
endx = (n[2]+n[0])/2
64-
endy = (n[3]+n[1])/2
6570
topx = n[8]
6671
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))
6875
y_v = endy - length
69-
if((topx-endx)==0):
76+
if((topx-endx)==0):#Denominator becomes zero
7077
print(180)
7178
else:
7279
tan = (topy - y_v)/(topx - endx)
@@ -76,19 +83,16 @@
7683
topy = n[7]
7784
endx = (n[12]+n[0])/2
7885
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))
8087
y_v = endy - length
81-
if((topx-endx)==0):
88+
if((topx-endx)==0):#Denominator becomes zero
8289
print(180)
8390
else:
8491
tan = (topy - y_v)/(topx - endx)
8592
print(np.arctan(tan*57.3)*2)
8693

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
9197
break
92-
93-
cap.release()
94-
cv2.destroyAllWindows()
98+
exit()

0 commit comments

Comments
 (0)