本次主要介绍opencv鼠标回调函数,以及图像与鼠标交互的一些简单应用
一、cv2.setMouseCallback()
1.参数及使用格式
在OpenCV中,可以调用cv2.setMouseCallback()
函数,将自定义的鼠标回调函数与指定的窗口绑定,即在该窗口中注册一个鼠标事件回调函数。当用户在窗口内执行鼠标操作时,该回调函数会被调用,并传递相应的参数。
cv2.setMouseCallback()
函数的语法如下:
cv2.setMouseCallback(windowName, onMouse[, param])
其中,参数含义如下:
windowName
:窗口名称,表示要绑定的窗口;onMouse
:鼠标回调函数,处理鼠标事件的函数;param
:可选参数,传递给回调函数的附加参数
2.鼠标回调函数
了解cv2.setMouseCallback()的各个参数后,接下来我们需要学习如何创建一个鼠标事件回调函数
(1)鼠标事件
在OpenCV中,常用的鼠标事件有以下几种:
cv.EVENT_MOUSEMOVE
:鼠标移动事件。cv.EVENT_LBUTTONDOWN
:左键按下事件。cv.EVENT_LBUTTONUP
:左键释放事件。cv.EVENT_LBUTTONDBLCLK
:左键双击事件。cv.EVENT_RBUTTONDOWN
:右键按下事件。cv.EVENT_RBUTTONUP
:右键释放事件。cv.EVENT_RBUTTONDBLCLK
:右键双击事件。cv.EVENT_MBUTTONDOWN
:中键按下事件。cv.EVENT_MBUTTONUP
:中键释放事件。cv.EVENT_MBUTTONDBLCLK
:中键双击事件。
(2)鼠标回调函数示例
在上一篇文章中为小狗加“opencv”水印的基础上,我们在这里使用鼠标的交互为小狗加上多个水印;
首先构造鼠标回调函数
def onMouse(event,x,y,flags,param):#鼠标回调函数
if event==cv2.EVENT_LBUTTONDOWN:#按下左键事件
cv2.putText(img,"opencv",(x,y),cv2.FONT_HERSHEY_SIMPLEX,0.75,(0,0,0),2)
这里补充一下cv2.putText()的参数及用法:
cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])
参数:
img
:需要写入文本的图像。text
:要写入的文本。org
:文本左下角的起始坐标点。fontFace
:字体类型。fontScale
:字体大小,缩放因子。color
:文本颜色。thickness
:字体粗细,默认为 1。lineType
:线条类型,可选参数,默认为cv2.LINE_8
。bottomLeftOrigin
:默认为False
,如果为True
,则起始坐标表示文本框左下角位置。
常用的字体:
cv2.FONT_HERSHEY_SIMPLEX
:简单的字体,可以解决大多数问题。cv2.FONT_HERSHEY_PLAIN
:类似cv2.FONT_HERSHEY_SIMPLEX
。cv2.FONT_HERSHEY_DUPLEX
:类似cv2.FONT_HERSHEY_SIMPLEX
。cv2.FONT_HERSHEY_COMPLEX
:较复杂的字体。cv2.FONT_HERSHEY_TRIPLEX
:类似cv2.FONT_HERSHEY_COMPLEX
。cv2.FONT_HERSHEY_COMPLEX_SMALL
:较复杂的字体,比cv2.FONT_HERSHEY_COMPLEX
小。cv2.FONT_HERSHEY_SCRIPT_SIMPLEX
:手写风格的字体。cv2.FONT_HERSHEY_SCRIPT_COMPLEX
:更加手写风格的字体。
以下是完整代码:
import cv2
import numpy
def onMouse(event,x,y,flags,param):#鼠标回调函数
if event==cv2.EVENT_LBUTTONDOWN:#按下左键事件
cv2.putText(img,"opencv",(x,y),cv2.FONT_HERSHEY_SIMPLEX,0.75,(0,0,0),2)
img=cv2.imread(r"C:\python study file\dog.jpg")
cv2.namedWindow("img")
cv2.setMouseCallback("img",onMouse)
while True:
cv2.imshow("img",img)
if cv2.waitKey(1)==ord("q"):#按q退出程序
break
cv2.destroyAllWindows()
效果图:
二.实战之制作一个提取hsv值区间器
在一些比赛中我们常常需要识别一些特定颜色的色块,这时候我们普遍的做法都是提取图像hsv值的upper和lower来将图像二值化,而鼠标的交互能帮助我们更快就能提取出图像中我们需要的hsv区间。
以下是代码:
import cv2
moving = False
upper_H, upper_S, upper_V = 0, 0, 0
lower_H, lower_S, lower_V = 255, 255, 255
def get_HSV(event, x, y, flags, param): # 鼠标回调函数
global upper_H, upper_S, upper_V # 引用全局变量
global lower_H, lower_S, lower_V, moving
if event == cv2.EVENT_LBUTTONDOWN: # 左键按下事件
moving = True
[upper_H, upper_S, upper_V] = img[y, x]
[lower_H, lower_S, lower_V] = img[y, x]
elif event == cv2.EVENT_MOUSEMOVE: # 鼠标移动事件
if flags == cv2.EVENT_FLAG_LBUTTON and moving == True: # 左键按下状态
upper_H = img[y, x, 0] if img[y, x, 0] > upper_H else upper_H
lower_H = img[y, x, 0] if img[y, x, 0] < lower_V else lower_H
upper_S = img[y, x, 1] if img[y, x, 1] > upper_S else upper_S
lower_S = img[y, x, 1] if img[y, x, 1] < upper_S else upper_S
upper_V = img[y, x, 2] if img[y, x, 2] > upper_V else upper_V
lower_V = img[y, x, 2] if img[y, x, 2] < lower_V else lower_V
elif event == cv2.EVENT_LBUTTONUP:
moving = False
upper = [upper_H, upper_S, upper_V]
lower = [lower_H, lower_S, lower_V]
print("upper:",upper,"\nlower:",lower)
img_origin = cv2.imread(r"C:\Users\13560\Desktop\1699413166600.jpg")
img=cv2.cvtColor(img_origin,cv2.COLOR_BGR2HSV)
cv2.namedWindow("img",cv2.WINDOW_NORMAL)
cv2.resizeWindow("img",img.shape[1],img.shape[0])
cv2.setMouseCallback("img", get_HSV)
while True:
cv2.imshow("img", img_origin)
if cv2.waitKey(1) == ord('q'): # 按q退出程序
break
cv2.destroyAllWindows()
运行结果