-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAssignment.py
More file actions
155 lines (111 loc) Β· 4.54 KB
/
Assignment.py
File metadata and controls
155 lines (111 loc) Β· 4.54 KB
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
"""
π· Contours & Shape Detection App
\======================================
This assignment helps users explore the concept of **contour detection** and **shape approximation** using OpenCV.
It demonstrates how to detect objects, approximate their geometry, and annotate their shape on an image.
---
π **Instructions**:
1. Start the program or notebook.
2. ## Choose one of the following shape creation methods:
**\[1] Draw Basic Shapes (Circle, Rectangle, etc.)**
* Programmatically create shapes (e.g., using `cv2.circle`, `cv2.rectangle`)
* Shapes must be filled or outlined with white (value = 255) on a black background
**\[2] Use a Preloaded or Uploaded Image**
* Upload an image with clearly defined shapes
* Convert to grayscale and apply thresholding before contour detection
---
3. ## Perform Contour Detection:
* Convert the image to grayscale (if not already)
* Apply **thresholding** (e.g., `cv2.threshold`) to get a binary image
* Use `cv2.findContours()` to extract contours
---
4. ## Shape Approximation & Classification:
* Iterate through contours
* Use `cv2.approxPolyDP()` to approximate each contour's shape
* Count the number of corners:
- **3 points** β Triangle
- **4 points** β Rectangle or Square
- **5 points** β Pentagon
- **>5 points** β Circle (or other curved shapes)
---
5. ## Draw and Annotate Results:
* Use `cv2.drawContours()` to draw detected shapes in color
* Use `cv2.putText()` to label each shape with its name above the contour
* You may also print coordinates or area (optional)
---
π¦ **Optional Additions**:
- Detect nested contours using `cv2.RETR_TREE` and draw hierarchy
- Add area/centroid calculations using `cv2.contourArea()` and `cv2.moments()`
- Annotate number of shapes detected
---
π‘ **Notes**:
* Ensure the input image is **binary or high contrast** for effective contour detection
* Use shape approximation threshold like `0.01 * cv2.arcLength(...)` for precision
* All contours should be labeled clearly with shape name and drawn in color for clarity
---
π **Learning Objectives**:
β
Understand how contours represent shape boundaries in images
β
Learn to use polygonal approximation to detect shape types
β
Practice using OpenCV functions: `findContours`, `approxPolyDP`, `drawContours`, `putText`
β
Improve image analysis and object recognition skills with OpenCV
---
π§ **Dependencies**:
* `OpenCV (cv2)`
* `NumPy`
* `matplotlib` *(for image display)*
* `PIL (optional)` *(for custom image processing or saving)*
"""
import cv2
import numpy as np
import matplotlib.pyplot as plt
def create_test_image():
"""Create an image with different shapes on a black background."""
img = np.zeros((400, 400), dtype=np.uint8)
cv2.rectangle(img, (50, 50), (150, 150), 255, -1) # Square
cv2.circle(img, (300, 100), 50, 255, -1) # Circle
cv2.polylines(
img, [np.array([[200, 200], [250, 300], [150, 300]])], True, 255, -1
) # Triangle
cv2.polylines(
img,
[np.array([[270, 220], [320, 270], [300, 320], [250, 320], [230, 270]])],
True,
255,
-1,
) # Pentagon
return img
def detect_shapes(img):
contours, _ = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
annotated = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
for cnt in contours:
epsilon = 0.01 * cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
x, y, w, h = cv2.boundingRect(approx)
# Shape classification
corners = len(approx)
if corners == 3:
shape = "Triangle"
elif corners == 4:
shape = "Rectangle"
elif corners == 5:
shape = "Pentagon"
else:
shape = "Circle"
cv2.drawContours(annotated, [approx], 0, (0, 255, 0), 2)
cv2.putText(
annotated, shape, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 0), 2
)
return annotated
if __name__ == "__main__":
img = create_test_image()
_, thresh = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
result = detect_shapes(thresh)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title("Input Image")
plt.imshow(img, cmap="gray")
plt.subplot(1, 2, 2)
plt.title("Detected Shapes")
plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
plt.axis("off")
plt.show()