OpenCV note finishing [image outline]

Although the edge i detection can detect the edge, but the edge is discontinuous. The image outline can connect the edges to form a whole, which includes information such as the size, position, and direction of the target.

1. Find contours: findContours()

格式:contours, hierarchy = findCountours ( image, mode, method )

  • Return value contours: the found contour
  1. Contours includes several contours[i], each contours[i] represents a contour, representing a numpy.ndarray type.
  2. Get the total number of contours: len(contours)
  3. Get the total number of pixels of the current contour: len(contours[i])
  • Return value hierarchy: organizational hierarchy.
  1. Express the positional nesting relationship between contours.
  2. Returns 4 index numbers [NEXT, BEFORE, FIRST, ROOT] and defaults to -1 when there is no nesting relationship.
  3. This number is determined by the extraction method in the parameter mode.
  • Parameter image: The input image must be an 8-bit single-channel binary image, and must be a white object with a black background.
  • Parameter mode: determines the extraction method of the contour:
  1. cv2.RETR_EXTERNAL only detects outer contours.
  2. cv2.RETR_LIST does not establish a hierarchical relationship for the retrieved contours.
  3. cv2.RETR_CCOMP only builds 2 level contours.
  4. cv2.RETR_TREE builds a hierarchical tree.
  • Parameter method: determines how to express the contour:
  1. cv2.CHAIN_APPROX_NONE: Keep all points, adjacent to no more than 1 pixel.
  2. cv2.CHAIN_APPROX_SIMPLE: Only keep the end coordinates in the direction.
    insert image description here

2. Draw contours: drawContours()

格式:image = drawContours (image, contours, contourIdx, color, thickness)

  • Return value image: the result image, it can also be written in the form of no return value image.
  • Parameter contours: the contour to be drawn.
  • Parameter contourIdx: The index of the contour to be drawn.
  • Parameter color: The color of the drawn line.
  • Parameter thickness: The width of the drawn line.

Above code:

import cv2
import numpy as np
import matplotlib.pyplot as plt

o = cv2.imread('contours.bmp')  

plt.figure(figsize=(10,10),dpi=100)
plt.subplot(1,4,1)
plt.title("O")
plt.imshow(o),plt.axis('off')

# 转换为8位灰度图
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)  

# 二值化图像
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  

# 提取轮廓
contours, hierarchy = cv2.findContours(binary,
                                cv2.RETR_TREE, # 建立等级树
                      cv2.CHAIN_APPROX_SIMPLE) # 保留关键点
n=len(contours) # 获取轮廓个数
contoursImg=[] # 创建一个填充轮廓的元组

for i in range(n):
    temp=np.zeros(o.shape,np.uint8) # 创建一个所有元素为0的矩阵
    contoursImg.append(temp) # 添加画布
    contoursImg[i]=cv2.drawContours(contoursImg[i], # 传入画布
                                          contours, # 提取当前的轮廓集合
                                                 i, # 第i个轮廓
                                         (0,0,255), # RGB通道选择B
                                                 5) # 线条宽度5
    # 显示
    plt.subplot(1,4,i+2)
    plt.title("Contours"+str(i))
    plt.imshow(contoursImg[i]),plt.axis('off')

print(hierarchy) # 打印组织层次

Operation:
insert image description here
The hierarchical organization printed here: the two-dimensional array represented by the hierarchy, it is necessary to explain:
according to the order of [back profile Index, front profile Index, child profile Index, parent profile Index], first in the first array [1, -1,-1,-1] means that the back contour index of Contours0 is 1, the front contour does not exist, so it is -1, the child contour does not exist, so it is -1, and the parent contour does not exist, so it is -1.

3. Moment feature: moments

The easiest way to compare two images is to compare moment features. A simple understanding is to use a set of matrix data to represent the contour: size, position, angle, shape, etc. When the compared matrix data is exactly the same, the two contours are also the same.

  • Spatial moments: m00 represents the object area.
    Zero-order moment: m00
    First-order moment: m10, m01
    Second-order moment: m20, m11, m02
    Third-order moment: m30, m21, m12, m03

  • Central moment: used to solve the consistency comparison of two objects at different positions.
    Second-order central moments: mu20, mu11, mu02
    Third-order central moments: mu30, mu21, mu12, mu03

  • Normalized central moment: Solve the consistency comparison of two objects after translation and scaling.
    Second-order Hu moments: nu20, nu11, nu02
    Third-order Hu moments: nu30, nu21, nu12, nu03

Above code:

import cv2
import numpy as np

o = cv2.imread('moments.bmp') 
cv2.imshow("original",o) 
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)  
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  
contours, hierarchy = cv2.findContours(binary,
                                             cv2.RETR_LIST,
                                             cv2.CHAIN_APPROX_SIMPLE)  
n=len(contours)
contoursImg=[]
for i in range(n):
    temp=np.zeros(o.shape,np.uint8) 
    contoursImg.append(temp) 
    contoursImg[i]=cv2.drawContours(contoursImg[i],contours,i,255,3) # 绘制轮廓
    cv2.imshow("contours[" + str(i)+"]",contoursImg[i]) 
    
print("矩特征:")
for i in range(n):
    print("Contours"+str(i)+" :\n",cv2.moments(contours[i])) # 打印矩特征 
    
print("面积:")
for i in range(n):
    print("Contours"+str(i)+"area :%d" %cv2.moments(contours[i])['m00']) # 打印轮廓面积
    
cv2.waitKey()
cv2.destroyAllWindows()

result:
insert image description here

4. Get the area and perimeter of the contour: contourArea / arcLength

cv2.contoursArea(contours[0]) # Get the contour area
cv2.arcLength(contours[0],closed) # Get the contour perimeter (closed is True to indicate that the contour is closed, and vice versa.)

5. Shape matching: matchShapes

score = cv2.matchShapes(grayscale image 1, grayscale image 2, compare Hu way, 0)
returns a match score of type float.

Above code:

import cv2
from matplotlib import pyplot as plt

#--------------读取3幅原始图像--------------------
o1 = cv2.imread('cs1.bmp')
o2 = cv2.imread('cs2.bmp')
o3 = cv2.imread('cc.bmp') 

#--------------色彩空间转换-------------------- 
gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY) 
gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY) 
gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY) 

#-------------进行Hu矩匹配--------------------
ret0 = cv2.matchShapes(gray1,gray1,2,0)
ret1 = cv2.matchShapes(gray1,gray2,2,0)
ret2 = cv2.matchShapes(gray1,gray3,2,0)
#--------------打印差值--------------------
print("模板图像得分:",ret0)
print("相似度得分:",ret1)
print("相似度得分:",ret2)

plt.subplot(131)
plt.imshow(o1) 
plt.title("pattern")
 
plt.subplot(132) 
plt.imshow(o2)
plt.title("o2")
 
plt.subplot(133)
plt.imshow(o3)
plt.title("o3")

cv2.waitKey()
cv2.destroyAllWindows()

operation result:
insert image description here

6. Rectangular outer frame: boundingRect

x,y,w,h = cv2.boundingRect(contours[0])
Returns the x, y, x-direction length w, y-direction length h of the upper left corner of the outer frame of a contour.

Above code:

import cv2
import numpy as np

#---------------读取并显示原始图像------------------ 
o = cv2.imread('cc.bmp')  
cv2.imshow("original",o)

#---------------提取图像轮廓------------------ 
gray = cv2.cvtColor(o,cv2.COLOR_BGR2GRAY)  
ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)  
contours, hierarchy = cv2.findContours(binary,
                                       cv2.RETR_LIST,
                                       cv2.CHAIN_APPROX_SIMPLE) 

#---------------构造矩形边界------------------ 
x,y,w,h = cv2.boundingRect(contours[0])
rect = np.array([[[x, y]], [[x+w, y]], [[x+w, y+h]], [[x, y+h]]])
# 注意:这里的rect是一个list类型,应该以[]的方式出现
cv2.drawContours(o, [rect], -1, (255, 0,0), 2) 

#---------------显示矩形边界------------------
cv2.imshow("result",o)
cv2.waitKey()
cv2.destroyAllWindows()

Running results:
insert image description here
Summary: There are many ways to draw geometric contours, so I won’t list them one by one here. I will share them here today, hoping to help you. . .

Guess you like

Origin blog.csdn.net/qq_34699535/article/details/120477376