OpenCV with Python โ 4
Back to book mode
Introduction
So far, we have mentioned lots of image preprocessing technique. We're going to talk one more approach for elimanating noise and move to the application aspect.
Morphology
Morphology is an image processing theroy based on Lattice theory and topology. Here, we're not going to talk about what is morphology. In fact, we're focus only on dilation and erosion.
Dilation help us to make picture brightness and make the features more bigger then before.
Erosion can make the feature smaller then before.
Often, we will come across lots of noise or some less important feature. We can first apply erosion to erase noise or rescale the size and convert the wanted features back to the original one by dilation. Let's see how dilation and erosion do:
- Dilation:
The value of the output pixel is the maximum value of all pixels in the neighborhood.
- Erosion:
The value of the output pixel is the minimum value of all pixels in the neighborhood.
Notice that before doing the dilation or erosion, we should ensure that the image is in binary format, that is, 0 and 1.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More โ
We removed hexagon but also affect other shapes in the image.
Contour / shape detection
What is contours?
Contours is simply a curve joining all of the continuous points along the specific boundary. Let's say when we see a circle, how do we recognize it as a circle not the rectangle? That's a stupid question, but we should first know HOW humans do, then we can apply it to the computer. Below image show how we do.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More โ
Flow chart of finding contours
Due to the complexity of the function in this session, I will first go through the function going to use and demonstrate all of it later. Here is the flow chart to do the contour detection.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More โ
Step by step explanation
The complete code will be showed after this session.
-
Read Image
-
Blur the image
Remove noise.
-
Convert to binary format
Using Canny or Threshold.
So far, we have finish the preprocessing. We combine them togetherand start to implement a function called get_countours
. (Function starts at line 78, we will walk throught it step by step).
-
Find contours
If mode is cv2.CHAIN_APPROX_SIMPLE, it will only return the points. Otherwise, cv2.CHAIN_APPROX_NONE will return the line. You can try it by yourself!
-
Drop the noise
Here, we use the size of the area to drop the noise. We use threshold to drop the noise.
-
Draw the contours
-
cv2.drawContours(img_output, contour, contourIdx, color, thickness)
Documentation
- img_output: Draw on which image.
- contour: Point vectors (Same as above).
- contourIdx: Index for which contour to draw. If negative, draw all the contours.
-
Recognize the shapes
Draw the bounding box and put the text to specify each shapes.
-
cv2.arcLength(contour, closed)
Documentation
- closed: Flag indicating whether the curve is closed or not.
-
cv2.approxPolyDP(contour, epsilon, closed)
Documentation
- epsilon: Specifying the approximation accuracy.
-
cv2.boundingRect(points)
Documentation
Code
import cv2
import numpy as np
def getContours(img):
'''4. Find contours'''
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
for cnt in contours:
'''5. Drop the noise'''
area = cv2.contourArea(cnt)
if area < 800:
continue
'''6.1 Draw the contours'''
cv2.drawContours(img_contour, cnt, -1, (255, 0, 0), 3)
'''6.2 Regconize the shape'''
peri = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
obj_cor = len(approx)
x, y, w, h = cv2.boundingRect(approx)
if obj_cor == 3:
object_type = "Tri"
elif obj_cor == 4:
asp_ratio = w / h
if (asp_ratio > 0.95) & (asp_ratio < 1.05):
object_type = "Square"
else:
object_type = "Rectangle"
elif obj_cor == 5:
object_type = "Pentagon"
elif obj_cor == 6:
object_type = "Hexagon"
else:
object_type = "Circle"
cv2.rectangle(img_contour, (x, y), (x + w, y + h), (0, 0, 255), 3)
cv2.putText(img_contour, object_type,
(x + (w // 2) - 20, y - 15),
cv2.FONT_HERSHEY_COMPLEX, 0.5,
(0, 0, 0), 2)
'''1. Read image'''
img = cv2.imread("resources/shapes.jpg")
'''2. Blur image'''
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_blur = cv2.GaussianBlur(img_gray, (3, 3), 1)
'''3. Convert to binary image'''
img_canny = cv2.Canny(img_blur, 50, 50)
img_contour = img.copy()
'''Other steps'''
get_contours(img_canny)
img_stack = stackImages(0.5, [[img, img_blur], [img_canny, img_contour]])
cv2.imshow("Result", img_stack)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.waitKey(1)
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More โ
Summary
Find contours can be one of the powerful tools for us. For example, we can use shape as a sign to tell the robot where to go! Also, the bounding box help us to highlight the object we're interested in. In terms of application, we can use it when we're doing object detection. We'll see more example in next article.
Reference
- Contours: Getting started
- LEARN OPENCV in 3 HOURS with Python (2020)
- ใๅฝฑๅ่็ใๅฝขๆ
ๅญธ Morphology