(17) Outline

1. Contour extraction

Use threshold segmentation or edge extraction to obtain binary images; objects need to be white and backgrounds must be black

import numpy as np
import cv2 as cv
im = cv.imread('test.jpg')
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

2. Display the outline

Show all contours: cv.drawContours(img, contours, -1, (0,255,0), 3)

Draw a separate 4th contour: cv.drawContours(img, contours, 3, (0,255,0), 3)

Useful practice: cnt = contours[4]

          cv.drawContours(img, [cnt], 0, (0,255,0), 3)

Contour approximation method

cv.CHAIN_APPROX_NONE: save all contour points

cv.CHAIN_APPROX_SIMPLE: save the start and end points of the line

 3. Contour features

(1)  Moment: find the center

import numpy as np
import cv2 as cv
img = cv.imread('star.jpg',0)
ret,thresh = cv.threshold(img,127,255,0)
im2,contours,hierarchy = cv.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])

(2)  Area: M['m00']

area = cv.contourArea(cnt)

 The contour points are: A(1,1), B(1,2), C(2,2), D(2,1). First select the points A and B, and the cross product of the vectors OA and OB can be obtained Triangle OAB area (with direction), note: the vector cross product has a direction, and the modulus of the cross product is the area of ​​the parallelogram. Then select two points B and C to calculate the area of ​​OBC (with direction), the difference of the area of ​​triangle OAB and OBC with direction is the area of ​​triangle ABC.

(A,B):1*2-1*1=1

(B,C):1*2-2*2=-2

(C,D):2*1-2*2=-2

(D,A):2*1-1*1=1

S=(1-2-2+1)/2

(3)  Contour perimeter

perimeter = cv.arcLength(cnt,True)

(4)  Contour approximation

epsilon = 0.1*cv.arcLength(cnt,True)
approx = cv.approxPolyDP(cnt,epsilon,True)

 (5)  Check convexity: if it is convex, return true, otherwise return false

k = cv.isContourConvex(cnt)

(6)  Border rectangle

直线边框矩形:(x,y)是矩形的左上角点,(w,h)是举行的宽和高
x,y,w,h = cv.boundingRect(cnt)
cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
旋转矩形:
rect = cv.minAreaRect(cnt)
box = cv.boxPoints(rect)   #( center (x,y), (width, height), angle of rotation )
box = np.int0(box)
cv.drawContours(img,[box],0,(0,0,255),2)

(7)  Minimum circumscribed circle

(x,y),radius = cv.minEnclosingCircle(cnt)   
center = (int(x),int(y))
radius = int(radius)
cv.circle(img,center,radius,(0,255,0),2)

(8)  Ellipse fitting

ellipse = cv.fitEllipse(cnt)
cv.ellipse(img,ellipse,(0,255,0),2)

(9)  Straight line fitting

rows,cols = img.shape[:2]
[vx,vy,x,y] = cv.fitLine(cnt, cv.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)

 3. Contour characteristics

(1) Aspect ratio

x,y,w,h = cv.boundingRect(cnt)
aspect_ratio = float(w)/h

(2)  Elongation

area = cv.contourArea(cnt)                                      
x,y,w,h = cv.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area

(3)  Hardness

area = cv.contourArea(cnt)
hull = cv.convexHull(cnt)
hull_area = cv.contourArea(hull)
solidity = float(area)/hull_area

(4)  Equivalent diameter

area = cv.contourArea(cnt)                                          
equi_diameter = np.sqrt(4*area/np.pi)

(5)  Direction

(x,y),(MA,ma),angle = cv.fitEllipse(cnt)

(6)  Maximum value, minimum value and position

min_val, max_val, min_loc, max_loc = cv.minMaxLoc(imgray,mask = mask)

(7)  Average color and brightness

mean_val = cv.mean(im,mask = mask)

4, convex hull

(1)   Convex defect

The convex hull is very similar to the polygon approximation, except that it is the outermost "convex" polygon of the object: the straight line connecting any two points in the set A is inside A, then the set A is called convex. As shown in the figure below, the red part is the convex hull of the palm, and the double arrow part represents Convexity Defects. Convexity defects are often used for gesture recognition, etc.:

# 1.先找到轮廓 
img = cv2.imread('convex.jpg', 0) 
_, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) 
image, contours, hierarchy = cv2.findContours(thresh, 3, 2)
 cnt = contours[0] 
# 2.寻找凸包,得到凸包的角点 
hull = cv2.convexHull(cnt) 
# 3.绘制凸包
 image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) 
cv2.polylines(image, [hull], True, (0, 255, 0), 2)

 

(2)  Point to contour distance

The cv2.pointPolygonTest() function calculates the shortest distance from the point to the contour (that is, the vertical line), also known as the polygon test:

dist = cv2.pointPolygonTest(cnt, (100, 100), True)  # -3.53

When parameter 3 is True, it indicates the calculated distance value: the value of the point outside the contour is negative, the value of the point on the contour is 0, and the value of the point inside the contour is positive; when the parameter 3 is False, only -1/0/1 is returned to indicate The position of the point relative to the contour, the distance is not calculated.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324107359&siteId=291194637