Mouse as a Paint-Brush
Goal
- Learn to handle mouse events in OpenCV
- You will learn these functions : cv.setMouseCallback()
- 学习如何在OpenCV中处理鼠标事件
- 你将学习这些函数: cv.setMouseCallback()
Simple Demo
Here, we create a simple application which draws a circle on an image wherever we double-click on it.
First we create a mouse callback function which is executed when a mouse event take place. Mouse event can be anything related to mouse like left-button down, left-button up, left-button double-click etc. It gives us the coordinates (x,y) for every mouse event. With this event and location, we can do whatever we like. To list all available events available, run the following code in Python terminal:
这里,我们创建了一个简单的应用,当我们双击的时候,在一张图片上画一个圆。
首先我们创建一个鼠标的回调函数,当一个鼠标事件发生时该函数执行。鼠标事件可以是任何和鼠标相关的事件,比如左键按下,左键松开,双击左键等等。它为我们提供每个鼠标事件的坐标(x,y)。有了事件和坐标,我们可以做任何我们想做的。想要列出所有可用的可用事件,在Python终端运行下列代码:
import cv2 as cv
events = [i for i in dir(cv) if "EVENT" in i]
print(events)
Creating mouse callback function has a specific format which is same everywhere. It differs only in what the function does. So our mouse callback function does one thing, it draws a circle where we double-click. So see the code below. Code is self-explanatory from comments :
创建鼠标回馈函数有一个明确的在各处都一样的格式。它仅在功能上有所不同。所以我们的鼠标回馈函数做一件事,它在我们鼠标双击之处画一个圆。看看下面的代码。代码从注释就是一目了然的:
import numpy as np
import cv2 as cv
#mouse callback function
def draw_circle(event,x,y,flags,param);if event == cv.EVENT_LBUTTONBLCLK:CV.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)
cv.namedWindow("image")
cv.setMouseCallback("image",draw_circle)
while(1):cv.imshow("image",img)if cv.waitKey(20)&0xFF ==27;breakcv.destroyAllWindows()
More Advanced Demo
Now we go for a much better application. In this, we draw either rectangles or circles (depending on the mode we select) by dragging the mouse like we do in Paint application. So our mouse callback function has two parts, one to draw rectangle and other to draw the circles. This specific example will be really helpful in creating and understanding some interactive applications like object tracking, image segmentation etc.
现在我们寻找一个更好的应用。在这,我们靠拖拽鼠标来画矩形或者圆(取决于我们选择的模式),就像我们在绘画应用中一样。所以我们的鼠标回调函数有两部分,一部分画矩形,另一部分画圆圈。这个明确的应用将对创建和理解一些交互式应用非常有帮助,比如目标跟踪 ,图像分割等等。
import numpy as np
import cv2 as cvdrawing = 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,modeif event == cv.EVENT_LBUTTONDOWM:drawing = Trueix,iy =x,yelif event == cv.EVENT_MOUSEMOVE:if drawing == True:if mode == True:cv.rectangle(img,(ix,iy),(x,y),(0,0,255),-1)else:cv.circle(img,(x,y),5,(0,0,255),-1)elif event == cv.EVENT_LBUTTONUP:drawing == Falseif mode == True:cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)else:cv.circle(img,(x,y),5,(0,0,255),-1)
Next we have to bind this mouse callback function to OpenCV window. In the main loop, we should set a keyboard binding for key ‘m’ to toggle between rectangle and circle.
接下来我们将绑定鼠标回调函数到OpenCV的窗口。在主循环中,我们应该设置绑定一个健”m“来切换矩形和圆。
img = np.zeros((512,512,3),np.uint8)
cv.nameWindow("image")
cv.setMouseCallback("image",draw_circle)while(1):cv.imshow("image",img)k = cv.waitKey(1)&0xFFif k == ord("m"):mode = not modeelif k == 27breakcv.destroyAllWindows()
Additional Resources
Exercises
- In our last example, we drew filled rectangle. You modify the code to draw an unfilled rectangle.
在我们的上个例子中,我们画填满的矩形。你修改代码来画一个没有填满的矩形。