OpenCV-Python学习(15)—— OpenCV 鼠标操作和响应(cv.setMouseCallback)

1. 学习目标

  1. 学习如何在OpenCV中处理鼠标事件;
  2. 学习鼠标事件与回调;
  3. 学习鼠标事件回调函数的基本流程。

2. Callback 基本流程

输入图片说明

3. 鼠标事件 cv.setMouseCallback 函数说明

3.1 cv.setMouseCallback() 函数使用
cv.setMouseCallback(winname,onMouse,userdata)
3.2 参数说明
参数说明
winname表示监听鼠标事件的窗口。
onMouse表示响应函数,即当鼠标事件触发时调用的函数。
userdata表示默认值0。这个参数是用户传递给回调函数的数据,用来处理轨迹条事件。如果使用的第三个参数value是全局变量,完全可以不去管这个userdata参数。传给回调函数的参数!!!
3.3 返回参数
typedef void(*cv::MouseCallback)(int event, int x, int y, int flags, void *userdata)
3.4 返回参数说明
参数说明
event表示当前鼠标执行的事件。
x表示当前鼠标坐标值x。
y表示当前鼠标坐标值y。
flags表示鼠标状态。
userdata表示用户定义的传递到setMouseCallback函数调用的参数。
3.5 event 参数说明
说明
EVENT_MOUSEMOVE (0)表示滑动事件。
EVENT_LBUTTONDOWN (1)表示左键点击事件。
EVENT_RBUTTONDOWN (2)表示右键点击事件。
EVENT_MBUTTONDOWN (3)表示中键点击事件。
EVENT_LBUTTONUP (4)表示左键放开事件。
EVENT_RBUTTONUP (5)表示右键放开事件。
EVENT_MBUTTONUP (6)表示中键放开事件。
EVENT_LBUTTONDBLCLK (7)表示左键双击事件。
EVENT_RBUTTONDBLCLK (8)表示右键双击事件。
EVENT_MBUTTONDBLCLK (9)表示中键双击事件。
3.6 flags 参数说明
说明
EVENT_FLAG_LBUTTON (1)表示左键拖曳事件。
EVENT_FLAG_RBUTTON (2)表示右键拖曳事件。
EVENT_FLAG_MBUTTON (4)表示中键拖曳事件。
EVENT_FLAG_CTRLKEY (8)表示(8~15)按 Ctrl 不放。
EVENT_FLAG_SHIFTKEY (16)表示(16~31)按 Shift 不放。
EVENT_FLAG_ALTKEY (32)表示(32~39)按 Alt 不放。

4. 【通过鼠标绘制随机颜色矩形】实例

4.1 实例代码
import cv2 as cv
import numpy as np

flagMove = False
oldImg = None
startX,startY = -1,-1
endX,endY = -1,-1
b,g,r = 0,0,0

def create_demo():
  global oldImg
  # 创建一个500*500的白色背景图片
  img = np.ones((500,500,3), dtype=np.uint8)*255
  # 复制一个一样大小的白色背景图
  oldImg = np.ones_like(img) * 255
  # 创建一个窗口
  cv.namedWindow('mouse_img')
  # 监听这个窗口的鼠标事件
  cv.setMouseCallback('mouse_img', draw_rectangle, img)
  # 每10毫秒显示一次图片
  while True:
    cv.imshow("mouse_img", img)
    # 监听每10毫秒是否按退出键
    if cv.waitKey(10) & 0xFF == 27:
      break
  # 销毁所有窗口
  cv.destroyAllWindows()

# 鼠标回调函数,绘制矩形
def draw_rectangle(event,x,y,flags,img):
  global flagMove,startX,startY,endX,endY,oldImg,b,g,r
  # 点击起点
  if event == cv.EVENT_LBUTTONDOWN:
    # 当前次鼠标左键开始坐标
    startX,startY = x,y
    # 开始后允许对移动中坐标进行记录
    flagMove = True
    # 产生随机颜色
    b,g,r = np.random.randint(0,256,size=3)
    b,g,r = int(b),int(g),int(r)
  # 移动终点
  if event == cv.EVENT_MOUSEMOVE and flagMove:
    # 将上次绘制的结果给当前图片,为了将当前次移动过程中产生的绘制清除
    img[:] = oldImg[:]
    # 当前次移动结束的坐标
    endX,endY = x,y
    # 绘制移动中的当前矩形
    cv.rectangle(img, (startX,startY), (endX,endY), (b,g,r), lineType=cv.LINE_AA)
  # 最后终点
  if event == cv.EVENT_LBUTTONUP:
    # 当前次坐标点绘制结束坐标点,结束鼠标移动监听
    endX,endY = x,y
    flagMove = False
    # 绘制当前次鼠标左键按下到放开起点和终点组成的矩形
    cv.rectangle(img, (startX,startY), (endX,endY), (b,g,r), lineType=cv.LINE_AA)
    # 保存当前次绘制的图片
    oldImg[:] = img[:]
    # 坐标点还原
    startX,startY = -1,-1
    endX,endY = -1,-1

if __name__ == "__main__":
  create_demo()
4.2 代码解析
  1. 创建一个500*500的白色背景图片;
  2. 复制一个一样大小的白色背景图;
  3. 创建一个窗口,监听这个窗口的鼠标事件;
  4. 鼠标回调函数,绘制矩形;
  5. 当前次鼠标左键开始坐标;
  6. 开始后允许对移动中坐标进行记录;
  7. 产生随机颜色;
  8. 将上次绘制的结果给当前图片,为了将当前次移动过程中产生的绘制清除;
  9. 当前次移动结束的坐标,绘制移动中的当前矩形;
  10. 当前次坐标点绘制结束坐标点,结束鼠标移动监听;
  11. 绘制当前次鼠标左键按下到放开起点和终点组成的矩形;
  12. 保存当前次绘制的图片,坐标点还原;
  13. 每10毫秒显示一次图片;
  14. 监听每10毫秒是否按退出键;
  15. 销毁所有窗口。
4.3 实例运行结果

输入图片说明

5. 注意

  1. 随机颜色的生成的时候,bgr的值必须是int类型;
  2. 每次绘制完成,必须对当前次绘制图片进行保存;
  3. 在移动过程中必须在绘制开始将上次绘制结果的图片覆盖给当前次,否则会出现移动一次一个矩形绘制;
  4. 可以使用鼠标监听事件方法实现图片截图,下一篇实战实现图片截图功能!
  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Rattenking

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

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

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

打赏作者

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

抵扣说明:

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

余额充值