理论内容
什么是图像轮廓?
具有相同颜色或强度的连续点的曲线。
轮廓的作用?
(1)可以用于图形的分析
(2)物体识别与检测
注意点:
(1)为了检测的准确性,需要先对图像进行二值化或Canny操作
(2)画轮廓时会修改输入的图像(在需要保留原始图像的情况下,需要进行深copy)
轮廓查找API:
findContours(img,mode,approximaionMode ……)
img:需要进行轮廓查找的图像
mode:RETR_EXTERNAL=0 只检测外轮廓 ;RETR_LIST=1 检测的轮廓不建立等级关系;RETR_CCOMP=2 每层最多两级 ; RETR_TREE=3 按树形存储轮廓
EXTERNAL:只检测外轮廓
LIST:从里到外,从右到左
CCOMP:从里到外,但是每层最多有两级
TREE:从外到里,从右到左
ApproximaionMode:CHAIN_APPROX_NONE 保留所有轮廓上的点 ;CHAIN_APPROX_SIMPLE 只保存角点
返回值 contours和hierarchy
contours:查找到的所有轮廓的列表
hierarchy:层级
绘制轮廓API:
drawContours(img,contours,contourIdx,color,thickness……)
img:需要进行轮廓绘制的图像
contours:轮廓的坐标点
contourIdx:轮廓顺序号,可以通过这个参数显示具体需要的轮廓(从0开始。-1绘制所有轮廓)
color:轮廓显示的颜色 (0,0,255)
thicness:线宽 (-1是全部填充)
轮廓的面积和周长:
可以通过面积和周长去舍去一些细小的,我们不需要的轮廓。
轮廓面积API
contourArea(contour)
contour:就是在查找轮廓中contours获得的轮廓坐标信息
轮廓周长API
arcLength(curve,closed)
curve:就是在查找轮廓中contours获得的轮廓坐标信息
closed:轮廓是否闭合,如果是闭合的就是True,不是闭合的就是False
多边形逼近与凸包
左边为逼近,右边为凸包
多边形逼近API
approxPolyDP(curve,epsilon,closed)
curve:就是在查找轮廓中contours获得的轮廓坐标信息
epsilon:精度
closed:是否为闭合 True False
多边形凸包API
convexHull(points,clockwise,……)
points:就是在查找轮廓中contours获得的轮廓坐标信息
clockwise:顺时针绘制
外接矩阵
最小和最大外接矩阵(最小外接矩阵可以看出图像旋转的角度)
最小外接矩阵API
minAreaRect(points)
points:就是在查找轮廓中contours获得的轮廓坐标信息
返回值:RotatedRect
RotatedRect:有 x,y,width,heigh,angle
最大外接矩阵API
boundingRect(array)
array:就是在查找轮廓中contours获得的轮廓坐标信息
返回值:Rect
Rect:有 x,y,width,heigh
实战内容
轮廓查找:
import cv2
import numpy as np
img = cv2.imread('E:\\pycharm\\PycharmFile\\opencv\\MM\\contour.png')
print(img.shape)
# 转变为单通道
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print(gray.shape)
# 二值化
ret, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
print(binary.shape)
# 轮廓查找
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
print(contours)
cv2.imshow('img', img)
cv2.imshow('binary', binary)
cv2.waitKey(0)
三通道的图片需要先变成单通道后才进行二值化,之后进行轮廓查找。
绘制轮廓:
#轮廓绘制
cv2.drawContours(img,contours,-1,(0,0,255),6)
contours就是刚刚查找轮廓获得的坐标。
计算面积
#计算面积
area=cv2.contourArea(contours[0])
print("area=%d"%(area))
contours[0]很重要,要确定是选择的那个轮廓求面积
计算周长
#计算周长
len=cv2.arcLength(contours[0],True)
print("len=%d"%(len))
多边形逼近
def drawshape(src, point):
i = 0
while i < len(point):
if (i == len(point) - 1):
x, y = point[i][0]
x1, y1 = point[0][0]
cv2.line(src, (x, y), (x1, y1), (0, 0, 255), 3)
else:
x, y = point[i][0]
x1, y1 = point[i + 1][0]
cv2.line(src, (x, y), (x1, y1), (0, 0, 255), 3)
i = i + 1
# 多边形逼近
e = 40
approx = cv2.approxPolyDP(contours[0], e, True)
# print(approx)
# 绘制逼近图
drawshape(img, approx)
多边形凸包
# 多边形凸包
hull = cv2.convexHull(contours[0])
# 绘制凸包图
drawshape(img, hull)
最小外接矩阵
#最小外接矩阵
r=cv2.minAreaRect(contours[1]) #这个返回值中含有角度信息
box=cv2.boxPoints(r) #去除r中的角度信息
box=np.int0(box) #由于box是float 使其变成int型
cv2.drawContours(img,[box],0,(0,0,255),2)
最大外接矩阵
#最大外接矩阵
x,y,w,h=cv2.boundingRect(contours[1])
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)