这篇博客将介绍如何使用Python和OpenCV捕获鼠标事件。还演示了如何快速裁剪和提取图像区域,这在为自己的自定义对象检测器创建训练数据时特别有用。
该示例将点击图片,并拖动一个矩形的兴趣区(ROI),然后从图像中裁剪出来。
1. 效果图
拿我最喜欢的小林老师的漫画图,截图图像中的薰衣草图片ROI,并展示,效果图如下:
在截一下郁金香,郁金香ROI下图右侧~
2. 源码
# 使用Python,OpenCV捕获鼠标单击事件
# USAGE
# python click_and_crop.py --image lin_image.jpg
# 导入必要的类
import argparse
import cv2
import imutils
# 初始化参考点列表和布尔值标志:是否正在执行裁剪
refPt = []
cropping = False
# 点击并裁剪ROI区域
# -events 鼠标事件(如按下鼠标左键,释放鼠标左键,鼠标移动等)
# -x x坐标
# -y y坐标
# -flages params 其他参数
def click_and_crop(event, x, y, flags, param):
# 获取全局变量的引用
global refPt, cropping
# 如果鼠标左被单击,记录(x,y)坐标并显示裁剪正在进行
if event == cv2.EVENT_LBUTTONDOWN:
refPt = [(x, y)]
cropping = True
# 检测鼠标左键是否释放
elif event == cv2.EVENT_LBUTTONUP:
# 记录结束(x,y)坐标,并显示裁剪结束
refPt.append((x, y))
cropping = False
# 在感兴趣区域记录矩形区域
cv2.rectangle(image, refPt[0], refPt[1], (0, 255, 0), 2)
cv2.imshow("image", image)
# 构建命令行参数及解析
# -image 原始图像的路径
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())
# 加载图像,并复制,设置鼠标回调函数
image = cv2.imread(args["image"])
image = imutils.resize(image, width=500)
clone = image.copy()
cv2.namedWindow("image")
cv2.setMouseCallback("image", click_and_crop)
# 保持循环直至按下‘q’键
while True:
# 展示图像并等待按下键
cv2.imshow("image", image)
key = cv2.waitKey(1) & 0xFF
# 如果按下‘r’键,则重置裁剪区域
if key == ord("r"):
image = clone.copy()
# 按下‘q’键,跳出循环
elif key == ord("q"):
break
# 如果参考点列表里有俩个点,则裁剪区域并展示
if len(refPt) == 2:
roi = clone[refPt[0][1]:refPt[1][1], refPt[0][0]:refPt[1][0]]
cv2.imshow("ROI", roi)
cv2.waitKey(0)
# 关闭所有打开的窗口
cv2.destroyAllWindows()