如何使用OpenCV在任意轮廓内部获取任意数量的不同点位
OpenCV轮廓内部采样不重复点位实现思路
方案1:掩码随机采样(最通用,实现简单)
- 第一步:基于目标轮廓生成对应单通道掩码图,尺寸和原图像保持一致,用
cv2.drawContours()方法,设置thickness=cv2.FILLED将轮廓内部填充为255、背景置为0。 - 第二步:提取掩码中所有像素值为255的坐标集合,直接调用
np.where(mask == 255)即可得到全量合法内部点数组,所有点天然属于轮廓内部,无需额外判断。 - 第三步:根据你需要的点位数量N,对上述坐标数组做无放回随机采样,用
np.random.choice()设置replace=False即可快速得到N个不重复的内部点位。
性能优化提示:如果图像尺寸极大、全量提取坐标内存开销过高,可以改用拒绝采样:随机生成图像范围内的坐标点,用cv2.pointPolygonTest(contour, (x,y), False)判断点是否在轮廓内部,结果大于0即为内部点,重复采样直到收集到足够的不重复点位即可,无需生成完整掩码。
方案2:三角剖分均匀采样(适合需要点位均匀分布的场景)
- 第一步:对目标轮廓做Delaunay三角剖分,过滤掉轮廓外部的三角形,得到轮廓覆盖范围内的所有三角面片。
- 第二步:按每个三角面片的面积比例分配采样点数,面积越大的三角形分配的采样数越多,保证整体点位分布均匀。
- 第三步:用重心坐标法在每个三角形内生成随机点,生成的点天然属于三角面片也即轮廓内部,所有点位去重后即可得到最终结果。
选型参考:
仅需要随机内部点无分布要求优先选方案1,逻辑简单、无判断误差、速度快;需要点位避免扎堆、尽可能均匀覆盖轮廓内部的场景选方案2。
内容的提问来源于stack exchange,提问作者santi
相关产品推荐
相关产品推荐

