• OpenCV for Python 学习笔记 二


    今天主要看了OpenCV中的事件以及回调函数,这么说可能不准确,主要是下面这两个函数(OpenCV中还有很多这些函数,可以在 http://docs.opencv.org/trunk/modules/highgui/doc/user_interface.html 找到,就不一一列举了),然后自己做了一个简单的绘图程序

    函数如下:

    cv2.setMouseCallback(windowName, onMouse[, param]) 
    cv2.createTrackbar(trackbarName, windowName, value, count, onChange) 

    先看第一个函数,cv2.setMouseCallback()

    import cv2
    import numpy as np
    
    def draw_circle(event, x, y, flags, param):
        print type(param[0]), param[1]
        if event == cv2.EVENT_LBUTTONDBLCLK:
            cv2.circle(parma, (x,y), 100, (255,0,0), -1)
    
    img = np.zeros((512,512,3), np.uint8)
    a = []
    cv2.namedWindow('image')
    cv2.setMouseCallback('image', draw_circle, [img, a])
    
    while(1):
        cv2.imshow('image',img)
        if cv2.waitKey(20) & 0xFF == 27:
            break
    cv2.destroyAllWindows()

    这段代码实现的功能是每当你在面板上双击时,绘制一个以双击点为园心,半径为100的圆

    加粗的地方是设置回调函数的地方,共有3个参数,第一个参数,表示将要操作的面板名,第二个参数是回调函数名,第三个是给回调函数的参数

    如果要给回调函数传递多个参数的话,则将这么多个参数存入一个列表/元组中,将其传入

    然后看回调函数,共有5个参数:

    第一个参数是鼠标事件名,可以通过如下方法查看OpenCV中的事件:

    event = [i for i in dir(cv2) if 'EVENT' in i]
    print event
    
    #############################################
    EVENT_FLAG_ALTKEY   EVENT_FLAG_CTRLKEY
    EVENT_FLAG_LBUTTON  EVENT_FLAG_MBUTTON
    EVENT_FLAG_RBUTTON  EVENT_FLAG_SHIFTKEY
    EVENT_LBUTTONDBLCLK  EVENT_LBUTTONDOWN
    EVENT_LBUTTONUP     EVENT_MBUTTONDBLCLK
    EVENT_MBUTTONDOWN   EVENT_MBUTTONUP
    EVENT_MOUSEMOVE      EVENT_RBUTTONDBLCLK
    EVENT_RBUTTONDOWN     EVENT_RBUTTONUP

    这么多事件,基本看名字就能知道干么了,就不说了

    第二个,第三个参数是鼠标在面板中的坐标

    第四个参数是有没有其他特殊控制,比如在按左键的时候,按了Ctrl,Shift,Alt键等,参数也是刚刚上面的EVENT列表中的,通过事件名可以找到对应flags

    第五个参数则是setMouseCallback()函数给回调函数传递的参数,至于怎么传递,前面已经说了(我的代码中,a没有用,只是为了演示如何给回调函数传递函数用的)

    下面是第二个函数,cv2.createTrackbar()

    共有5个参数,其实这五个参数看变量名就大概能知道是什么意思了

    第一个参数,是这个trackbar对象的名字

    第二个参数,是这个trackbar对象所在面板的名字

    第三个参数,是这个trackbar的默认值

    第四个参数,是这个trackbar上调节的范围(0~count)

    第五个参数,是调节trackbar时调用的回调函数名(为什么此处没有像setMouseCallback函数一样,设置一个回调函数的参数项,这个还不清楚)

    至于如何获取trackbar的当前位置,可以通过

    cv2.getTrackbarPos(trackbarname, winname) 

    这个函数获得当前trackbar的位置,这里的参数我就不解释了。

    最后用这两个函数做了下面一个简单的绘图程序:

    每次获取当前的色彩,鼠标按下后开始绘图,鼠标移动到哪,则画到哪,默认是绘制从起始点到终点的矩形,如果按了'm'键,则切换绘制以起始点和终点为直径的圆,圆心在两点的中心,如果再按'm'键,则切换会矩形。(由于本人对Python的变量作用域这块理解还不是很到位,因此用了很多全局变量,写的不好,请大家多多见谅)

    import cv2
    import numpy as np
    import math
    import copy as cp
    
    drawing = False
    mode = True
    ix,iy = -1,-1
    pre_img = np.zeros((512,512,3), np.uint8)
    img = np.zeros((512,512,3), np.uint8)
    
    def nothing(x):
        pass
    
    def draw_circle(event, x, y, flags, param):
        global ix,iy,drawing,mode,pre_img,img
        
        # 每次获取当前Trackbar的位置
        r = cv2.getTrackbarPos('R', 'hello')
        g = cv2.getTrackbarPos('G', 'hello')
        b = cv2.getTrackbarPos('B', 'hello') 
        colors=(b,g,r)    
       
        print colors 
        if event == cv2.EVENT_LBUTTONDOWN:
            drawing = True
            ix,iy = x,y
        elif event == cv2.EVENT_MOUSEMOVE:
            if drawing == True:
                img = cp.deepcopy(pre_img)
                if mode == True:
                    cv2.rectangle(img, (ix,iy), (x,y), colors, -1)
                else:
                    length = int(math.sqrt((ix-x)**2+(iy-y)**2)/2)
                    center = (int(float(ix+x)/2), int(float(iy+y)/2))
                    cv2.circle(img, center, length, colors, -1)
        elif event == cv2.EVENT_LBUTTONUP:
            drawing = False
            if mode == True:
                cv2.rectangle(img, (ix,iy), (x,y), colors,-1)
            else:
                length = int(math.sqrt((ix-x)**2+(iy-y)**2)/2)
                center = (int(float(ix+x)/2), int(float(iy+y)/2))
                cv2.circle(img, center, length, colors, -1)
            pre_img=img
       
       
    # 创建面板       
    cv2.namedWindow('hello')
    
    # 在面板'hello'上,创建3个trackbar,分别命名为R,G,B,回调函数都是啥都不做
    cv2.createTrackbar('R', 'hello', 0,255, nothing)
    cv2.createTrackbar('G', 'hello', 0,255, nothing)
    cv2.createTrackbar('B', 'hello', 0,255, nothing)
    
    # 创建鼠标事件的回调函数
    cv2.setMouseCallback('hello', draw_circle)
    
    while(1):
        cv2.imshow('hello',img)
        k = cv2.waitKey(1) & 0xFF
        # 每次按'm'键都会切换状态,当m=True时,绘制矩形,m=False,绘制圆
        if k == ord('m'):
            mode = not mode
            
        # 如果按了'ESC'键,则关闭面板
        elif k == 27:
            break
        
    cv2.destroyAllWindows()

    绘制出来的效果如下:

  • 相关阅读:
    airtest支持Cocos-Creator,SDK接入
    Python的getter和setter方法
    liunx常用命令
    liunx的vim常用命令收集
    django+atx+liunx的一些shell脚本
    django+airtest+atx部署liunx平台
    Android下的鉴权实现方案
    Mate20 pro实现H265 (HEVC)实时硬件编码
    OpenCV C++常用功能介绍
    Ubuntu16.04编译libjpeg-turbo库
  • 原文地址:https://www.cnblogs.com/pakfahome/p/3913559.html
Copyright © 2020-2023  润新知