【youcans 的 OpenCV 例程300篇】217. 鼠标交互获取多边形区域
函数 cv.selectROI 可以通过鼠标在图像上选择感兴趣的矩形区域(ROI,region of interest)。
如果要通过鼠标在图像上选择感兴趣的多边形区域,可以利用鼠标交互来绘制。
函数原型:
函数 cv.polylines() 用来绘制多边形曲线或多段线。
函数 cv.fillPoly() 用来绘制一个或多个填充的多边形区域。
cv.polylines(img, pts, isClosed, color[, thickness=1, lineType=LINE_8, shift=0]) → img
cv.fillPoly(img, pts, color[, lineType=LINE_8, shift=0, offset=Point()]) → img
参数说明:
- img:输入输出图像,允许单通道灰度图像或多通道彩色图像
- pts:多边形顶点坐标, 二维 Numpy 数组的列表
- isClosed: 闭合标志,True 表示闭合多边形,False 表示多边形不闭合
特别注意多边形顶点坐标 pts 的格式:
- pts 是一个列表,列表中的元素是二维 Numpy 数组,每个元素表示一组顶点坐标。
- *二维 Numpy 数组的形状为 (m,2),每行表示多边形的一个顶点的坐标 (xi,yi),数据格式应为整型。
例如:
points1 = np.array([[200,100], [295,169], [259,281], [141,281], [105,169]], np.int)
points2 = np.array([[200,400], [259,581], [105,469], [295,469], [141,581]])
points1、points2 是形状为 (m,2) 的二维 Numpy 数组。
对于函数 cv.polylines 与 cv.fillPoly,不能直接把二维 Numpy 数组 points1 或 points2作为函数参数,而要将其作为列表的元素,如: [points1]、[points2] 或 [points1, points2]。
例程 A4.9:鼠标交互获取多边形区域(ROI)
函数 cv.selectROI 可以通过鼠标在图像上选择感兴趣的矩形区域(ROI,region of interest)。
如果要通过鼠标在图像上选择感兴趣的多边形区域,可以利用鼠标交互来绘制。
def mouseHandler(event, x, y, flags, param):
global drawing
setpoint = (x, y)
if event == cv.EVENT_LBUTTONDOWN:
drawing = True
pts.append(setpoint)
print("选择顶点 {}:{}".format(len(pts), setpoint))
elif event == cv.EVENT_RBUTTONDOWN:
drawing = False
print("结束绘制。\n ROI 顶点坐标:")
print(pts)
img = cv.imread("../images/imgLena.tif")
print("单击鼠标左键:选择 ROI 顶点")
print("单击鼠标右键:结束 ROI 选择")
print("按 ESC 退出")
pts = []
drawing = True
cv.namedWindow('origin')
cv.setMouseCallback('origin', mouseHandler)
while True:
imgCopy = img.copy()
if len(pts) > 0:
cv.circle(imgCopy, pts[-1], 5, (0,0,255), -1)
if len(pts) > 1:
for i in range(len(pts)-1):
cv.circle(imgCopy, pts[i], 5, (0,0,255), -1)
cv.line(imgCopy, pts[i], pts[i+1], (255,0,0), 2)
if drawing==False:
cv.line(imgCopy, pts[0], pts[-1], (255,0,0), 2)
cv.imshow('origin', imgCopy)
key = 0xFF & cv.waitKey(1)
if key == 27:
break
cv.destroyAllWindows()
points = np.array(pts, np.int)
cv.polylines(img, [points], True, (255,255,255), 2)
mask = np.zeros(img.shape[:2], np.uint8)
cv.fillPoly(mask, [points], (255,255,255))
imgROI = cv.bitwise_and(img, img, mask=mask)
plt.figure(figsize=(9, 6))
plt.subplot(131), plt.title("origin image"), plt.axis('off')
plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))
plt.subplot(132), plt.title("ROI mask"), plt.axis('off')
plt.imshow(mask, cmap='gray')
plt.subplot(133), plt.title("ROI cropped"), plt.axis('off')
plt.imshow(cv.cvtColor(imgROI, cv.COLOR_BGR2RGB))
plt.tight_layout()
plt.show()
【本节完】
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125490992)
Copyright 2022 youcans, XUPT
Crated:2022-6-26
欢迎关注『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注『youcans 的 OpenCV学习课』 系列,持续更新中
210. 绘制直线也会有这么多坑?
211. 绘制垂直矩形
215. 基于多段线绘制近似椭圆
216. 绘制多段线和多边形
217. 鼠标交互获取多边形区域
Original: https://blog.csdn.net/youcans/article/details/125490992
Author: YouCans
Title: 【OpenCV 例程200篇】217. 鼠标交互获取多边形区域(ROI)
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/633709/
转载文章受原作者版权保护。转载请注明原作者出处!