OpenCV-Python根据鼠标点击位置截取ROI

OpenCV-Python根据鼠标点击位置截取ROI


前言

基于OpenCV获取鼠标在图像中的位置,截取不规则的ROI区域,实现初级的抠图功能。


一、实现过程

1.引入库

# _*_ coding: utf-8 _*_
# @name : GetROI.py
# @author : 霜晨月~
import cv2
import numpy as np

2. 获取鼠标位置

定义一个类,实现获取鼠标位置和图像截取功能,代码如下:

class GetRoiMouse():
    global img # 输入的图像

    def __init__(self):
        self.lsPointsChoose = [] 
        self.tpPointsChoose = [] 
        self.pointsCount = 0 	# 顶点计数
        self.pointsMax = 8 		# 最大顶点个数
        self.mouseWindowName = 'click ROI'

    def mouseclick(self):	# 显示一个窗口
        cv2.namedWindow(self.mouseWindowName)
        # opecv可以设置监听鼠标
        # setMouseCallback(windowName,onMouse())
        # 在onMouse中写点击鼠标时要进行的工作
        cv2.setMouseCallback(self.mouseWindowName, self.on_mouse)
    
        cv2.imshow(self.mouseWindowName, img)
        cv2.waitKey(0)


    def getRoi(self):
        mask = np.zeros(img.shape, np.uint8)
        pts = np.array(self.lsPointsChoose, np.int32)  # 顶点集
        pts = pts.reshape((-1, 1, 2))
        mask = cv2.polylines(mask, [pts], True, (255, 255, 255))
        mask2 = cv2.fillPoly(mask, [pts], (255, 255, 255))
        # 顶点个数:4,矩阵变成4*1*2维
        # OpenCV中需要将多边形的顶点坐标变成顶点数×1×2维的矩阵
        # 这里 reshape 的第一个参数为-1, 表示“任意”,意思是这一维的值是根据后面的维度的计算出来的
        # void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
        #               const Scalar& color, int lineType=8, int shift=0, Point offset=Point() )
        # cv2.imshow('mask', mask2)
        # cv2.imwrite('mask.bmp', mask2)
        # cv2.drawContours(mask,points,-1,(255,255,255),-1)
        # 截取图像中的对应位置
        self.ROI = cv2.bitwise_and(mask2, img)
	
	# OpenCV的鼠标响应函数,可以在内部定义鼠标的各种响应
    def on_mouse(self, event, x, y, flags, param):
        # 左键点击
        if event == cv2.EVENT_LBUTTONDOWN:
            print('left-mouse')
            self.pointsCount += 1
            print(self.pointsCount)
            point1 = (x, y)
            # 画出点击的位置
            img1=img.copy()
            cv2.circle(img1, point1, 10, (0, 255, 0), 2)
            self.lsPointsChoose.append([x, y])
            self.tpPointsChoose.append((x, y))
            # 将鼠标选的点用直线连起来
            for i in range(len(self.tpPointsChoose) - 1):
                cv2.line(img1, self.tpPointsChoose[i], self.tpPointsChoose[i + 1], (0, 0, 255), 2)
            cv2.imshow(self.mouseWindowName, img1)
            
            if (self.pointsCount == self.pointsMax):
                self.getRoi()
                cv2.destroyWindow(self.mouseWindowName)
        # -------------------------右键按下清除轨迹---------------
        if event == cv2.EVENT_RBUTTONDOWN:  # 右键点击
            print("right-mouse")
            self.lsPointsChoose = []
            self.tpPointsChoose = []
            self.pointsCount = 0
            # print(len(tpPointsChoose))
            for i in range(len(self.tpPointsChoose) - 1):
                # print('i', i)
                cv2.line(img, self.tpPointsChoose[i], self.tpPointsChoose[i + 1], (0, 0, 255), 2)
            cv2.imshow(self.mouseWindowName, img)

使用方法

if __name__ == '__main__':
    img = cv2.imread('../image.jpg')
    mouse_roi = GetRoiMouse()
    mouse_roi.mouseclick()
    ROI = mouse_roi.ROI
    cv2.imwrite('roi.jpg', ROI)

实例展示

原图

原图像
ROI
ROI

  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值