Skip to content

Commit a7ef7a2

Browse files
authored
Merge pull request #584 from kuspia/main
polygon_detector
2 parents b102d36 + bf36b4a commit a7ef7a2

File tree

6 files changed

+212
-0
lines changed

6 files changed

+212
-0
lines changed

polygon_detector/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
# Polygon detector: A powerful automated python script to detect various polygon from an input image.
3+
4+
5+
Following listed properties are determined by the script
6+
```
7+
type
8+
color
9+
area
10+
location
11+
```
12+
_Note: Color will be classified as red or green or blue depending upon the dominant shade also note for the centroid location of each shape top left corner of the image is taken as origin._
13+
14+
Supported Polygons
15+
```
16+
>Triangle
17+
>Quadilaterals
18+
> Square
19+
> Rhombus
20+
> Trapezium
21+
> Parllelogram
22+
>Pentagon
23+
>Hexagon
24+
>Circle
25+
```
26+
27+
### Sample Example
28+
29+
<img src="/polygon_detector/img_guide_help/1.png" alt="slow_net_have_fast_internet_to_load_it_ok"/>
30+
31+
# *******
32+
33+
<img src="/polygon_detector/img_guide_help/2.png" alt="slow_net_have_fast_internet_to_load_it_ok"/>
34+
35+

polygon_detector/Samples/Sample1.png

8.54 KB
Loading

polygon_detector/img_guide_help/1.png

8.54 KB
Loading

polygon_detector/img_guide_help/2.png

70.4 KB
Loading

polygon_detector/polygon_detect.py

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
2+
# flake8: noqa
3+
import cv2
4+
import numpy as np
5+
import os
6+
7+
8+
shapes = {}
9+
10+
def scan_image(img_file_path):
11+
12+
global shapes
13+
img = cv2.imread(img_file_path)
14+
15+
gimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
16+
17+
_, timg = cv2.threshold(gimg, 254, 255, cv2.THRESH_BINARY)
18+
co, _ = cv2.findContours(timg, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
19+
20+
shapes1 = {}
21+
for i in range(1, len(co)):
22+
app = cv2.approxPolyDP(co[i], 0.01 * cv2.arcLength(co[i], True), True)
23+
M = cv2.moments(co[i])
24+
cX = int(M['m10'] / M['m00'])
25+
cY = int(M['m01'] / M['m00'])
26+
Area = round(cv2.contourArea(co[i]), 1)
27+
28+
colorarr = img[cY, cX]
29+
fincol = 'NA'
30+
B = colorarr[0]
31+
G = colorarr[1]
32+
R = colorarr[2]
33+
34+
if (R > G):
35+
if (B > R):
36+
fincol = 'blue'
37+
else:
38+
fincol = 'red'
39+
else:
40+
if (B > G):
41+
fincol = 'blue'
42+
else:
43+
fincol = 'green'
44+
if (len(app) == 3):
45+
shapes1['Triangle'] = [fincol, Area, cX, cY]
46+
elif (len(app) == 4):
47+
ptsarr = app.ravel()
48+
49+
x1 = ptsarr[0]
50+
y1 = ptsarr[1]
51+
x2 = ptsarr[2]
52+
y2 = ptsarr[3]
53+
x3 = ptsarr[4]
54+
y3 = ptsarr[5]
55+
x4 = ptsarr[6]
56+
y4 = ptsarr[7]
57+
58+
l1 = ((x2 - x1) ** 2 + (y2 - y1) ** 2)
59+
l2 = ((x3 - x2) ** 2 + (y3 - y2) ** 2)
60+
l3 = ((x4 - x3) ** 2 + (y4 - y3) ** 2)
61+
l4 = ((x4 - x1) ** 2 + (y4 - y1) ** 2)
62+
63+
d1 = ((x3 - x1) ** 2 + (y3 - y1) ** 2)
64+
d2 = ((x4 - x2) ** 2 + (y4 - y2) ** 2)
65+
66+
ap1 = float(l1) / l2
67+
ap2 = float(l2) / l3
68+
ap3 = float(l3) / l4
69+
ap4 = float(l4) / l1
70+
71+
f = 0
72+
73+
if (abs(x2 - x1) < 3 and abs(x3 - x4) < 3):
74+
f = 1
75+
if (abs(y2 - y1) < 3 and abs(y3 - y4) < 3):
76+
f = 1
77+
if (abs(x1 - x4) < 3 and abs(x2 - x3) < 3):
78+
f = 1
79+
if (abs(y1 - y4) < 3 and abs(y2 - y3) < 3):
80+
f = 1
81+
82+
if ((x2 - x1) != 0 and (x3 - x4) != 0):
83+
sl1 = float(y2 - y1) / (x2 - x1)
84+
sl2 = float(y3 - y4) / (x3 - x4)
85+
if (sl2 != 0):
86+
sl = abs(float(sl1) / sl2)
87+
if (sl >= 0.9 and sl <= 1.1):
88+
f = 1
89+
if ((x1 - x4) != 0 and (x2 - x3) != 0):
90+
sl1 = float(y1 - y4) / (x1 - x4)
91+
sl2 = float(y2 - y3) / (x2 - x3)
92+
if (sl2 != 0):
93+
sl = abs(float(sl1) / sl2)
94+
if (sl >= 0.9 and sl <= 1.1):
95+
f = 1
96+
97+
98+
if ((ap1 >= 0.9 and ap1 <= 1.1) and (ap2 >= 0.9 and ap2 <= 1.1) and (ap3 >= 0.9 and ap3 <= 1.1) and (
99+
ap4 >= 0.9 and ap4 <= 1.1)):
100+
if (float(d1) / d2 >= 0.9 and float(d1) / d2 <= 1.1):
101+
shapes1['Square'] = [fincol, Area, cX, cY]
102+
else:
103+
shapes1['Rhombus'] = [fincol, Area, cX, cY]
104+
elif ((float(l1) / l3 >= 0.9 and float(l1) / l3 <= 1.1) and (
105+
float(l2) / l4 >= 0.9 and float(l2) / l4 <= 1.1)):
106+
shapes1['Parallelogram'] = [fincol, Area, cX, cY]
107+
elif (f):
108+
shapes1['Trapezium'] = [fincol, Area, cX, cY]
109+
else:
110+
shapes1['Quadrilateral'] = [fincol, Area, cX, cY]
111+
elif (len(app) == 5):
112+
shapes1['Pentagon'] = [fincol, Area, cX, cY]
113+
elif (len(app) == 6):
114+
shapes1['Hexagon'] = [fincol, Area, cX, cY]
115+
else:
116+
shapes1['Circle'] = [fincol, Area, cX, cY]
117+
118+
shapes.clear()
119+
120+
for key, value in sorted(shapes1.items(), key=lambda e: e[1][1], reverse=True):
121+
shapes[key] = value
122+
123+
shapes1.clear()
124+
125+
return shapes
126+
127+
128+
if __name__ == '__main__':
129+
130+
total_sam = 1
131+
132+
while(total_sam != 0 ):
133+
134+
curr_dir_path = os.getcwd()
135+
print('Currently working in '+ curr_dir_path)
136+
137+
img_dir_path = curr_dir_path + '/Samples/'
138+
139+
140+
file_num = total_sam
141+
total_sam-=1
142+
img_file_path = img_dir_path + 'Sample' + str(file_num) + '.png'
143+
144+
if os.path.exists('Samples/Sample' + str(file_num) + '.png'):
145+
print('\nFound Sample' + str(file_num) + '.png')
146+
147+
else:
148+
print('\n[ERROR] Sample' + str(file_num) + '.png not found. Make sure "Samples" folder has the selected file.')
149+
exit()
150+
151+
152+
153+
try:
154+
155+
shapes = scan_image(img_file_path)
156+
print('*******************************')
157+
158+
print('Total Shapes Found =' , len(shapes))
159+
160+
for i , j in shapes.items():
161+
print ( 'Shape Name:' , i )
162+
print('Color:', j[0])
163+
print('Area:', j[1])
164+
print('Location cX, cY:', j[2] , j[3])
165+
print('Color:', j[3])
166+
print('*******************************')
167+
168+
169+
170+
171+
except Exception:
172+
print('\n[ERROR] scan_image function is throwing an error.')
173+
exit()
174+
175+

polygon_detector/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
numpy==1.19.1
2+
opencv==4.4.0

0 commit comments

Comments
 (0)