OpenCV学习笔记(七)——窗口交互操作(图像窗口滑动条、鼠标响应事件)


窗口交互操作可以方便用户对程序流程进行操作,能使用户根据不同需求实现不同的处理效果。有时,某一个参数的需要反复调试不同的数值来确定,使用图像窗口滑动条可以快速确定这些参数值。因此交互操作不仅可以在程序运行过程中改变参数数值、避免重复运行程序、节省时间,还能够增加结果的对比效果。

1 图像窗口滑动条

图像窗口滑动条就是在显示图像的窗口中创建的能够通过滑动改变数值的滑动条,它可以帮助我们动态调节某些参数,使图像处理的效果更加明显。在OpenCV4中可以使用cv.createTrackbar()函数在显示图像的窗口上创建滑动条。

#cv.createTrackbar()函数原型
cv.createTrackbar(trackbarname,
				  winname,
				  value,
				  count
				  [, onChange
				  [, userdata]])

其中各返回值和参数的含义分别为:
trackbarname:滑动条的名称
winname:在其中创建滑动条的窗口的名称
value:指向整数变量的指针
count:滑动条的最大值
onChange:每次滑动条更改位置时要调用的函数指针
userdata:传递给回调函数的可选参数

该函数能够在图像窗口的上方创建一个范围从0开始的滑动条,并将创建后的通过值返回。由于滑动条只能输出整数,因此如果需要得到小数,则需要进行后续处理,如输出值除以10就可以得到含有以为小数的数据。注意,value指向的值反应滑动条的位置。在创建滑动条时,该参数确定了滑动条的初始位置,当滑动条创建完成后,该指针指向的整数随着滑动条的移动而改变,如果使用的value参数是全局变量,则可以不用修改userdata参数,使用参数的默认值0即可。

示例代码

# -*- coding:utf-8 -*-
import cv2 as cv
import numpy as np
import sys


def call_backl_brightness(x):
    global value, img, img1
    value = cv.getTrackbarPos('brightness', 'Brighter')
    img1 = np.uint8(np.clip((value / 100 * img), 0, 255))


if __name__ == '__main__':
    # 读取图像并判断是否读取成功
    img = cv.imread('../images/image.jpg')
    img1 = img.copy()
    if img is None:
        print('Failed to read image.jpg.')
        sys.exit()
    cv.namedWindow('Brighter')
    # 设置滑动条的初始值为100
    value = 100
    # 创建滑动条
    cv.createTrackbar('brightness', 'Brighter', value, 300, call_backl_brightness)

    while True:
        cv.imshow('Brighter', img1)
        if cv.waitKey(1) == ord('q'):
            break
    cv.destroyAllWindows()

示例代码通过拖动滑动条改变图像亮度,下图展示了改变滑动条前后图片的状态。
在这里插入图片描述

2 鼠标响应

有时我们需要在图像中标记出重要的区域,通过鼠标可以很好地完成这项任务,OpenCV4中提供了cv.MouseCallback()鼠标响应函数。

#cv.MouseCallback()函数原型
None = cv.MouseCallback(winname,
						onMouse,
				  		[, userdata])

其中各返回值和参数的含义分别为:
winname:在其中添加鼠标响应的窗口的名称
onMouse:鼠标响应的回调函数
userdata:传递给回调函数的可选参数

该函数能够在指定的图像窗口中添加鼠标响应事件。
onMouse在鼠标状态发生改变时调用,回调函数鼠标响应事件的可选标志如下标所示。

标志简记说明
cv.EVENT_MOUSEMOVE0鼠标指针在窗口上移动
cv.EVENT_LBUTTONDOWN1按下鼠标左键
cv.EVENT_RBUTTONDOWN2按下鼠标右键
cv.EVENT_MBUTTONDOWN3按下鼠标中键
cv.EVENT_LBUTTONUP4释放鼠标左键
cv.EVENT_RBUTTONUP5释放鼠标右键
cv.EVENT_MBUTTONUP6释放鼠标中键
cv.EVENT_LBUTTIONDBLCLK7双击鼠标左键
cv.EVENT_RBUTTIONDBLCLK8双击鼠标右键
cv.EVENT_MBUTTIONDBLCLK9双击鼠标中键
cv.EVENT_MOUSEWHEEL10正值表示向前滚动,负值表示向后滚动
cv.EVENT_MOUSEHWHEEL11负值表示向前滚动,正值表示向后滚动

下表列出了回调函数中鼠标响应的标志

标志简记说明
cv.EVENT_FLAG_LUBTTON1按住鼠标左键拖曳
cv.EVENT_FLAG_RUBTTON2按住鼠标右键拖曳
cv.EVENT_FLAG_MUBTTON4按住鼠标中键拖曳
cv.EVENT_FLAG_CTRLKEY8按下Ctrl键
cv.EVENT_FLAG_SHIFTKET16按下Shift键
cv.EVENT_FLAG_ALTKEY32按下Alt键

简单来说,鼠标响应事件就是当鼠标指针位于对于的图像窗口内时,时刻检测鼠标鼠标指针状态,当鼠标指针状态发生改变时,调用回调函数,根据回调函数中事件逻辑选择执行相应的操作。

例如,若回调函数中只处理鼠标左键按下的事件,即判断标志是否为cv.EVENT_LBUTTONDOWN,则只有当标志为cv.EVENT_LBUTTONDOWN时,才有相应的逻辑操作;否则不会执行任何操作。

示例代码

# -*- coding:utf-8 -*-
import cv2 as cv
import sys


def draw(event, x, y, flags, param):
    global img, pre_pts

    # 鼠标右键按下
    if event == cv.EVENT_RBUTTONDOWN:
        print('请点击鼠标左键进行轨迹的绘制。')

    # 鼠标左键按下
    if event == cv.EVENT_LBUTTONDOWN:
        pre_pts = (x, y)
        print('轨迹起始坐标为:{}, {}'.format(x, y))

    # 鼠标移动
    if event == cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_LBUTTON:
        pts = (x, y)
        img = cv.line(img, pre_pts, pts, (0, 0, 255), 2, 5,0)
        pre_pts = pts
        cv.imshow('image', img)


if __name__ == '__main__':
    # 读取图像并判断是否读取成功
    img = cv.imread('../images/flower.jpg')
    img1 = img.copy()
    if img is None:
        print('Failed to read flower.jpg.')
        sys.exit()
    pre_pts = -1, -1
    cv.imshow('image', img)
    cv.setMouseCallback('image', draw)
    cv.waitKey(0)
    cv.destroyAllWindows()

代码运行结果如下图所示。
在这里插入图片描述
下一篇将会介绍OpenCV中直方图的计算与绘制操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值