current position:Home>Fanwai 4 Handling of mouse events and solutions to common problems in Python opencv

Fanwai 4 Handling of mouse events and solutions to common problems in Python opencv

2022-01-30 18:42:11 Dream eraser

Little knowledge , Great challenge ! This article is participating in 「 A programmer must have a little knowledge 」 Creative activities

This article has participated in  「 Digging force Star Program 」 , Win a creative gift bag , Challenge creation incentive fund .

The way this series is written

This series of column writing will adopt the original question and answer writing form , Quickly let you learn OpenCV My primary 、 intermediate 、 Advanced knowledge .

4. Python OpenCV Mouse event related processing and solutions to common problems

This blog mainly analyzes cv2.setMouseCallback function , And how to solve the problems of this function in daily coding .

This function is mainly OpenCV Functions used to handle mouse related events in , It can capture the events triggered by data , And deal with it .

Before using this function , You can go through it first help Function lookup basic usage .

The prototype of this function is as follows :

setMouseCallback(windowName, onMouse [, param]) -> None
 Copy code 

You can see that the function has two parameters , One is the name of the window , The second is the callback function , Window name and cv2.imshow Just keep the names consistent in .

Through the function prototype , It can be seen that cv2.setMouseCallback Function is to set a callback function for the window .

OpenCV What events are there in the mouse ?

The code for viewing the event is as follows , With built-in functions dir Can be consulted .

import cv2

def show_event():
    events = [i for i in dir(cv2) if 'EVENT' in i]
    print(events)

if __name__ == "__main__":
    show_event()
 Copy code 

The operation results are as follows , All and event( Event related functions , It's all listed )

['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']
 Copy code 

In the above events , The most commonly used is EVENT_LBUTTONDOWN,EVENT_LBUTTONUP, Let's focus on .

EVENT_LBUTTONDOWN Left mouse button down event .

First render a form through the following code , Test the left mouse button press .

import cv2


def show_event():
    events = [i for i in dir(cv2) if 'EVENT' in i]
    print(events)


def mouse_handler(event, x, y, flags, userdata):
    if event == 1:   # cv2.EVENT_LBUTTONDOWN
        print(" Press the left mouse button ")


if __name__ == "__main__":

    image = cv2.imread("./tt.jpg")

    cv2.namedWindow("mouse_event")
    cv2.imshow("mouse_event", image)
    cv2.setMouseCallback("mouse_event", mouse_handler)
    cv2.waitKey()

 Copy code 

The code works as follows , Click the left mouse button on the picture , Data input will be carried out on the console , The output content is shown in the red box of the screenshot .

 Insert picture description here

The problem to be noticed at this time is , Even if you don't load any pictures , Just use nameWindow Named the form , Corresponding setMouseCallback The function will also bind successfully , The specific test code is as follows .

# image = cv2.imread("./tt.jpg")

cv2.namedWindow("mouse_event")
# cv2.imshow("mouse_event", image)
cv2.setMouseCallback("mouse_event", mouse_handler)
 Copy code 

From the above case , We can also draw the following inferences ,cv2.setMouseCallback The second parameter in the function callback function onMouse , Have a certain format , Because there is such a paragraph in the above code :

def mouse_handler(event, x, y, flags, userdata):
 Copy code 

This is actually for all mouse events , The format of callback functions is unified , Only the specific implementation inside the function is different .

The parameters are described as follows :

  • event: Mouse event name , Through this value, you can get what kind of event operation the mouse performs ;
  • x, y: The mouse operates the event for a moment , The coordinate position ;
  • flags: It means to be associated with event Relevant practices include FLAG Events ;
  • userdata: Parameters passed in when the mouse callback function is triggered .

The above parameters are very easy to understand , But at present, a lot of content on the Internet is right flags The parameters pass by , No explanation .

This parameter is actually a subset of all events we obtained above , Take a look at all the events obtained before .

['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']
 Copy code 

In which you focus on looking for flag Value , Search as follows :

'EVENT_FLAG_ALTKEY',
'EVENT_FLAG_CTRLKEY',
'EVENT_FLAG_LBUTTON',
'EVENT_FLAG_MBUTTON',
'EVENT_FLAG_RBUTTON',
'EVENT_FLAG_SHIFTKEY'
 Copy code 

Translate English a little , You can understand flags Parameters , For example, we want to drag while holding down the left mouse button , The core code is :

event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON
 Copy code 

Press and hold the keyboard CTRL At the same time , Press the left mouse button , The code is as follows

event == cv2.EVENT_LBUTTONUP and flags == cv2.EVENT_FLAG_CTRLKEY
 Copy code 

Next, let's realize how to hold down the left mouse button and drag , Draw a rectangle .

import cv2

image = cv2.imread("./tt.jpg")
cv2.namedWindow("mouse_event")
x1, y1 = 0, 0


def show_event():
    events = [i for i in dir(cv2) if 'EVENT' in i]
    print(events)


def mouse_handler(event, x, y, flags, userdata):
    global x1, y1
    if event == cv2.EVENT_LBUTTONDOWN:
        print(" Left click ")
        x1, y1 = x, y

    if event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
        # print(" Press and drag with the left mouse button ")
        cv2.rectangle(image, (x1, y1), (x, y), (0, 255, 0), -1)


if __name__ == "__main__":
    cv2.setMouseCallback("mouse_event", mouse_handler)
    while True:
        cv2.imshow("mouse_event", image)
        k = cv2.waitKey(1) & 0xFF
        if k == 27:
            break

    cv2.destroyAllWindows()
 Copy code 

The above code , The last parameter is not used userdata, Next, we apply this parameter by passing parameters .

The core can be modified in one place , stay cv2.setMouseCallback The image that the function part will read image Pass it to the callback function , As follows

cv2.setMouseCallback("mouse_event", mouse_handler, image)
 Copy code 

OpenCV Solution to capture mouse events in video

The above has implemented the capture of mouse events in the picture , Next, let's look at how to do the same in the video .

It has been known from previous knowledge , Video processing is to perform corresponding operations on each frame of video , That can be done according to the following code .

import cv2


def mouse_handler(event, x, y, flags, frame):

    if frame is not None:
        #  Get coordinates , Test use 
        # print(x, y)
        if event == cv2.EVENT_MOUSEMOVE:
            cv2.putText(frame, "Hello OpenCV", (x, y),
                        cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 0))
            cv2.imshow("video", frame)


if __name__ == "__main__":

    cap = cv2.VideoCapture("./test.mp4")
    while cap.isOpened():
        ret, frame = cap.read()
        if ret:
            cv2.imshow("video", frame)
            cv2.setMouseCallback("video", mouse_handler, frame)
            if cv2.waitKey(25) & 0xFF == 27:
                break

    cap.release()
    cv2.destroyAllWindows()
 Copy code 

The above code is bound to EVENT_MOUSEMOVE Incident , So when the mouse moves , There will be one Hello OpenCV The words... , However, this method will cause the video to render repeatedly , Not efficient , After several frequent refreshes , The page will crash .

If you just want to test , Can be cv2.waitKey(25) Set the number in to 1000, So the video playback speed will slow down , You can grab the final effect .

 Insert picture description here

For the learning of mouse callback function , The focus is still on events , Another thing to note is the calculation of combined button and mouse position , You can implement a simple... Based on this OpenCV Drawing board , Of course, the premise is that you are already familiar with the graphics drawing function you learned before .

Supplementary knowledge ,OpenCV Draw polygon

stay Last blog in , We are missing a function , Draw polygon , Here is a supplement , The function of cv2.polylines, The function prototype is as follows :

polylines(img, pts, isClosed, color[, thickness[, lineType[, shift]]]) -> img
 Copy code 

One of the most important parameters pts, This parameter represents the polyline array of the polygon to be drawn , It can also be understood as the vertex order coordinates of the polygon .

For example, the following code :

image = np.zeros((400, 400, 3), np.uint8)
points = np.array(
    [[50, 50], [170, 100], [200, 150], [300, 320]], np.int32)
cv2.polylines(image, [points], True, (255, 0, 0))
cv2.imshow('image',image)
cv2.waitKey()
 Copy code 

The polygons drawn are as follows :

 Insert picture description here

Last , You can combine this literature to cv2.setMouseCallback function , Plus the function of drawing a line , Implement a polygon manual drawing tool .

copyright notice
author[Dream eraser],Please bring the original link to reprint, thank you.
https://en.pythonmana.com/2022/01/202201301842100457.html

Random recommended