Geometric shape recognition and measurement in OpenCV


Geometric shape recognition and measurement in OpenCV


Writing with code and being compassionate


I often see people who have learned OpenCV not long ago asking how to recognize some simple geometric shapes and their colors. In fact, with OpenCV's contour discovery and geometric analysis related functions, it takes less than 100 lines of code to implement these simple geometric shape recognition and object measurement related operations very well. This article will show you how to implement the following functions through OpenCV contour discovery and geometric analysis related functions.

  • Geometric shape recognition (identify triangles, quadrilateral/rectangles, polygons, circles)
  • Calculate geometric shape area and perimeter, center location
  • Extracting the colors of geometric shapes

Before we get to the specific code implementation and program demonstration, let's get some concepts straight.

I: Introduction to basic concepts and functions

1. Contours

What is a contour? Simply put, a contour is a series of points connected to form a shape, they have the same color, contour discovery is a very useful tool for object analysis, object detection, etc. When using contour discovery related functions in OpenCV, the input image is required to be a binary image, so that it is easy to contour extraction, edge extraction and other operations. The functions and parameters for profile discovery are explained as follows.

findContours(image, mode, method, contours=None, hierarchy=None, offset=None)
 - image input/output binary image
 - mode returns the structure of the profile, which can be List, Tree, External
 - method The way contour points are encoded is basically based on the chain encoding
 - contours The set of contours returned
 - hieracrchy returns the contour hierarchy
 - Whether the offset point is displaced

2. polygon approximation

polygonalloom, is achieved by infinitely approximating the profile shape, Removal of non-critical points、 Key points for getting the profile, A method of constantly approximating the true shape of a silhouette,OpenCV in polygonal The functions and parameters of the approximation are explained as follows:

approxPolyDP(curve, epsilon, closed, approxCurve=None)
 - curve indicates the set of input contour points
 - epsilon denotes the approximation curvature, smaller means more similar approximation
- close Whether to close

3. geometric distance calculation

The image geometric distance is a geometric feature of the image, and the higher-order geometric distance has feature invariance after centering, which can produce Hu distance output for operations such as shape matching, Here we get the center position of the specified contour by calculating the first-order geometric distance, and the function and parameters for calculating the geometric distance are explained as follows.

moments(array, binaryImage=None)
 - array indicates the specified input profile
 - binaryImage defaults to None

II: Code implementation and demonstration

Based on contour discovery and polygon approximation, geometric distance for geometric shape recognition and object measurement, two other related APIs are used to calculate the perimeter and area of the contour respectively. The exact usage is reflected in the code. The entire code is implemented in the following steps: 1. Image binarization

#  binarized image
print("start to detect lines...
")
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
cv.imshow("input image", frame)

2.Contour Discovery

out_binary, contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for cnt in range(len(contours)):
    #  Extracting and drawing contours
    cv.drawContours(result, contours, cnt, (0, 255, 0), 2)

3.geometric shape recognition

#  silhouette approaching
epsilon = 0.01 * cv.arcLength(contours[cnt], True)
approx = cv.approxPolyDP(contours[cnt], epsilon, True)

#  Analyze the geometry
corners = len(approx)
shape_type = ""
if corners == 3:
    count = self.shapes['triangle']
    count = count+1
    self.shapes['triangle'] = count
    shape_type = " triangular"
if corners == 4:
    count = self.shapes['rectangle']
    count = count + 1
    self.shapes['rectangle'] = count
    shape_type = " rectangles"
if corners >= 10:
    count = self.shapes['circles']
    count = count + 1
    self.shapes['circles'] = count
    shape_type = " circle"
if 4 < corners < 10:
    count = self.shapes['polygons']
    count = count + 1
    self.shapes['polygons'] = count
    shape_type = " polygonal"

4.Measure perimeter, area, calculate center

 # Solve for center location
mm = cv.moments(contours[cnt])
cx = int(mm['m10'] / mm['m00'])
cy = int(mm['m01'] / mm['m00'])
cv.circle(result, (cx, cy), 3, (0, 0, 255), -1)

 # Calculate area and perimeter
p = cv.arcLength(contours[cnt], True)
area = cv.contourArea(contours[cnt])

5.Color Extraction

#  Color Analysis
color = frame[cy][cx]
color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")"

The run shows the original image as follows.

Analysis of the results.

Console output.


Recommended>>
1、How to design Java exceptions elegantly
2、Indepth analysis of Java garbage collection mechanism
3、AOF persistence for Redis
4、URIwasnotreportedtoparserforentity
5、IT interview dry run PHP interview questions summary and answers

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号