python-opencv学习记录--图像轮廓

图像轮廓

语法

cv2.findContours(img.mode,method)

mode:轮廓检索模式

  • RETR_EXTERNAL :只检索最外面的轮廓

  • RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中

  • RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界

  • RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次 (最常用)

method:轮廓逼近方法

  • CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)
  • CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-asppnV3c-1611470829946)(E:\写作\markdown\深度学习\资料\资料\02-07notebook课件\图像操作\chain.png)]

为了更高的准确率,使用二值图像

代码案例

二值处理代码

img = cv2.imread('contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('thresh',thresh)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

在这里插入图片描述

扫描二维码关注公众号,回复: 13495219 查看本文章

绘制轮廓

def drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None):

image
传入的图像,在这张图上画,注意,drawContours本身会直接修改image,不需要返回值,所以在传入图片前先备份一下原图,一般用:img = image * 1,这里image是np.array,乘一相当于复制了一份,注意:如果img = image这样直接赋值,是没有用的,修改img照样会修改image,这是因为深拷贝与浅拷贝的不同,这里image * 1是一个小技巧,但正规的深拷贝应该用copy这个函数,(还得导包,所以偷个懒,直接乘 1)

contours:
这个是一个列表,注意是一个列表是一个列表是一个列表,可以直接将刚才用findContours找出来的contours给他,也可以是自己给出的一组坐标信息。

contourIdx:画的轮廓下标, -1表示画出全部的轮廓。比如刚才找出来的contours,在将-1给到contourIdx,就会把所有轮廓画出来。

color:画线的颜色:例如(0,0,255)

thickness: 画线的粗细,-1则为填充

#传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
# 注意需要copy,要不原图会变
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv2.imshow('res',res)

在这里插入图片描述

轮廓特征

#轮廓面积
cnt=contours[0]
print(cv2.contourArea(cnt))
#8500.5
#轮廓周长,True表示闭合的
print(cv2.arcLength(cnt,True))
#437.9482651948929

轮廓近似

在这里插入图片描述

原图

在这里插入图片描述

img = cv2.imread('contours2.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)
cnt = contours[0]
draw_img = img.copy()
res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
cv2.imshow('res',res)

轮廓图

在这里插入图片描述

epsilon = 0.1*cv2.arcLength(cnt,True) #比例系数越小,近似精度越高
approx = cv2.approxPolyDP(cnt,epsilon,True)
draw_img = img.copy()
res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
cv2.imshow('res',res)

轮廓近似图

在这里插入图片描述

边界图形

矩形

img = cv2.imread('contours.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)
cnt = contours[2]
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('img',img)

效果

在这里插入图片描述

轮廓面积与边界矩形比

area = cv2.contourArea(cnt)
x, y, w, h = cv2.boundingRect(cnt)
rect_area = w * h
extent = float(area) / rect_area
print ('轮廓面积与边界矩形比',extent)
#轮廓面积与边界矩形比 0.743223766795295

外接圆

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

效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45619006/article/details/113090583