OpenCV drawContours绘制重叠区域时部分像素被排除?原因解析
cv2.drawContours填充重叠区域出现空白的原因及解决方法
我在测试cv2.drawContours函数时编写了如下代码:
import cv2 import numpy as np def fix_format(cts): return [np.asarray(np.round(ct), np.int32)[:, :, np.newaxis] for ct in cts] # 两个重叠的矩形轮廓 cts1 = [ [[1, 1], [6, 1], [6, 4], [1,4]], [[3, 2], [7, 2], [7, 7], [3,7]] ] img1 = cv2.drawContours(np.zeros([10, 10]), fix_format(cts1), contourIdx=-1, color=1, thickness=-1)
原本以为设置thickness=-1会填充轮廓,重叠区域会得到两个区域的并集,但打印img1时发现重叠区域的img1[3][4]和img1[3][5]仍为0值。
我分别单独测试两个轮廓,得到了对应结果:
- 单独绘制第一个轮廓:重叠区域为填充状态
- 单独绘制第二个轮廓:重叠区域为填充状态
- 同时绘制两个轮廓:重叠区域变为空白
原因分析
cv2.drawContours在thickness=-1填充轮廓时,默认采用奇偶填充规则(Odd-Even Rule):
对于图像中的每个像素,统计穿过该像素的轮廓边数量,若为奇数则填充,偶数则不填充。当两个重叠轮廓覆盖同一像素时,该像素会被两次计数(偶数),因此不会被填充,最终值保持为0。
你的两个矩形轮廓重叠区域(x范围3-6,y范围2-4)内的像素,会被两个轮廓各填充一次,触发奇偶规则的抵消逻辑,所以这些像素最终为0。
解决方法
如果需要得到两个轮廓区域的并集,可以采用以下方式:
分别填充后按位或
先单独填充每个轮廓到不同的图像,再通过按位或操作合并结果,确保重叠区域保留填充状态:
import cv2 import numpy as np def fix_format(cts): return [np.asarray(np.round(ct), np.int32)[:, :, np.newaxis] for ct in cts] cts1 = [ [[1, 1], [6, 1], [6, 4], [1,4]], [[3, 2], [7, 2], [7, 7], [3,7]] ] img_base = np.zeros([10, 10], dtype=np.uint8) # 单独填充第一个轮廓 img_cnt1 = cv2.drawContours(img_base.copy(), fix_format(cts1[:1]), -1, 1, -1) # 单独填充第二个轮廓 img_cnt2 = cv2.drawContours(img_base.copy(), fix_format(cts1[1:]), -1, 1, -1) # 按位或得到并集 img_union = cv2.bitwise_or(img_cnt1, img_cnt2)
内容的提问来源于stack exchange,提问作者Carlo
相关产品推荐
相关产品推荐

