Python+Opencv实现计算闭合区域面积
本文介绍利用Python和OpenCV计算闭合区域面积的两种方法。首先解析cv2.contourArea函数基于格林公式的原理,说明逆时针与顺时针输入对结果正负的影响。其次提供通过填充连通域并统计非零像素个数来计算面积的替代方案,适用于需要精确像素计数的场景。
一、cv2.contourArea
在初次使用这个函数时,返回的面积值有时为0或负数,让人难以理解。经过研究后发现,这涉及到具体的计算原理。
OpenCV中计算轮廓内部面积的函数,其底层逻辑是基于格林公式(Green's Theorem)来实现的,具体公式如下:

格林公式在计算单连通域面积时,默认以逆时针方向为正方向。如果输入的轮廓数组是按照顺时针方向排列的,计算出的面积就会显示为负数。而面积为0的情况,通常是因为轮廓仅由单个像素点构成,没有围成实际区域。

具体实现代码如下:
img = cv2.imread('test.png', 0)
contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_L1)
area = []
topk_contours =[]
for i in range(len(contours)):
a = cv2.contourArea(contours[i], True)
area.append(abs(a))
topk = 2 #取最大面积的个数
for i in range(2):
top = area.index(max(area))
area.pop(top)
topk_contours.append(contours[top])
x, y = img.shape
mask = np.zeros((x, y, 3))
mask_img = cv2.drawContours(mask, topk_contours, -1, (255, 255, 255), 1)
cv2.imwrite('mask_img.png', mask_img, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
cv2.imshow('mask_img:', mask_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果如下:

二、按像素个数计算连通域面积
这里介绍另一种基于连通域内部像素数量来计算面积的方法:
img = cv2.imread('test.png', 0)
contours, hierarchy = cv2.findContours(img, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_TC89_L1)
area = []
topk_contours =[]
x, y = img.shape
for i in range(len(contours)):
# 对每一个连通域使用一个掩码模板计算非0像素(即连通域像素个数)
single_masks = np.zeros((x, y))
fill_image = cv2.fillConvexPoly(single_masks, contours[i], 255)
pixels = cv2.countNonZero(fill_image)
area.append(pixels)
topk = 2 #取最大面积的个数
for i in range(2):
top = area.index(max(area))
area.pop(top)
topk_contours.append(contours[top])
mask = np.zeros((x,y,3))
mask_img = cv2.drawContours(mask, topk_contours, -1, (255, 255, 255), 1)
cv2.imwrite('mask_img.png', mask_img, [int(cv2.IMWRITE_JPEG_QUALITY), 100])
cv2.imshow('mask_img:', mask_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

关于Python结合OpenCV计算闭合区域面积的讲解就到这里,更多关于Python和OpenCV面积处理的内容,欢迎查阅本站往期文章或继续浏览后续内容,感谢大家的支持!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













