本文来自公众号”AI大道理“。
这里即有AI,也有大道理。
1、问题描述:轮廓的面积contourArea()得出一个面积,后面利用宽*高得出一个面积,两个面积结果不一样。统计发现前者面积永远小于后者面积。
2、contourArea()
findContours() 提取轮廓, contourArea() 计算轮廓面积。
ContourArea计算轮廓的面积使用格林公式。
格林公式是什么?
在高数的曲线曲面积分部分,格林公式、高斯公式和斯托克斯公式是三个十分十分重要的公式,利用这三个公式可以将复杂的积分转化为我们比较熟悉的积分进行解决。
格林公式的应用是有条件的:封闭且正向、被积函数在D上是连续的。
为什么要用格林公式计算?
格林公式可以求解第二型的曲线积分,即曲面面积。
因此,opencv的函数ContourArea()是在求不规则的曲面面积。
实际上它在求下图白色区域的面积。
3、几何面积
宽*高的面积是矩形的面积。
Rect selection = boundingRect(contours[t])
是在这个白色的区域外面画出一个最小矩形。
因此area=selection.width * selection.height求的面积是红色矩形的面积。
所以才使得contourArea()求出来的面积和宽高面积不一样,且永远小于看宽高面积。
4、真实面积
上述ContourArea()面积比最小外接矩形的面积小很好理解。
但问题是,ContourArea()求得得面积居然比真实面积还要小,也就是比白色区域得面积要小。
这又是怎么回事呢?
原来ContourArea()是取连通域边界像素中心点,连接起来,成为一个轮廓,导致一周得边界像素点丢失,即求得得面积比真实得面积少了一圈。
比如下图,真实面积4*4=16,而ContourArea()则只是算红线内得面积,只有3*3=9。
因此,countArea() 函数也会 ”有中去无“,视而不见,算出来的轮廓面积会出现0。
有轮廓,但是面积为0。(不是见鬼了)
比如有的轮廓厚度只有两像素,都是边缘线,那计算出来的面积就等于0。
4、总结
contourArea()求的是封闭曲线内面积,几何面积求的是最小外接矩的面积。
所以才使得contourArea()求出来的面积和宽高面积不一样,且永远小于看宽高面积。
由于在计算面积得时候丢失了外围像素,因此contourArea()求出来的面积比真实面积要小。
(一开始误以为contourArea()是在求红色线条内线条所包含的面积,而几何面积是在计算红色线条外线条所包含的面积。因为线条是有粗细的,实际中用的2即两个像素点画这个红色矩形。所以前者面积永远小于后者面积。但是,求证后发现,即使减掉线条的粗细,求得的面积还是对应不上。)
——————
浅谈则止,细致入微AI大道理
扫描下方“AI大道理”,选择“关注”公众号
—————————————————————
—————————————————————