图像轮廓
1、轮廓绘制
直接使用自带函数cv2.findContours(img,mode,method)
# cv2.findContours(img,mode,method)
# mode:轮廓检索模式
# RETR_EXTERNAL:只检索最外面的轮廓
# RETR_LIST:检索所有的轮廓,并将其保存到一条链表中
# RETR_CCOMP:检索所有的轮廓,并将他猛组织为两层,顶层是各部分的外部边界,第二层是空洞的边界
# RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次
# method:轮廓逼近方法
# CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方式输出多边形(顶点的序列)
# CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分
import cv2
img = cv2.imread('image/similar.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# 绘制轮廓
# 传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
# 注意需要copy,要不然原图会变
draw_img = img.copy()
res = cv2.drawContours(draw_img,contours, -1, (0,0,255),1)
cv2.imshow('init',img)
cv2.imshow('res',res)
原图:
轮廓:
复杂图形:
2、轮廓特征
2.1面积和周长
cnt = contours[0]
# 面积
area = cv2.contourArea(cnt)
print(area)
# 周长,True表示闭合的
C = cv2.arcLength(cnt,True)
print(C)
2.2、轮廓近似
epsilon = 0.07*C
approx = cv2.approxPolyDP(cnt,epsilon, True)
draw_img = img.copy()
res1 = cv2.drawContours(draw_img,[approx], -1, (0,0,255),1)
cv2.imshow('res1',res1)
参数epsilon可自己设置,值越大,近似图形越简单
2.3、外接矩形
包括两种类型,直角矩形和旋转矩形。
直角矩形不考虑物体的旋转,所以他的面积不是最小的。
旋转矩形它也考虑了旋转,是用最小面积绘制的。
# 外接矩形
#直角矩形
x,y,w,h = cv2.boundingRect(cnt)
rect_img = img.copy()
cv2.rectangle(rect_img,(x,y),(x+w,y+h),(0,255,0),1)
cv2.imshow('rect1',rect_img)
#旋转矩形
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(rect_img,[box],0,(0,0,255),2)
cv2.imshow('rect2',rect_img)
rect_area = w*h
extent = float(area)/rect_area
print('轮廓面积与边界矩形比',extent)
直角矩形:
旋转矩形:
2.4、外接圆
#外接圆
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
circle_img = img.copy()
cv2.circle(circle_img,center,radius,(0,255,0),2)
cv2.imshow('circle',circle_img)