5

I'd like to write a program that in its simplest form opens a window showing a webcam capture using OpenCV and printing the coordinates of the mouse cursor hovering over the window in terminal. For this i want to use a callback function. My problem is that this callback function does not seem to run. I do not get any error messages when running the program, but nothing seem to happen when I hover my cursor over the camera window.

I suspect that the cause for this might be that my callback function is in the class CallBack, and that cv.SetMouseCallback cannot access it or something. I am new to both OpenCV and callback functions, so any suggestions on what my problem might be or what I'm missing here would be appreciated.

My simplified code is shown below for reference. Thanks in advance.

import cv

class CallBack:

    def __init__(self):
        cv.NamedWindow("Camera", cv.CV_WINDOW_AUTOSIZE );
        self.capture = cv.CaptureFromCAM(0)

    def on_mouse(self,event, x, y, flag, param):
        if(event == cv.CV_EVENT_MOUSEMOVE):
            print param
            print x,y

    def callback(self):
        while True:
            src = cv.QueryFrame(self.capture)
            s = "Hello World"
            cv.SetMouseCallback("Camera",self.on_mouse, param = s)
            cv.ShowImage("Camera", src)

if __name__ == '__main__':
    cb = CallBack()
    cb.callback()
7
  • 1
    If this is your actual code, it won't do anything at all, because everything, even the if __name__ part, is inside the class definition. Is that correct? Commented May 6, 2013 at 22:20
  • Side notes: (1) Always create new-style classes (class CallBack(object):). (2) Don't put extra parens around things like if conditions; it throws off experienced Python readers and makes them wonder why you thought it was necessary (is there some operator precedence that needs to be overridden? or a tuple or genexp? or …). Commented May 6, 2013 at 22:22
  • Also, how do you know that it's not calling on_mouse? You only print anything inside the if. What if the problem is that you've got the params wrong, or the event isn't what you expected? It would look exactly the same as not calling your code at all, right? Commented May 6, 2013 at 22:25
  • Finally: "I suspect that the cause for this might be that my callback function is in the class CallBack, and that cv.SetMouseCallback cannot access it or something." Nope, that's not it. When you do self.on_mouse, that gives you a bound method, which anyone (including cv.SetMouseCallback) can just treat as a callable and call. It doesn't need any special access. (And even if it did, all methods are "public" in Python, so that wouldn't be a problem.) Commented May 6, 2013 at 22:28
  • One more thing: Are you sure the camera window is active/focused/whatever-the-appropriate-term-is-for-your-platform? Often background windows don't get mouse events unless they do something special, and it's reasonable that OpenCV might not do that something special. (Sorry I can't be more specific, but I don't know what platform you're on.) Commented May 6, 2013 at 22:30

1 Answer 1

5

I found the reason for this behavior. Turns out I have to add a

if cv.WaitKey(10) == 27:
    break

at the end of the while-loop. The reason seems to be (from what I have found) that the loop will now wait for 10 milliseconds for the escape-key to be pressed. If the escape-key is not pressed during this time, the loop will continue, cv.SetMouseCallback is called and self.on_mouse will run as it should. If the cv.WaitKey() is not called at the end of the while-loop, the program will get stuck in the cv.ShowImage-call, never call cv.SetMouseCallback and thus never execute self.on_mouse.

The updated simplified code will be as shown below.

import cv

class CallBack:

    def __init__(self):
        cv.NamedWindow("Camera", cv.CV_WINDOW_AUTOSIZE );
        self.capture = cv.CaptureFromCAM(0)

    def on_mouse(self,event, x, y, flag, param):
        if(event == cv.CV_EVENT_MOUSEMOVE):
           print param
           print x,y

    def callback(self):
        while True:
             src = cv.QueryFrame(self.capture)
             s = "Hello World"
             cv.SetMouseCallback("Camera",self.on_mouse, param = s)
             cv.ShowImage("Camera", src)

             if cv.WaitKey(10) == 27:
                  break

if __name__ == '__main__':
    cb = CallBack()
    cb.callback()

Refer to this page for more information.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.