OpenCV学习笔记(13)——轮廓特征

摘要:
查找轮廓的不同特征,例如面积,周长,重心,边界等1.矩图像的矩可以帮助我们计算图像的质心,面积等。
  • 查找轮廓的不同特征,例如面积,周长,重心,边界等

1.矩

图像的矩可以帮助我们计算图像的质心,面积等。

函数cv2.momen()会将计算得到的矩以一个字典的形式返回,

我们的测试图像如下:

OpenCV学习笔记(13)——轮廓特征第1张

例程如下:

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('8.jpg',0)
ret,thresh = cv2.threshold(img,127,255,0)
im,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
M = cv2.moments(cnt)
print(M)
#会返回一个字典


#计算重心
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
  

2.轮廓面积

轮廓面积可以用cv2.contourArea()计算得到,也可以使用矩,M['m00‘]

print(cv2.contourArea(cnt))

3.轮廓周长

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

print(cv2.arcLength(cnt,True))#试了一下,如果强行赋予False,得到的周长会比用True短一些

4.轮廓近似

将轮廓形状近似到另外一种有更少点组成的轮廓形状,新轮廓的点的数目由我们设定的准确度来决定。使用的Douglas-Peucker算法在此不细讲了。

我们假设要在下图中找一个矩形

OpenCV学习笔记(13)——轮廓特征第2张

然而这个图凹凸不平,直接提取轮廓无法提取到一个完美的矩形。因此我们就可以使用这个函数来近似这个形状了。这个函数的第二个参数epsilon,是从原始轮廓到近似轮廓的最大距离,是一个准确度参数。因此对它的调整对最后的结果很重要。

例程如下:

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
im = cv2.imread('9.png')
img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#用这个方式转换的原因是最后输出时希望能看到彩色的的轮廓图
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)#这个和上面的True都是表示是闭曲线
#approx得到的仅仅是几个点集,需要将其连接起来

# cv2.drawContours(im,approx,-1,(0,0,255),3) 该函数只能画出几个点
cv2.polylines(im, [approx], True, (0, 255, 0), 2)#需要用这个函数才能画出轮廓,中间的True也是指示是否为闭曲线的

cv2.imshow('img',im)
cv2.waitKey(0)

最终效果如下:

指定为10%时:OpenCV学习笔记(13)——轮廓特征第3张 指定为1%时:OpenCV学习笔记(13)——轮廓特征第4张

5.凸包

凸包与轮廓近似相似,有些时候他们给出的结果是一样的,但是本质上讲他们是不同的。函数cv2,convexHull()可以用来检测一个曲线是否具有凸性缺陷,并能纠正缺陷。一般来说,凸性曲线总是凸出来的,至少是频带。如果有地方凹进去了就被叫做凸性缺陷。如下图所示:

OpenCV学习笔记(13)——轮廓特征第5张

红色表示了他的凸包,而凸性缺陷被双箭头标出来了。

对于参数还有需要说明的地方:

hull = cv2.convexHull(points[],hull[],clockwise,retirnPoints)

  • point是我们要传入的轮廓
  • hull 输出,通常不需要
  • clockwise 方向标志,如果设置为True,输出的凸包是顺时针方向的,否则为逆时针方向
  • returnPoints 默认为True。它会返回凸包上点的坐标。如果设置为False,则会返回凸包点对应于原轮廓上的点坐标

实际操作中,不如需要获得上面的凸包,只需要:

hull = cv2.convexHull(cnt)

即可。但是如果你想获得凸性缺陷,需要把returnPoints设置为False。以上面的矩形为例,在获取他的轮廓cnt后,先把returnPoin设置为True查找凸包,会得到矩形的四个角点坐标。再将returnPoints设为False,将得到轮廓点的索引,即前面的四个坐标在原轮廓中的序列位置。

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
im = cv2.imread('9.png')
img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#用这个方式转换的原因是最后输出时希望能看到彩色的的轮廓图
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
hull = cv2.convexHull(cnt,returnPoints=True)
print(hull)
# cv2.drawContours(im,hull,-1,(0,0,255),3) #该函数只能画出几个点
cv2.polylines(im, [hull], True, (0, 255, 0), 2)#需要用这个函数才能画出轮廓,中间的True也是指示是否为闭曲线的

cv2.imshow('img',im)
cv2.waitKey(0)

设置为True时得到的结果是

[[[161 126]]
[[ 8 126]]
[[ 8 10]]
[[161 10]]]

是矩形四个角点的坐标

设置为False后

[[113]
[ 60]
[ 0]
[126]]  

表示的是上面四个点在cnt中的索引号,且不能画出凸包了

6.凸性检测

就是检测一个曲线是不是凸的,只能返回True和False

k = cv2.isContourConvex(cnt)

7.边界矩形

有两类边界矩形。

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

x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

返回值中,(x,y)是矩阵左上角的坐标,(w,h)是举行的宽和高。

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

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
im = cv2.imread('10.png')
img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#用这个方式转换的原因是最后输出时希望能看到彩色的的轮廓图
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
#直边界矩形
x,y,w,h = cv2.boundingRect(cnt)
im = cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
#旋转边界矩形
s = cv2.minAreaRect(cnt)
a = cv2.boxPoints(s)
a = np.int0(a)#必须转换a的类型才能用polylines中画出,我也不知道为啥


cv2.polylines(im,[a],True,(0,0,255),3)
cv2.imshow('img',im)
cv2.waitKey(0)

最终效果如下:

OpenCV学习笔记(13)——轮廓特征第6张

8.最小外接圆

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

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
im = cv2.imread('10.png')
img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#用这个方式转换的原因是最后输出时希望能看到彩色的的轮廓图
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
im = cv2.circle(im,center,radius,(0,255,0),2)
# cv2.polylines(im,[a],True,(0,0,255),3)

cv2.imshow('img',im)
cv2.waitKey(0)

OpenCV学习笔记(13)——轮廓特征第7张

9.椭圆拟合

使用cv2.fitEllipse()找椭圆,返回值就是旋转边界矩形的内切圆。用cv2.ellipse()画椭圆

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
im = cv2.imread('10.png')
img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#用这个方式转换的原因是最后输出时希望能看到彩色的的轮廓图
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
ellise = cv2.fitEllipse(cnt)
im = cv2.ellipse(im,ellise,(0,255,0),2)
cv2.imshow('img',im)
cv2.waitKey(0)

OpenCV学习笔记(13)——轮廓特征第8张

10.直线拟合

类似ゆ根据一组点拟合出一条直线,也可以根据 图像中的白色点拟合出一条直线,不过过程较为复杂

书上的例程如下:

# -*- coding:utf-8 -*-

import numpy as np
import cv2
from matplotlib import pyplot as plt
im = cv2.imread('10.png')
img = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)#用这个方式转换的原因是最后输出时希望能看到彩色的的轮廓图
ret,thresh = cv2.threshold(img,127,255,0)
img,contours,hierarchy = cv2.findContours(thresh,1,2)
cnt = contours[0]
rows,cols = im.shape[:2]
#cv2.fitLine(points, distType, param, reps, aeps[, line ]) → line
#points – Input vector of 2D or 3D points, stored in std::vector<> or Mat.
#line – Output line parameters. In case of 2D fitting, it should be a vector of
#4 elements (likeVec4f) - (vx, vy, x0, y0), where (vx, vy) is a normalized
#vector collinear to the line and (x0, y0) is a point on the line. In case of
#3D fitting, it should be a vector of 6 elements (like Vec6f) - (vx, vy, vz,
#x0, y0, z0), where (vx, vy, vz) is a normalized vector collinear to the line
#and (x0, y0, z0) is a point on the line.
#distType – Distance used by the M-estimator
#distType=CV_DIST_L2
#ρ(r) = r2 /2 (the simplest and the fastest least-squares method)
#param – Numerical parameter ( C ) for some types of distances. If it is 0, an optimal value
#is chosen.
#reps – Sufficient accuracy for the radius (distance between the coordinate origin and the
#line).
#aeps – Sufficient accuracy for the angle. 0.01 would be a good default value for reps and
#aeps.
[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)
im = cv2.line(im,(cols-1,righty),(0,lefty),(0,255,0),2)
cv2.imshow('img',im)
cv2.waitKey(0)
OpenCV学习笔记(13)——轮廓特征第9张

免责声明:文章转载自《OpenCV学习笔记(13)——轮廓特征》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇三层架构和MVC的区别京东商城总架构师、基础平台负责人刘海锋:京东双11创新技术实践下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

闵可夫斯基和

闵可夫斯基和Tags:高级算法 一、概述 学习此内容需一定计算几何基础,出门右拐:https://www.cnblogs.com/xzyxzy/p/10033130.html官方定义:两个图形(A,B)的闵可夫斯基和(C={a+b|ain A,bin B})通俗一点:从原点向图形A内部的每一个点做向量,将图形(B)沿每个向量移动,所有的最终位置的并便是闵...

「转」python数字图像处理(18):高级形态学处理

python数字图像处理(18):高级形态学处理  形态学处理,除了最基本的膨胀、腐蚀、开/闭运算、黑/白帽处理外,还有一些更高级的运用,如凸包,连通区域标记,删除小块区域等。 1、凸包 凸包是指一个凸多边形,这个凸多边形将图片中所有的白色像素点都包含在内。 函数为: skimage.morphology.convex_hull_image(image)...

OpenCV+python轮廓

OpenCV中的轮廓 1.1什么是轮廓轮廓可以简单认为成连续的点(连着边界)连在一起的曲线,具有相同的颜色或者灰度。轮廓在形状分析和物体的检测和识别中很有用。 为了准确,要使用二值化图像。需要进行阀值化处理或者Canny边界检测。 查找轮廓的函数会修改原始图像。如果之后想继续使用原始图像,应该将原始图像储存到其他变量中。 在OpenCV中,查找轮廓...

凸包算法

包含点s集合中所有点的最小凸多边形的名字叫凸包 Graham扫描算法: 1.从y轴最低点作为起始点p0 2.从p0开始极坐标扫描,依次遍历图中所有的点,按极坐标角度大小,逆时针方向遍历 3.如果新遍历的点能产生一个左旋转,则将该点添加到凸包中,否则舍去 实现流程 1.彩色图像转灰度图像 2.灰度图像转二值图像 3.通过发现轮廓得到候选点 4.计算凸包 5...

Graham 扫描法找凸包(convexHull)

凸包定义 通俗的话来解释凸包:给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有的点  Graham扫描法 由最底的一点 (p_1) 开始(如果有多个这样的点,那么选择最左边的),计算它跟其他各点的连线和 x 轴正向的角度,按小至大将这些点排序,称它们的对应点为 (p_{2},p_{3},...,p_{n})。这里的时...

CAGD: 第十二章 B样条曲面

    第十二章 B样条曲面 B样条曲面在CAD/CAM中具有非常重要的地位,它可由B样条曲线通过直积推广而得,正如由Bézier曲线经由直积推广而得Bézier曲面一样。本章主要讨论B样条曲面的性质及其相关的配套技术。 12.1 B样条曲面的定义及性质 给定三维空间个点,参数和的节点矢量、,参数曲面: (12.1.1) 称为次B样条曲面。式中称为曲面的...