OpenCV contour approximation-polygon fitting, bounding rectangle and bounding circle

Introduction

Contour Approximation refers to approximating or fitting the contour to obtain an approximate contour. In image processing, contours represent the boundaries of objects in an image, so contour approximation can be used to describe and identify the shape of objects.

Polygon fitting

Polygon fitting (Approximating Polygons) is to approximate the outline into a polygon composed of straight line segments. Common ones include minimum enclosing rectangle, minimum enclosing circle, least squares ellipse, etc. Polygon fitting can be achieved using the cv2.approxPolyDP() function.

Contour approximation can reduce the number of contour points, simplify contour information, and facilitate subsequent tasks such as contour feature extraction and object recognition.

Detailed explanation of method

approx = cv2.approxPolyDP(curve, epsilon, closed)

Parameter Description:

  • curve: input contour.
  • epsilon: Approximate accuracy, that is, the maximum Euclidean distance between two contours. The smaller the parameter, the closer the approximate result is to the actual contour; conversely, the approximate result will be rougher.
  • closed: Boolean type parameter, indicating whether to close the outline. If it is True, it means that the input contour is closed, and the approximate result will also be closed; otherwise, it means that the input contour is not closed, and the approximate result will not be closed either.

return value:

  • approx: The approximate result is an ndarray array that contains the coordinates of the points on the approximated contour.

It should be noted that before using the cv2.approxPolyDP() function, you need to use the cv2.findContours() function to extract the contours of the image to obtain the input contour. In addition, when approximating the contour, the appropriate approximation accuracy needs to be selected according to the specific scenario, which is determined based on actual needs.

Code practice:

The experimental data used this time is this picture: random.png. I drew it blindly using drawing software.

OpenCV(10):Contourapproximation-polygonfitting,boundingrectangleandboundingcircle

Following the contour detection mentioned above, first get the contour of the image, and then fit the contour.

import cv2
import numpy as np

#Write a method to display the image. After displaying, press any key to continue the code.
def cv_show(title,img):
    cv2.imshow(title,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    return

img = cv2.imread('random.png')

# is the content of the previous chapter, specifically it will output a contour image and return a contour data
def draw_contour(img,color,width):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#Convert grayscale image
    ret, binary = cv2.threshold(gray,10,255,cv2.THRESH_BINARY)#Convert to binary image
    contour,hierarchy = cv2.findContours(binary, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)#Find contours, all stored in contour
    copy = img.copy()
    result = cv2.drawContours(copy,contour[:],-1,color,width)
    cv_show('resoult',resoult)
    return contour


contour = draw_contour(img,(0,0,255),2)
print(type(contour))
epsilon = 0.01*cv2.arcLength(contour[0],True)
approx = cv2.approxPolyDP(contour[0], epsilon, True)
print(type(approx),approx.shape)

res = cv2.drawContours(img.copy(),[approx],-1,(0,0,255),2)
cv_show('res',res)
In the draw_contour() method, first convert the color image to a grayscale image, and then convert it to a binary image through the cv2.threshold() function. Next, call the cv2.findContours() function to find the contours in the image, and use the cv2.drawContours() function to draw the contours. Finally, the obtained contour data is returned. 

In the main function, first call the draw_contour() method to obtain the contour data of the image, then approximate the contour through the cv2.approxPolyDP() function, and use the cv2.drawContours() function to draw the approximated contour. Finally, the results are displayed through the cv_show() method.

It should be noted that the contour data returned by the cv2.findContours() function is a list containing all contours, so when calling the cv2.approxPolyDP() function, you need to select the contour to be processed, and only one contour can be entered. The test image here is just an outline, so just slice [0] and it’s done.

result:

OpenCV(10): Contour approximation - polygon fitting, bounding rectangle and bounding circleOpenCV(10):Contourapproximation-polygonfitting,boundingrectangleandboundingcircle

Bounding rectangle

The cv2.boundingRect() function is a commonly used function in OpenCV, used to calculate the vertical bounding rectangle (also called the surrounding rectangle or enclosing rectangle) of the outline. Website:yii666.com

The syntax of this function is as follows:

x, y, w, h = cv2.boundingRect(contour)</code><code>

Among them, contour represents the input contour data, which can be a single contour or a list containing multiple contours.

The return value contains four parameters, which respectively represent the x coordinate, y coordinate of the upper left corner of the rectangle, and the width and height of the rectangle.

In this code, the cv2.boundingRect() function is used to obtain the position and size of the bounding rectangle of the input contour, and the x and y< in the return value /code> represents the coordinates of the upper left corner of the bounding rectangle respectively, w and h represent the width and height of the rectangle respectively. This line of code assigns the calculated position and size of the bounding rectangle to x, y, w, and h Four variables.

Code practice:

The test image used this time is this: contour.png. I also drew it casually using a drawing tool.

OpenCV(10):Contourapproximation-polygonfitting,boundingrectangleandboundingcircleArticle address https://www.yii666.com/blog/496427.html

Similar to polygon fitting, first calculate the boundary, and then use cv2.boundingRect() to calculate the bounding rectangle

import cv2
import numpy as np

#Write a method to display the image. After displaying, press any key to continue the code.
def cv_show(title,img):
    cv2.imshow(title,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    return

img = cv2.imread('contour.png')

def draw_contour(img,color,width):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#Convert grayscale image
    ret, binary = cv2.threshold(gray,10,255,cv2.THRESH_BINARY)#Convert to binary image
    contour,hierarchy = cv2.findContours(binary, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)#Find contours, all stored in contour
    copy = img.copy()
    result = cv2.drawContours(copy,contour[:],-1,color,width)
    cv_show('resoult',resoult)
    return contour

contour = draw_contour(img,(0,255,255),2)
#print(np.array(contour).shape)

x,y,w,h = cv2.boundingRect(contour[0])
img_rectangle = cv2.rectangle(img.copy(),(x,y),(x + w,y + h),(255,255,0),2)
cv_show('img',img_rectangle)
</code><code>

In this code, the draw_contour() method is called to obtain the contour data of the image, and it is passed to the cv2.boundingRect() function to calculate the position and size of the bounding rectangle of the contour. . Then, use the cv2.rectangle() function to draw a rectangle on the image. The coordinates of the upper left corner of the rectangle are specified by x and y, and the width and The height is specified by w and h, the color is (255, 255, 0), and the line width is 2. Finally, use the cv_show() method to display the results.

The img.copy() method is used here to copy the original image, and then draw a rectangle on the copied image. This prevents direct modification of the original image; at the same time, using the copied image to display the results is more standardized.

Border circle

cv2.minEnclosingCircle() is a function in OpenCV that is used to calculate the minimum circumscribed circle of a two-dimensional point set.

The function prototype is:

center, radius = cv2.minEnclosingCircle(points)</code><code>

Among them, the points parameter is the input two-dimensional point set, usually a numpy array with the shape of (N,2). center is the coordinates of the center of the output circle, and the shape is (2,); radius is the radius of the output circle.

The implementation principle of this function is to obtain the smallest circle that can cover all point sets by solving the input point set. During implementation, this function uses the Rotating Caliper algorithm to find the smallest circle.

The rotation stuck algorithm is an effective algorithm for calculating the two-dimensional convex hull and its properties. It is also often used when calculating the minimum circumscribed circle. The basic idea of the algorithm is to first calculate the convex hull of the point set, and then rotate two tangents on the boundary of the convex hull, respectively as the diameter of the circle, to find the smallest circle.

It should be noted that the cv2.minEnclosingCircle() function is only applicable to two-dimensional point sets, and when the input point set does not fully meet the conditions, the minimum circumscribed circle obtained by this function may not be unique. . Article source address: https://www.yii666.com/blog/496427.html

Code practice

import cv2
import numpy as np

#Write a method to display the image. After displaying, press any key to continue the code.
def cv_show(title,img):
    cv2.imshow(title,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    return

img = cv2.imread('contour.png')

def draw_contour(img,color,width):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#Convert grayscale image
    ret, binary = cv2.threshold(gray,10,255,cv2.THRESH_BINARY)#Convert to binary image
    contour,hierarchy = cv2.findContours(binary, cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)#Find contours, all stored in contour
    copy = img.copy()
    result = cv2.drawContours(copy,contour[:],-1,color,width)
    cv_show('resoult',resoult)
    return contour

contour = draw_contour(img,(0,255,255),2)
print(np.array(contour).shape)

(x,y),radius = cv2.minEnclosingCircle(contour[0])
center = (int(x),int(y))
radius = int(radius)
img_circle = cv2.circle(img.copy(),center,radius,(25,0,255),2)
cv_show('img',img_circle)

Use the cv2.minEnclosingCircle() function to calculate the minimum circumscribed circle of the contour contour[0] and return the center coordinates (x, y) and radius. This method can only input one boundary.
Convert the circle center coordinates (x, y) to integer coordinates (int(x), int(y)) and cast the radius to an integer.
Use the cv2.circle() function to draw a circular area on the copied version of the original image img.copy(). The center coordinates are (int(x), int(y)), the radius is radius, and the color is (25, 0 , 255) (BGR format), line width is 2.
Call the cv_show() function to display the drawn image.

result:

OpenCV(10):Contourapproximation-polygonfitting,boundingrectangleandboundingcircleOpenCV(10):Contourapproximation-polygonfitting,boundingrectangleandboundingcircle

Note that cv2.circle() and cv2.rectangle() will change the input object, so copy it.

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. OpenCV skill treeHomepageOverview 21092 people are learning the system

syntaxbug.com © 2021 All Rights Reserved.