opencv图像轮廓
Posted puheng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv图像轮廓相关的知识,希望对你有一定的参考价值。
最小外接圆
函数cv2.minEnclosingCircle() 可以帮我们找到一个对象的外切圆。它是所有能够包括对象的圆中面积最小的一个。
案例:现有下面这样一张图片,要求将图片中心的花朵标记出来。
代码:
import numpy as np import cv2 as cv img=cv.imread("image.jpg",0) #为了显示方便,这里将图片进行缩放 x,y=img.shape img=cv.resize(img,(y//2,x//2)) #将图片二值化,由于前景物体是黑色的,因此在二值化时采用cv.THRESH_TOZERO_INV这种方式 ret,thresh=cv.threshold(img,127,255,cv.THRESH_TOZERO_INV) #寻找图片中的轮廓,mode=cv.RETR_EXTERNAL,这是为了寻找最外层的轮廓 im,contour,hierarchy=cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE) #cv.minEnclosingCircle函数的参数要求是ndarray类型,因此这里将找到的 # 轮廓中的所有的点存放在一个列表中,然后使用这个列表创建数组 point_list=[] for i in contour: for j in i: point_list.append(j[0]) point_array=np.array(point_list) #使用最小外接圆函数,返回值为这个圆的圆心坐标和圆半径长度 (x,y),radius=cv.minEnclosingCircle(point_array) #图片上的坐标均为整数,圆的半径也要求是整数,因此将它们强制转换为int类型 center=(int(x),int(y)) color=cv.cvtColor(img,cv.COLOR_GRAY2BGR) color=cv.circle(color,center,radius=int(radius),color=(0,0,255),thickness=2) #显示图片 cv.imshow("color",color) cv.waitKey(0) cv.destroyAllWindows()
程序结果:
凸包
凸包与轮廓近似相似,但不同,虽然有些情况下它们给出的结果是一样的。函数cv2.convexHull() 可以用来检测一个曲线是否具有凸性缺陷,并能纠正缺陷。一般来说,凸性曲线总是凸出来的,至少是平的。在opencv中使用函数cv.convexhull来寻找轮廓的凸包,该函数的定义为:
hull=cv.convexHull( points[, hull[, clockwise[, returnPoints]]])
这个函数的参数如下:
Points:我们需要传入的轮廓
Hull:输出,通常不需要
clockwise : 取向标志,如果为True,凸包的方向是顺时针方向,否则为逆时针方向;
returnPoints : 默认为True. 它会返回凸包上点的坐标。如果设置为False,就会返回与凸包点对应的轮廓上的点。
还是上面的这副图片,我们对上面的代码稍加修改,可以得到凸包的形状,代码如下:
import numpy as np import cv2 as cv img=cv.imread("image.jpg",0) #为了显示方便,这里将图片进行缩放 x,y=img.shape img=cv.resize(img,(y//2,x//2)) #将图片二值化,由于前景物体是黑色的,因此在二值化时采用cv.THRESH_TOZERO_INV这种方式 ret,thresh=cv.threshold(img,127,255,cv.THRESH_TOZERO_INV) #寻找图片中的轮廓,mode=cv.RETR_EXTERNAL,这是为了寻找最外层的轮廓 im,contour,hierarchy=cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE) #cv.minEnclosingCircle函数的参数要求是ndarray类型,因此这里将找到的 # 轮廓中的所有的点存放在一个列表中,然后使用这个列表创建数组 point_list=[] for i in contour: for j in i: point_list.append(j[0]) point_array=np.array(point_list) #寻找凸包,返回值是凸包上的点 hull=cv.convexHull(point_array,returnPoints=True) color=cv.cvtColor(img,cv.COLOR_GRAY2BGR) #将凸包绘制出来,需要注意的是:这里需要将凸包上点的坐标写成一个 #列表传入函数cv.ploylines,否则绘制出来的只是凸包上的一系列点 color=cv.polylines(color,[hull],True,(0,0,255),2) #显示图片 cv.imshow("color",color) cv.waitKey(0) cv.destroyAllWindows()
程序运行结果为:
以上是关于opencv图像轮廓的主要内容,如果未能解决你的问题,请参考以下文章
youcans 的 OpenCV 例程200篇194.寻找图像轮廓(cv.findContours)