OpenCV版本要求在2.3.1以上

本文主要简绍如何在Python中调用OpenCV来画图和OpenCV的鼠标回调函数的使用。

1.画图

在大部分画图的函数中,都会有以下几个参数,比如img是你要进行画图的图片,color是画笔的颜色,thickness和lineType是画线的粗细和线的类型(线的类型一般使用cv2.LINE_AA)。

画图的过程很简单,首先,我们用numpy的函数创建一个空白的图片,然后直接调用相应的画图函数来画图。比如画直线的话,就使用cv2.line()这个函数,它出了需要之前介绍的参数外,还需要我们给出直线的起点和终点(这里起点为(0,0)终点为(511,511)),代码如下:

import numpy as np
import cv2

# Create a black image
img = np.zeros((512,512,3), np.uint8)

# Draw a diagonal blue line with thickness of 5 px
cv2.line(img,(0,0),(511,511),(255,0,0),5)

如果要画矩形的话,就需要再给出矩形左上角和右下角两个点的坐标:

cv2.rectangle(img,(384,0),(510,128),(0,255,0),3)

画圆,则需要给出圆心和半径,这里thickness为-1表示用(0,0,255)即绿色填充满整个图形(OpenCV中颜色的顺序是BGR):

cv2.circle(img,(447,63), 63, (0,0,255), -1)

画椭圆则稍微复杂,需要再给出中心位置,长轴长度,短轴长度,起始角度和终止角度等,以下代码的效果可以画半个椭圆:

cv2.ellipse(img,(256,256),(100,50),0,0,180,(255,0,0),-1)

画多边形则需要给出各个顶点的坐标,然后把这些坐标转化成ROWS*1*2类型的数组,输入进函数,这里需要用到numpy的reshape函数。这里还需要说明顶点坐标的数据类型必须是int32才可以:

pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv2.polylines(img,[pts],True,(0,255,255))

这里,如果把函数中的True改成False,则画出的多边形是不闭合的。因此,我们可以利用这个特点来画多条直线(效率比line函数高很多)。

在图片中添加文字的话,需要再给出文字内容、字体和大小等的参数:

font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)

这里,font的类型可以参考

  cv2.putText()  的函数说明。



最后,这是以上函数画出的图形的样子



2.鼠标回调函数

鼠标事件的回调函数的设置主要是指cv2.setMouseCallback()的设置。它的两个参数分别是回调函数所作用的窗口名称以及回调函数的函数名。回调函数的需要声明成一下形式

def draw_circle(event,x,y,flags,param):

其中,函数名可以任意,但是参数要按照这样的形式声明,event是用来区分触发回调函数的事件的,以下代码列出了能够触发回调函数的事件;

import cv2
events = [i for i in dir(cv2) if 'EVENT' in i]
print events

其中,主要的事件有 left-button down, left-button up, left-button double-click等,每个事件都能把事件发生的坐标位置传递到回调函数中。以下的代码的效果是,当我们在图上双击时,画一个蓝色的圆:

import cv2
import numpy as np

# mouse callback function
def draw_circle(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img,(x,y),100,(255,0,0),-1)

# Create a black image, a window and bind the function to window
img = np.zeros((512,512,3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

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

使用回调函数的功能还能使我们完成更复杂的任务,以下的代码使我们用‘m'键来切换画图的模式——画矩形或者是画圆:

import cv2
import numpy as np

drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix,iy = -1,-1

# mouse callback function
def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode

    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy = x,y

    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                cv2.circle(img,(x,y),5,(0,0,255),-1)

    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        else:
            cv2.circle(img,(x,y),5,(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'):
        mode = not mode
    elif k == 27:
        break

cv2.destroyAllWindows()