导读

OpenCV功能越发强大,不学一下怎么行?


今天要分享这篇文章带我们一起了解通过鼠标进行图形的绘制,包括直线、矩形、圆等,。让我们走进这篇文章,一起来了解一下吧!


如果你有什么问题,或者有什么想法,欢迎评论与我一起沟通交流。如果你想了解更多有关于计算机视觉、OpenCV、机器学习、深度学习等相关技术的内容,想与更多大佬一起沟通,那就加群:326866692 或者扫描下方二维码加入我们吧!


1 鼠标控件

1 引入

只要我们用电脑,几乎必不可少要用到鼠标,通过鼠标的一些点击、移动,我们可以完成很多功能。


在OpenCV中,我们也提供了鼠标控件,方便我们用鼠标去操作绘图,就像我们电脑的画图软件一样。

2 控件介绍

想查看OpenCV都支持哪些鼠标控件,我们可以通过如下的代码查看:


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


这样我们就能得到控件如下:


['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_MOUSEHWHEEL', 'EVENT_MOUSEMOVE', 'EVENT_MOUSEWHEEL', 'EVENT_RBUTTONDBLCLK', 'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP']


这几个控件在OpenCV中的定义及含义如下:


(1)EVENT_MOUSEMOVE:指示鼠标指针已在窗口上移动。
(2)EVENT_LBUTTONDOWN:指示按下鼠标左键。
(3)EVENT_RBUTTONDOWN:指示已按下鼠标右键。
(4)EVENT_MBUTTONDOWN:指示按下鼠标中键。
(5)EVENT_LBUTTONUP:指示鼠标左键已释放。
(6)EVENT_RBUTTONUP:表示鼠标右键已释放。
(7)EVENT_MBUTTONUP:指示鼠标中键已释放。
(8)EVENT_LBUTTONDBLCLK:指示双击鼠标左键。
(9)EVENT_RBUTTONDBLCLK:指示双击鼠标右键。
(10)EVENT_MBUTTONDBLCLK:指示双击鼠标中键。
(11)EVENT_MOUSEWHEEL:正值和负值分别表示向前和向后滚动。
(12)EVENT_MOUSEHWHEEL:正值和负值分别表示右滚动和左滚动。


3 控件调用API

控件调用的API是 setMouseCallback ,该API实现的功能是:


为指定窗口设置鼠标处理程序。


API定义如下:


def setMouseCallback(windowName, onMouse, param=None)


API的参数含义如下:


(1)windowName:窗口名称,必须使用namedWindow创建
(2)onMouse:鼠标回调函数
(3)param:传递给回调的可选参数,一般用不到



对于第2个参数,我们需要自己写调用函数,在后面,我们会举具体的例子。


2 鼠标绘制圆

1 回调函数

我们要写好鼠标的回调函数,方便我们后面调用


以鼠标绘制圆为例,当我们按下鼠标,我们就以当前位置为圆心,50为半径,画一个圆。我们写回调函数如下:


import cv.cv2 as cv
import numpy as np
from random import *


def draw_circle(event,x,y,flags,param):
if event == cv.EVENT_LBUTTONUP:
cv.circle(img,(x,y),50,(randint(0,255),randint(0,255),randint(0,255)),-1)


2 其他代码及执行结果

代码如下:


img = np.ones((512,762,3), np.uint8)*255  #创建一个白色背景的图片


winname = "Drawing board"
cv.namedWindow(winname)
cv.setMouseCallback(winname,draw_circle)
while(1):
cv.imshow(winname,img)
if cv.waitKey(20) & 0xFF == 27:
break
cv.destroyAllWindows()


执行结果如下:


【OpenCV教程】07 鼠标控件基本操作_控件


3 矩形的绘制

1 回调函数

我们绘制一个矩形,鼠标点击的位置是初始位置,释放的位置是最终位置:


import cv.cv2 as cv
import numpy as np
from random import *


def draw_rectangle(event,x,y,flags,param):
global ix,iy,drawing
b = randint(0, 255)
g = randint(0, 255)
r = randint(0, 255)
if event == cv.EVENT_LBUTTONDOWN:
drawing = True
ix,iy = x,y
elif event == cv.EVENT_MOUSEMOVE:
if drawing == True:
cv.rectangle(img,(ix,iy),(x,y),(b,g,r),-1)


elif event == cv.EVENT_LBUTTONUP:
drawing = False
cv.rectangle(img,(ix,iy),(x,y),(b,g,r),-1)


2 其他代码及执行结果

代码如下:


drawing = False
ix = 0
iy = 0
img = np.ones((512,762,3), np.uint8)*255 #创建一个白色背景的图片


winname = "Drawing board"
cv.namedWindow(winname)
cv.setMouseCallback(winname,draw_rectangle)
while(1):
cv.imshow(winname,img)
if cv.waitKey(20) & 0xFF == 27:
break
cv.destroyAllWindows()


执行结果如下:


【OpenCV教程】07 鼠标控件基本操作_回调函数_02


4 直线的绘制

1 回调函数

绘制直线,其实就是绘制数学上的线段,通过两个点控制线段,鼠标点击的位置是线段的一个端点,释放的位置为直线的另一个端点:


import cv.cv2 as cv
import numpy as np
from random import *


def draw_line(event,x,y,flags,param):
global ix,iy,drawing
b = randint(0, 255)
g = randint(0, 255)
r = randint(0, 255)
if event == cv.EVENT_LBUTTONDOWN:
ix,iy = x,y
elif event == cv.EVENT_LBUTTONUP:
cv.line(img,(ix,iy),(x,y),(b,g,r),2)


2 其他代码及执行结果

代码如下:


drawing = False
ix = 0
iy = 0
img = np.ones((512,762,3), np.uint8)*255 #创建一个白色背景的图片


winname = "Drawing board"
cv.namedWindow(winname)
cv.setMouseCallback(winname,draw_line)
while(1):
cv.imshow(winname,img)
if cv.waitKey(20) & 0xFF == 27:
break
cv.destroyAllWindows()


执行结果如下:


【OpenCV教程】07 鼠标控件基本操作_右键_03


说在后面的话

这篇文章到这里就要结束啦,希望大家能够通过这篇文章,能够了解鼠标的操作函数,了解鼠标的几个基本操作并能熟练应用!


例子举不完,我们还可以用类似的方法构建多边形、构建椭圆,构建非填充图形,我们可以做一个简化版的画图出来。只不过,这是在基础教程中,我们带领大家通过简单的示例,快速入门。


让我们在后续的课程中,再接再厉,学习更多知识吧。



【OpenCV教程】07 鼠标控件基本操作_右键_04