OpenCV————鼠标绘制和滑动条

导入包

import cv2
import numpy as np

可以通过下面的代码来查看所有的鼠标事件函数

 events=[i for i in dir(cv2) if 'EVENT' in i]#查看所有鼠标事件
 print(events)
 
输出为:
['EVENT_FLAG_ALTKEY',  flags 代表拖拽事件。按住alt键不放
 'EVENT_FLAG_CTRLKEY',按住ctrl键不放
 'EVENT_FLAG_LBUTTON',按住左键拖拽
 'EVENT_FLAG_MBUTTON',中键拖拽
 'EVENT_FLAG_RBUTTON',右键拖拽
 'EVENT_FLAG_SHIFTKEY',按住shift不放
 
 'EVENT_LBUTTONDBLCLK', event鼠标事件。左键双击
 'EVENT_LBUTTONDOWN',按下左键
 'EVENT_LBUTTONUP',释放左键
 'EVENT_MBUTTONDBLCLK',
 'EVENT_MBUTTONDOWN',
 'EVENT_MBUTTONUP',
 'EVENT_MOUSEHWHEEL',
 'EVENT_MOUSEMOVE',
 'EVENT_MOUSEWHEEL',
 'EVENT_RBUTTONDBLCLK',
 'EVENT_RBUTTONDOWN',
 'EVENT_RBUTTONUP']

创建回调函数。当双击鼠标左键时,自动出现圆

def draw_circle(event,x,y,flags,param):#创建回调函数,参数分别是:event鼠标事件,flags鼠标拖拽事件,x,y中心坐标
    if event==cv2.EVENT_LBUTTONDBLCLK:#双击鼠标左键
        cv2.circle(img,(x,y),100,(255,0,0),-1)

img=np.zeros((512,512,3),np.uint8)#黑色画布,长宽都为512,3表示BGR3种颜色,uint8是用0-255表示所有颜色
cv2.namedWindow('image')#窗口命名
cv2.setMouseCallback('image',draw_circle)#用鼠标画
while(1):
    cv2.imshow('image',img)
    if cv2.waitKey(20)&0xFF==27:#。cv2.waitKey(delay)返回值:
        # 1、等待期间有按键:返回按键的ASCII码(比如:Esc的ASCII码为27);
        # 2、等待期间没有按键:返回 -1;
        break
cv2.destroyAllWindows()

拖动鼠标来画矩形或者圆

drawing=False
mode=True
ix,iy=-1,-1
def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode#定义全局变量

    if event==cv2.EVENT_LBUTTONDOWN:#若按下左键,drawing 的状态变成TRUE
        drawing=True
        ix,iy=x,y
    elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:#若拖动左键,
        if drawing==True:
            if mode==True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)# (ix,iy),(x,y)
                # 当按下左键时就会将鼠标所在x,y的值赋给ix,iy作为矩形的左上角起始点,(x,y)终点坐标

            else:
               # cv2.circle(img,(x,y),3,(0,0,255),-1)#画圆,拖动鼠标时会画很多连在一起的小圆
                r = int(np.sqrt((x - ix) ** 2 + (y - iy) ** 2))#起始点是圆心,沿着半径方向拖动拉长半径
                cv2.circle(img,(x,y),r,(0,0,255),-1)
    elif event==cv2.EVENT_LBUTTONUP:#松开左键时,drawing=False
        drawing==False
        if mode==True:#当没有执行上一个elif时,松开左键会画矩形,
            cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        else:
            cv2.circle(img, (x, y), 3, (0, 0, 255), -1)

img=np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
while(1):
    cv2.imshow('image',img)
    k=cv2.waitKey(1)&0xFF
    if k==ord('m'):#按'm'键来控制mode状态,每按一次就会将mode的状态变为与上一次相反,从而判断是画圆还是矩形
        mode=not mode
    elif k==27:#ESC键退出
        break

用滑动条作调色板

def nothing(x):
    pass

img=np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')

#创建滑动条
cv2.createTrackbar('R','image',0,255,nothing)# 参数1:滑动条轨迹名, 参数2:滑动条依附的窗口名
# 参数3:滑块的位置,创建时,滑块初始位置就是这个变量当前的值 参数4:轨迹的最大值, 参数5:回调函数
#在本例中这个回调函数不用做任何事情,我们只需要 pass 就可以了。
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)

switch='0:OFF\n1:ON'#创建转换按钮,opencv不带转换按钮,所以用滑动条来代替,颜色区间值设为0和1,表示关和开
cv2.createTrackbar(switch,'image',0,1,nothing)

while(1):
    cv2.imshow('image',img)
    k=cv2.waitKey(1)&0xFF
    if k==27:
        break

    r=cv2.getTrackbarPos('R','image')
    g=cv2.getTrackbarPos('G','image')
    b=cv2.getTrackbarPos('B', 'image')
    s=cv2.getTrackbarPos(switch,'image')

    if s==0:
        img[:]=0#s=0时,图像颜色0代表黑色
    else:
        img[:]=[b,g,r]
cv2.destroyAllWindows()

OpenCV————鼠标绘制和滑动条_第1张图片

将鼠标和滑动条结合起来,可以选择不同颜色的画笔绘制。

def nothing(x):
    pass

drawing=False
mode=True
ix,iy=-1,-1

def draw_circle(event,x,y,flags,param):
    r = cv2.getTrackbarPos('R', 'image')
    g = cv2.getTrackbarPos('G', 'image')
    b = cv2.getTrackbarPos('B', 'image')
    #     s=cv2.getTrackbarPos(switch,'image')
    color=(b,g,r)
    # switch = '0:OFF\n1:ON'  # 创建转换按钮,opencv不带转换按钮,所以用滑动条来代替
    # cv2.createTrackbar(switch, 'image', 0, 1, nothing)
    global ix,iy,drawing,mode#定义全局变量

    if event==cv2.EVENT_LBUTTONDOWN:#若按下左键,drawing 的状态变成TRUE
        drawing=True
        ix,iy=x,y
    elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:#若拖动左键,
        if drawing==True:
            if mode==True:
                cv2.rectangle(img,(ix,iy),(x,y),color,-1)# (ix,iy),(x,y)
                # 当按下左键时就会将鼠标所在x,y的值赋给ix,iy作为矩形的左上角起始点,(x,y)终点坐标

            else:
               # cv2.circle(img,(x,y),3,(0,0,255),-1)#画圆,拖动鼠标时会画很多连在一起的小圆
                r = int(np.sqrt((x - ix) ** 2 + (y - iy) ** 2))#起始点是圆心,沿着半径方向拖动拉长半径
                cv2.circle(img,(x,y),r,color,-1)
    elif event==cv2.EVENT_LBUTTONUP:#松开左键时,drawing=False
        drawing=False
        if mode==True:#当没有执行上一个elif时,松开左键会画矩形,
            cv2.rectangle(img,(ix,iy),(x,y),color,-1)
        else:
            cv2.circle(img, (x, y), 3, color, -1)

img=np.zeros((512,512,3),np.uint8)
cv2.namedWindow('image')
#创建滑动条
cv2.createTrackbar('R','image',0,255,nothing)# 参数1:滑动条轨迹名, 参数2:滑动条依附的窗口名
# 参数3:滑块的位置,创建时,滑块初始位置就是这个变量当前的值 参数4:轨迹的最大值, 参数5:回调函数
#在本例中这个回调函数不用做任何事情,我们只需要 pass 就可以了。
cv2.createTrackbar('G','image',0,255,nothing)
cv2.createTrackbar('B','image',0,255,nothing)
# switch='0:OFF\n1:ON'#创建转换按钮,opencv不带转换按钮,所以用滑动条来代替
# cv2.createTrackbar(switch,'image',0,1,nothing)
cv2.setMouseCallback('image',draw_circle)
while(1):
    cv2.imshow('image',img)
    k=cv2.waitKey(1)&0xFF
    if k==ord('m'):#按'm'键来控制mode状态,每按一次就会将mode的状态变为与上一次相反,从而判断是画圆还是矩形
        mode=not mode
    elif k==27:#ESC键退出
        break

OpenCV————鼠标绘制和滑动条_第2张图片

你可能感兴趣的:(opencv)