日照市东港区创新电子技术中心
ndfweb.cn

OpenCV+python轮廓计算


2021-08-17 23:03:17 (3636)


1.3轮廓的近似方法
之前提到轮廓是一个形状具有相同灰度值的边界,它会存储形状边界上所有的(x,y)坐标。实际上我们不需要所有的点,当需要直线时,找到两个端点即可。cv2.CHAIN_APPROX_SIMPLE可以实现。它会将轮廓上的冗余点去掉,压缩轮廓,从而节省内存开支。
下面用矩阵来演示,在轮廓列表中的每一个坐标上画一个蓝色圆圈。第一个显示使用cv2.CHAIN_APPROX_NONE的效果,一共734个点,第二个图是使用cv2.CHAIN_APPROX_SIMPLE的结果,只有4个点。

2.轮廓特征
2.1矩
图像的矩可以帮助我们计算图像的质心,面积等。
函数cv2.moments()会将计算得到的矩以一个字典的形式返回。

import numpy as npimport cv2img = cv2.imread('1024.jpg',0)ret,thresh = cv2.threshold(img,127,255,0)image,contours,hierarchy=cv2.findContours(thresh,1,2)cnt=contours[0]M=cv2.moments(cnt)print(M)

根据这些矩的值,我们可以计算出对象的重心:

cx=int(M['m10']/M['m00'])cy=int(M['m01']/M['m00'])

2.2轮廓面积
可以使用函数cv2.contourArea()计算得到,也可以用矩(0阶矩),M['m00']。

area=cv2.contourArea(cnt)

2.3轮廓周长
也被称为弧长。可以使用函数cv2.arcLength()计算得到。这个函数的第二参数可以用来指定对象的形状是闭合的(True),还是打开的(一条曲线)。

perimeter = cv2.arcLength(cnt,True)

2.4轮廓近似
将轮廓形状近似到另外一种由更少点组成的轮廓形状,新轮廓的点的数目由我们设定的准确度来决定,使用的Douglas-Peucker算法,可以自己Google。
假设我们要在一幅图像中查找一个矩形,但是由于图像的种种原因我们不能得到一个完美的矩形,而是一个“坏形状”,现在就可以使用这个函数来近似这个形状,第二个参数是epsilon,它是从原始轮廓到近似轮廓的最大距离,它是一个准确度参数。

epsilon=0.1*cv2.arcLength(cnt,True)approx = cv2.approxPolyDP(cnt,epsilon,True)

2.5凸包
凸包与轮廓近似相似,但不同,虽然有些情况下它们给出的结果是一样的。函数cv2.convexHull()可以用来检测一个曲线是否具有凸性缺陷,并能纠正缺陷。一般来说,凸性曲线总是凸出来的,至少是平的。如果有地方凹进去了就被叫做凸性缺陷。例如下图中的手,红色曲线显示了手的凸包,凸性缺陷被双箭头标出来了。

hull = cv2.convexHull(points,hull,clockwise,returnPoints)

参数:

  • points我们要传入的轮廓

  • hull输出,通常不需要

  • clockwise方向标志,如果设置为True,输出的凸包是顺时针方向的,否则为逆时针方向。

  • returnPoints默认值为True。它会返回凸包上点的坐标,如果设置为False,就会返回与凸包点对应的轮廓上的点。
    要获得上图的凸包,可以用下面命令:

hull=cv2.convexHull(cnt)

但是如果你想获得凸性缺陷,需要把returnPoints设置为False。以上面矩形为例,首先我们找到他的轮廓从cnt。现在把returnPoints设置为True查找凸包,得到的就是矩形的四个角点。把returnPoints设置为False,得到的是轮廓点的索引。
2.6凸性检测
函数cv2.isContourConvex()可以检测一个曲线是不是凸的。它只能返回True或者False。

k=cv2.isContourConvex(cnt)

2.7边界矩形
直边界矩形,一个直矩形,没有旋转。不会考虑对象是否旋转。所以边界矩形的面积不是最小的。可以使用函数cv2.boundingRect()查找得到

#(x,y)为矩形左上角的坐标,(w,h)是矩形的宽和高x,y,w,h=cv2.boundingRect(cnt)img=cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

旋转的边界矩形,这个边界矩形是面积最小的,因为它考虑了对象的旋转。用函数cv2.minAreaRect()。返回的是一个Box2D结构,其中包含矩形最上角角点坐标(x,y)矩形的宽和高(w,h)以及旋转角度。但是要绘制这个矩形需要矩形的4个角点,可以通过函数cv2.boxPoints()获得。
其中绿色的为直矩形,红色为旋转矩形。

2.8最小外接圆
函数cv2.minEnclosingCircle()可以帮我们找到一个对象的外接圆。它是所有能够包括对象的圆中面积最小的一个。

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

2.9椭圆拟合
使用函数cv2.ellipse(),返回值其实就是旋转边界矩形的内切圆。

ellipse = cv2.fitEllipse(cnt)img = cv2.ellipse(img,ellipse,(0,255,0),2)

2.10直线拟合
可以根据一组点拟合出一条直线,同样我们也可以为图像中的白色点拟合出一条直线。

rows,cols = img.shape[:2]
[vx,vy,x,y]=cv2.fitLine(cnt,cv2.DIST_L2,0,0.01,0.01)
lefty=int((x*vy/vx)+y)
righty=int(((cols-x)*vy/vx)+y)img = cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)


了解更多请访问:http://www.ndfweb.cn/news-895.html
  NDF俱乐部
  国际域名注册
  建站咨询
合作伙伴:万网 | 新网 | 新网互联 NDF网站建设淘宝店 | 实用工具 | 外貿網站建設 | 联系我们
鲁公网安备 37110202000336号 Sitemap - RSSRSS订阅