【OpenCV 例程300篇】217. 鼠标交互获取多边形区域(ROI)

OpenCV 例程200篇 总目录


【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)。

如果要通过鼠标在图像上选择感兴趣的多边形区域,可以利用鼠标交互来绘制。

    # A4.9 鼠标交互获取多边形区域
    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)

    # 鼠标交互绘制多边形 ROI
    img = cv.imread("../images/imgLena.tif")  # 读取彩色图像(BGR)

    # 鼠标交互 ROI
    print("单击鼠标左键:选择 ROI 顶点")
    print("单击鼠标右键:结束 ROI 选择")
    print("按 ESC 退出")
    pts = []  # ROI 顶点坐标向量
    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)  # 按 ESC 退出
        if key == 27:  # Esc 退出
            break
    cv.destroyAllWindows()  # 图像窗口

    points = np.array(pts, np.int)  # ROI 多边形顶点坐标集
    cv.polylines(img, [points], True, (255,255,255), 2)  # 在 img 绘制 ROI 多边形
    mask = np.zeros(img.shape[:2], np.uint8)  # 黑色掩模,单通道
    cv.fillPoly(mask, [points], (255,255,255))  # 多边形 ROI 为白色窗口
    imgROI = cv.bitwise_and(img, img, mask=mask)  # 按位与,从 img 中提取 ROI

    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. 鼠标交互获取多边形区域

  • 4
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python中使用OpenCV进行不规则多边形ROI区域提取需要以下步骤: 1. 导入所需的库 我们需要导入OpenCV库,并将其命名为cv2。 2. 读取图像 使用cv2.imread()函数读取图像。这里假设图像文件名为"image.jpg"。 3. 创建ROI多边形 定义一个包含不规则多边形顶点的列表作为ROI区域。 4. 创建掩膜 使用cv2.fillPoly()函数创建一个与图像大小相同的空白图像,作为掩膜。然后使用cv2.fillPoly()函数在掩膜上填充多边形。 5. 应用掩膜 使用cv2.bitwise_and()函数将原始图像与掩膜进行按位与操作,即只保留ROI区域。 6. 显示结果 使用cv2.imshow()函数显示提取的ROI区域。 7. 释放窗口 使用cv2.waitKey(0)等待按下任意键后,使用cv2.destroyAllWindows()函数关闭窗口。 以下是一个简单的示例代码: ```python import cv2 import numpy as np # 读取图像 image = cv2.imread('image.jpg') # 创建ROI多边形 roi_vertices = np.array([[(100, 100), (300, 100), (200, 300), (50, 200)]], dtype=np.int32) # 创建掩膜 mask = np.zeros_like(image) cv2.fillPoly(mask, roi_vertices, 255) # 应用掩膜 roi_image = cv2.bitwise_and(image, mask) # 显示结果 cv2.imshow('ROI Image', roi_image) # 释放窗口 cv2.waitKey(0) cv2.destroyAllWindows() ``` 将以上代码保存为Python脚本,运行后会显示提取的ROI区域图像。其中,roi_vertices是一个包含多边形顶点的列表,可以根据需要调整顶点的坐标和个数来定义不规则多边形的形状。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

youcans_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值