基于OpenCV Python实现凹多边形图像裁剪
嘿,没问题!用OpenCV裁剪凹多边形包围的区域完全可以通过掩码法实现,不管是凸多边形还是凹多边形都适用。我给你一步步拆解并附上可直接运行的代码:
解决思路:掩码法裁剪任意多边形区域
核心思路是先创建一个和原图像尺寸一致的掩码,把多边形区域填充为白色,再通过按位与操作保留原图像中掩码白色区域的内容,完美解决非矩形区域的裁剪需求。
具体步骤:
步骤1:准备图像与多边形坐标
先读取你的输入图像,然后把你给出的多边形坐标转换成OpenCV要求的格式:需要是numpy.int32类型的数组,并且调整形状为(-1, 1, 2)(这是OpenCV绘制/填充多边形的标准格式)。步骤2:创建空白掩码
生成一个和原图像尺寸相同的单通道空白图像,初始像素值全为0(黑色),后续我们会把多边形区域填充为255(白色)。步骤3:填充多边形到掩码
使用cv2.fillPoly()函数填充掩码的多边形区域,这个函数默认采用非零环绕填充规则,能正确识别并填充凹多边形的内部区域,不会出现填充不全的问题。步骤4:掩码与原图像结合
通过cv2.bitwise_and()函数,将原图像和掩码进行按位与操作,这样只有掩码中白色的区域(也就是多边形包围的部分)会被保留,其余区域变为黑色。可选:提取最小包围矩形区域
如果你不想保留周围的黑色区域,可以用cv2.boundingRect()找到多边形的最小外接矩形,然后从裁剪后的图像中截取这部分,得到只包含多边形内容的图像。
完整代码示例
import cv2 import numpy as np # 1. 读取输入图像(替换成你的图像路径) img = cv2.imread("your_image.jpg") if img is None: print("无法读取图像,请检查路径是否正确!") exit() # 2. 定义你提供的凹多边形坐标 polygon_points = np.array([[10,150],[150,100],[300,150],[350,100],[310,20],[35,10]], dtype=np.int32) # 转换为OpenCV要求的形状:(-1, 1, 2) polygon_points = polygon_points.reshape((-1, 1, 2)) # 3. 创建与图像尺寸相同的空白掩码(单通道,初始全黑) mask = np.zeros(img.shape[:2], dtype=np.uint8) # 4. 在掩码上填充多边形区域为白色(255) cv2.fillPoly(mask, [polygon_points], 255) # 5. 用掩码裁剪图像 cropped_img = cv2.bitwise_and(img, img, mask=mask) # 可选:提取多边形的最小包围矩形区域,去掉周围黑色 x, y, w, h = cv2.boundingRect(polygon_points) cropped_roi = cropped_img[y:y+h, x:x+w] # 显示结果 cv2.imshow("原始图像", img) cv2.imshow("掩码", mask) cv2.imshow("裁剪结果(带黑色背景)", cropped_img) cv2.imshow("裁剪结果(仅多边形区域)", cropped_roi) cv2.waitKey(0) cv2.destroyAllWindows()
关键点说明
cv2.fillPoly()对凹多边形的支持:这个函数不需要额外设置填充规则,默认就能正确处理凹多边形的内部填充,不用担心出现漏填或者填充错误的情况。- 掩码的通用性:不管是规则的矩形、不规则的凸多边形还是凹多边形,掩码法都是最通用的裁剪方案,逻辑清晰且容易调试。
- 可选的ROI提取:如果你的应用场景不需要黑色背景,那
boundingRect+切片的方式就能快速得到只包含目标区域的图像。
内容的提问来源于stack exchange,提问作者Himanshu Tiwari
相关产品推荐
相关产品推荐

