2013-05-06 2 views
2

Я хотел бы написать программу, которая в своей простейшей форме открывает окно, показывающее захват веб-камеры с использованием OpenCV и печать координат курсора мыши, зависающего над окном в терминале. Для этого я хочу использовать функцию обратного вызова. Моя проблема в том, что эта функция обратного вызова не работает. Я не получаю никаких сообщений об ошибках при запуске программы, но ничего не происходит, когда я наводил курсор на окно камеры.Использование обратных вызовов событий мыши в классах Python

Я подозреваю, что причиной этого может быть то, что моя функция обратного вызова находится в классе CallBack и что cv.SetMouseCallback не может получить к нему доступ или что-то в этом роде. Я новичок как в OpenCV, так и в функциях обратного вызова, поэтому любые предложения по моей проблеме или тому, что мне не хватает здесь, будут оценены.

Этот упрощенный код приведен ниже для справки. Заранее спасибо.

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() 
+1

Если это ваш фактический код, он ничего не сделает, потому что _everything_, даже часть 'if __name__', находится внутри определения' class'. Это верно? – abarnert

+0

Боковые заметки: (1) Всегда создавайте классы нового стиля ('class CallBack (object):'). (2) Не добавляйте дополнительные парсеры вокруг вещей, таких как условия 'if'; он бросает опытных читателей Python и заставляет их задаться вопросом, почему вы думали, что это необходимо (есть ли какой-либо приоритет оператора, который нужно переопределить, или кортеж или генкс или?). – abarnert

+0

Также, как вы знаете, что это не вызов 'on_mouse'? Вы только «печатаете» что-нибудь внутри 'if'. Что если проблема в том, что у вас неправильные параметры, или «событие» - это не то, что вы ожидали? Он будет выглядеть точно так же, как не называть ваш код вообще, не так ли? – abarnert

ответ

4

Я нашел причину такого поведения. Оказывается, я должен добавить

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

в конце while-loop. Причина, по-видимому, (из того, что я нашел), что цикл будет ждать 10 миллисекунд для нажатия клавиши escape. Если в течение этого времени не будет нажата клавиша эвакуации, цикл продолжится, вызывается cv.SetMouseCallback, и self.on_mouse будет работать как следует. Если cv.WaitKey()не, вызываемый в конце цикла while, программа застрянет в cv.ShowImage -колл, никогда не вызывать cv.SetMouseCallback и, следовательно, никогда не выполнять self.on_mouse.

Обновленный упрощенный код будет таким, как показано ниже.

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() 

Для получения дополнительной информации обратитесь к this page.

Смежные вопросы