python轮廓函数 python的轮子

【python】opencv库中cv2.findContours()和cv2.drawContours()函数一.查找轮廓
cv2.findContours()
[image,] contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
轮廓检索方式:
轮廓近似方法:
二.绘制轮廓
cv2.drawContours()
cv2.drawContours(img, contours, -1, (0, 0, 255), 2)
OpenCV-Python教程:22.轮廓层级理论
在前面的关于轮廓的几节里 , 我们介绍了轮廓相关的一些函数 。但当我们用cv2.findContours()函数来找轮廓的时候,我们传入了一个参数,Contour Retrieval Mode 。我们一般传的是cv2.RETR_LIST或者cv2.RETR_TREE这样就可以了 。但是这个参数实际是什么意思呢?
并且在输出时我们得到了三个数组,第一个是图像,第二个是我们的轮廓,第三个输出名字是hierarchy 。但是我们一直没用这个 。
什么是层级?
一般来说我们用cv2.findContours()函数来检测图像里的目标 , 有时候目标在不同的地方,但是在有些情况下,有些图形在别的图形里面,就像图形嵌套 , 在这种情况下,我们把外面那层图形叫做parent , 里面的叫child 。这样图形里的轮廓之间就有了关系 。我们可以指定一个轮廓和其他之间的是如何连接的,这种关系就是层级 。
看下面的例子:
在这个图像里 , 不同的图形我标注了0-5,2和2a表示了最外层盒子的外部和内部轮廓 。
这里轮廓0,1,2是外部的 。我们可以说他们是hierarchy-0,或者他们是同层级的 。
接下来是contour-2a,可以认为是轮廓-2的孩子,或者反过来,contour-2是contour-2a的父亲,所以它在hierarchy-1里 。类似的contour-3是contour-2的孩子,在下一层级 。最后contour4,5是contour-3a的孩子,它们在最后的层级 。
OpenCV里的层级表示
每个轮廓有他自己的关于层级的信息,谁是他的孩子,谁是他的父亲等 。OpenCV用一个包含四个值得数组来表示:[Next, Previous, First_Child, Parent]
"Next表明同一层级的下一个轮廓"
比如,在我们的图片里的contour-0,水上hi他相同层级的下一个轮廓?是contour-1,所以Next=1,对于Contour-1,下一个是contour-2,所以Next=2
那对于contour-2呢?没有同层级的下一个轮廓,所以Next=-1 。那么对于contour-4呢?同层级的下一个是contour-5,所以下一个轮廓是contour-5.Next=5
"Previous指同层级的前一个轮廓"
和上面一样,contour-1的前一个是contour-0.contour-2的前一个contour-1.对于contour-0没有前序,所以-1
"First_Child指它的第一个孩子轮廓"
不用解释,对于contour-2,孩子是contour-2a,所以这里是contour-2a的索引,contour-3a有两个孩子,但我们只取第一个,是contour-4 , 所以First_Child=4.
"Parent指它的父轮廓索引"
和First_Child相反,contour-4和contour-5的parent都是contour-3a,对于contour-3a,是contour-3
注意:
如果没有孩子或者父亲,就为-1
我们知道了层级,现在来看OpenCV里的轮廓获取模式,四个标志cv2.RETR_LIST, cv2.RETR_TREE, cv2.RETR_CCOMP, cv2.RETR_EXTERNAL表示啥?
轮廓获取模式
1.RETR_LIST
这是最简单的一个,它获取所有轮廓,但是不建立父子关系,他们都是一个层级 。
所以,层级属性第三个和第四个字段(父子)都是-1,但是Next和Previous还是有对应值 。
下面是结果,每行是对应轮廓的层级信息 。
hierarchy
2.RETR_EXTERNAL
如果用这个模式,它返回最外层的 。所有孩子轮廓都不要,我们可以说在这种情况下,只有家族里最老的会被照顾,其他都不管 。
所以在我们的图像里,有多少最外层的轮廓呢,有3个 , contours 0,1,2
3.RETR_CCOMP
这个模式获取所有轮廓并且把他们组织到一个2层结构里,对象的轮廓外边界在等级1里,轮廓内沿(如果有的话)放在层级2里 。如果别的对象在它里面 , 里面的对象轮廓还是放在层级1里 , 它的内沿在层级2.
看下面的例子,轮廓的顺序为红色,他们的层级是绿色,
看第一个轮廓,contour-0,他的层级是1,他有两个洞,contours1和2,他们都属于层级2,所以对于contour-0,Next是contour-3,没有前序 , 他的第一个孩子是contour-1,没有parent,所以层级数组是[3,-1,1,-1]
看contour-1,他在层级2里,Next是contour-2 , 没有前序,没有孩子 , parent是contour-0,所以数组是[2,-1,-1,0]
同样对于contour-2,也在层级2里,没有next,前序是contour-1,没有孩子,parent是contour-0,所以[-1,1,-1,0] 。
contour-3:next是contour-5,Previous是contour-0,Child是contour-4,没有parent , 所以[5,0,4,-1]
contour-4:在层级2里,没有兄弟,所以没有Next,没有Previous,没有孩子,parent是contour-3,[-1,-1,-1,3]
4.RETR_TREE
最后 , Mr.Perfect 。它取回所有的轮廓并且创建完整的家族层级列表,它甚至能告诉你谁是祖父,父亲,儿子 , 孙子 。。
比如把上面的图形用cv2.RETR_TREE ,
对于contour-0:层级是0,Next是contour-7,没有previous,孩子是contour-1,没有parent , 所以[7,-1,1,-1]
contour-1:在层级1里,没有同级的其他轮廓,没有previous,孩子是contour-2,所以[-1,-1,2,0]
OpenCV里的直方图
OpenCV-Python系列八:提取图像轮廓 当python轮廓函数你完成图像分割之后,图像轮廓检测往往可以进一步筛选python轮廓函数你要的目标,OpenCV中可以使用cv2.findContours来得到轮廓 。
补充 python轮廓函数:
再不少场景中,找轮廓的最小外接矩形是基本需求,opencv中minAreaRect得到的是一个带有旋转角度信息的rect,可以使用cv2.boxPoints(rect)来将其转为矩形的四个顶点坐标(浮点类型).你也可以使用cv2.polylines来绘制这样的轮廓信息
注意findContours参数的变化,在opencv4中,返回值只有contours和hierarchy,这一点与opencv3中不同 。对与轮廓的层级结构,比较难用,虽然可以通过轮廓的层级结构来进行索引你需要的轮廓,不过对于大部分机器视觉应用场景,二值化的结果有时候很难预料,单单通过这种层级关系索引,非常容易出错 。所以,只找最外部结构的 cv2.RETR_EXTERNAL 是不是真香呢python轮廓函数?
处理cv2.approxPolyDP()外,你也可以使用cv2.convexHull来求轮廓的近似凸包,其中凸形状内部--任意两点连线都在该形状内部 。
clockwise :默认为False,即轮廓为逆时针方向进行排列python轮廓函数;
returnPoints :设置为False会返回与凸包上对应的轮廓的点索引值,设置为True,则会返回凸包上的点坐标集,默认为True
对于opencv-python的提取图像轮廓部分有问题欢迎留言,Have Fun With OpenCV-Python, 下期见 。
python怎么识别图片中每个线的基本形状轮廓搜索
Cv2的方法 。findContours用于查找轮廓 。代码示例如下:
Cr、t = cv2 。cv2 findContours (b 。retr_tree cv2.chain_approx_simple) #
第三个参数定义了轮廓的近似方式
在上述函数的参数中,第一个参数是二值化矩阵,第二个参数是获得轮廓的方式,第三个参数是定义轮廓的近似方式 。
搜索大纲
Cv2方法 。FindContours用于查找contours 。代码示例如下:
Cr t等于cv2 。Cv2 findContours (b. retr_tree Cv2 .chain_approx_simple) #
第三个参数定义了轮廓的近似方式
上述函数的参数中 , 第一个参数是二值化矩阵,第二个参数是获取轮廓的方式,第三个参数是定义轮廓的近似方式 。
OpenCV-Python教程:19.轮廓属性1图像矩
帮python轮廓函数你计算一些属性python轮廓函数,比如重心,面积等 。
函数cv2.moments()会给你一个字典 , 包含所有矩值
你可以从这个里面得到有用python轮廓函数的数据比如面积,重心等 。重心可以用下面的式子得到python轮廓函数:
2.轮廓面积
轮廓面积由函数cv2.contourArea()得到或者从矩里得到M['m00']
3.轮廓周长
可以用cv2.arcLength()函数得到 。第二个参数指定形状是否是闭合的轮廓(如果传True) 。或者只是一个曲线 。
4.轮廓近似
这会把轮廓形状近似成别的边数少的形状,边数由我们指定的精确度决定 。这是Douglas-Peucker算法的实现 。
要理解这个,假设你试图找一个图像里的方块,但是由于图像里的一些问题,你得不到一个完美的方块,只能得到一个“坏方块” 。现在你可以使用这个函数来近似 , 第二个参数叫epsilon,是从轮廓到近似轮廓的最大距离 。是一个准确率参数,好的epsilon的选择可以得到正确的输出 。
在下面第二个图像里,绿线显示python轮廓函数了epsilon = 10% of arc length 的近似曲线 。第三个图像显示了epsilon = 1% of the arc length 。第三个参数指定曲线是否闭合 。
5.凸形外壳
凸形外壳和轮廓近似类似,但是还不一样(某些情况下两个甚至提供了同样的结果) 。这儿,cv2.convexHull()函数检查凸面曲线缺陷并修复它 。一般来说,凸面曲线总是外凸的,至少是平的,如果它内凹了 , 这就叫凸面缺陷 。比如下面这张图,红线显示了手的凸形外壳 。双向箭头显示了凸面缺陷,是轮廓外壳的最大偏差 。
参数详情:
·points 是我们传入的轮廓
·hull 是输出,一般我们不用传
·clockwise: 方向标示,如果是True,输出凸形外壳是顺时针方向的 。否则,是逆时针的 。
·returnPoints:默认是True 。然后会返回外壳的点的坐标 。如果为False , 它会返回轮廓对应外壳点的索引 。
所以要获得凸形外壳,下面
但是如果你想找到凸面缺陷,你需要传入returnPoints = False 。我们拿上面的矩形图形来说,首先我找到他的轮廓cnt,现在用returnPoints = True来找他的凸形外壳,我得到下面的值:[[[234 202]], [[51 202]], [51 79]], [[234 79]]]是四个角的点 。如果你用returnPoints = False,我会得到下面的结果:[[129], [67], [0], [142]].这是轮廓里对应点的索引,比如cnt[129] = [234, 202]],这和前面结果一样 。
6.检查凸面
有一个函数用来检查是否曲线是凸面, cv2.isContourConvex().它返回True或False 。
7.边界矩形
有两种边界矩形
7.a.正边界矩形
这个矩形不考虑对象的旋转,所以边界矩形的面积不是最小的 , 函数是cv2.boundingRect() 。
假设矩形左上角的坐标是(x,y),(w, h)是它的宽和高
7.b.渲染矩形
这个边界矩形是用最小面积画出来的 , 所以要考虑旋转 。函数是cv2.minAreaRect() 。它返回一个Box2D结构,包含了(左上角(x,y),(width, height),旋转角度) 。但是要画这个矩形我们需要4个角 。这四个角用函数cv2.boxPoints()得到
8.最小闭包圆
我们找一个目标的外接圆可以用函数cv2.minEnclosingCircle().这个圆用最小面积完全包围目标 。
9.椭圆
用一个椭圆来匹配目标 。它返回一个旋转了的矩形的内接椭圆
10. 直线
类似的我们可以匹配一根直线,下面的图像包含一系列的白色点,我们可以给它一条近似的直线 。
END
3.8 等高线 等高线可以简单地解释为连接所有连续点(沿着边界)的曲线,具有相同的颜色或强度 。等高线是形状分析、目标检测和识别的有用工具 。
让我们看看如何找到二值图像的轮廓:
cv2.findcontours()函数中有三个参数,
第一个是源图像
第二个是轮廓检索模式
第三个是轮廓近似方法
它输出图像、轮廓和层次 。轮廓是图像中所有轮廓的python列表 。每个轮廓都是对象边界点(x,y)坐标的numpy数组 。
使用 cv2.drawContours, 它也可以用来绘制任何给出边界点的形状 。它的第一个参数是源图像,第二个参数是应该作为等高线列表 , 第三个参数是等高线索引(在绘制个体轮廓时使用) 。要绘制所有轮廓,传递-1)、颜色、厚度等 。
要绘制图像中的所有轮廓:
要绘制第4个轮廓:
但大多数情况下 , 下面的方法更适合:
这是 cv2.findContours 函数中的第三个参数的说明 。
如果传递 cv2.CHAIN_APPROX_NONE , 则存储所有边界点 。但实际上我们需要所有的要点吗?例如,你发现了一条直线的轮廓 。你需要这条线上所有的点来代表这条线吗?不,我们只需要这条线的两个端点 。这就是 cv2.CHAIN_APPROX_SIMPLE所做的 。它删除所有冗余点并压缩轮廓,从而节省内存 。
你可以提取有用的数据,如面积、质心等 。质心可以通过下面的方式来获取
它将一个轮廓形状近似为另一个形状,根据我们指定的精度 , 顶点数量较少 。
为了理解这一点,假设您试图在图像中找到一个正方形,但是由于图像中的一些问题,您没有得到一个完美的正方形,而是一个“坏形状”(如下面第一幅图像所示) 。现在可以使用此函数来近似形状 。在这里,第二个参数称为epsilon,它是从轮廓到近似轮廓的最大距离 。这是一个精度参数 。为了得到正确的输出,需要明智地选择epsilon 。
下图,在第二幅图像中,绿线显示了epsilon=10%弧长的近似曲线 。第三张图片显示的epsilon=弧长的1%相同 。第三个参数指定曲线是否关闭 。
凸面船体看起来类似于轮廓近似,但事实并非如此(在某些情况下两者都可能提供相同的结果) 。在这里,cv2.converxHull()函数检查曲线是否存在凸性缺陷,并对其进行修正 。一般来说,凸曲线是指总是凸出的曲线,或者至少是平的曲线 。如果它在内部膨胀,就称为凸性缺陷 。例如,检查下面的手图像 。红线表示手的凸面外壳 。双面箭头标记显示了凸性缺陷,即船体与轮廓的局部最大偏差 。
points是我们经过的轮廓 。
hull是输出,通常我们避免它 。
clockwise :方向标志 。如果为真,则输出凸壳为顺时针方向 。否则 , 它是逆时针方向的 。
returnPoints :默认为真 。然后返回船体点的坐标 。如果为false,则返回与外壳点对应的轮廓点索引 。
因此 , 如上图所示,要得到一个凸面外壳,以下就足够了:
有一个函数可以检查曲线是否是凸的 , cv2.isContourConvex() 。它只是返回正确还是错误 。
直的矩形,不考虑物体的旋转 。所以边界矩形的面积不会是最小的 。它由函数 cv2.boundingrect() 找到 。
设(x , y)为矩形的左上角坐标,(w,h)为矩形的宽度和高度 。
在这里,边界矩形是用最小面积绘制的,因此它也考虑了旋转 。使用的函数是 cv2.minareect()。但是要画这个矩形,我们需要四个角 。它是通过函数 cv2.boxpoints() 获得的 。
在这里,我们将学习提取一些经常使用的对象属性 , 如坚固性、等效直径、遮罩图像、平均强度等 。
范围是轮廓区域与边界矩形区域的比率 。
坚固性是指轮廓面积与其凸面外壳面积之比 。
等效直径是面积与轮廓面积相同的圆的直径 。
方向是指向对象的角度 。下面的方法也给出了长轴和短轴的长度 。
在某些情况下,我们可能需要包含该对象的所有点 。可以这样做:
这里,有两种方法,一种是使用numpy函数 , 另一种是使用opencv函数(最后一行注释) 。结果也相同,但有轻微的差异 。numpy以(行、列)格式给出坐标,而opencv以(x、y)格式给出坐标 。所以基本上答案会互换 。注意,row=x , column=y 。
极端点是指物体的最上面、最下面、最右边和最左边的点 。
【python轮廓函数 python的轮子】python轮廓函数的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于python的轮子、python轮廓函数的信息别忘了在本站进行查找喔 。

    推荐阅读