2011-07-21 7 views
8

Obligatorio - Soy un novato. Tener un trabajo que implique programación y me enseño a mí mismo sobre la marcha. Huelga decir que como profesor consigo las cosas mal con frecuencia y a fondo.OpenCV 2.3 con VS 2008 - Mouse Eventos

Donde estoy ahora: creé la clase "Gráfico", sorprendentemente hace gráficos. Pero ahora quiero hacerlo de modo que con un clic del mouse modifique el gráfico. Pero parece que no puedo obtener un controlador de mouse para que sea una función miembro de la clase.

cv::setMouseCallback(windowName, onMouse, 0); // Set mouse handler to be onMouse 

no funciona con

cv::setMouseCallback(windowName, Graph::onMouse, 0); 

Me da la falta de errores de parámetros. De acuerdo con this no puedo hacer que sea una función miembro. Después de seguir la respuesta dada, se compila, pero mi puntero this se anula. Ugh.

OnMouse se ve así:

void onMouse(int event, int x, int y,int, void*) 
{ 
    if (event == CV_EVENT_LBUTTONDOWN) 
    { 
     cvMoveWindow("Window", 500, 500); //Just to see if stuff happened 
    } 
    return; 
} 

No me importa acerca de cómo mover la ventana, que desea modificar el gráfico en sí - que se almacena como una variable de cv :: Mat en un objeto gráfico. Y no puedo entender cómo hacerlo.

Cualquier ayuda sería apreciada, y realmente espero que esto no sea solo un galimatías.

+0

¡buena pregunta! Tengo exactamente el mismo problema –

Respuesta

11

Sí, las funciones de devolución de llamada en C++ son una alegría, ¿verdad? De hecho, tienes que darle a OpenCV una función (no un método de clase) como ya has descubierto. Sin embargo, se puede hackear alrededor de este horror usando la siguiente técnica:

class MyClass 
{ 
public: 
    void realOnMouse(int event, int x, int y, int flags) 
    { 
     // Do your real processing here, "this" works fine. 
    } 
}; 

// This is a function, not a class method 
void wrappedOnMouse(int event, int x, int y, int flags, void* ptr) 
{ 
    MyClass* mcPtr = (MyClass*)ptr; 
    if(mcPtr != NULL) 
     mcPtr->realOnMouse(event, x, y, flags); 
} 

int main(int argv, char** argc) 
{ 
    // OpenCV setup stuff... 

    MyClass processor; 
    cv::setMouseCallback(windowName, wrappedOnMouse, (void*)&processor); 

    // Main program logic 

    return 0; 
} 

Ese último parámetro en setMouseCallback es bastante útil para superar algunos de los problemas que suelen encontrar como este.

+0

¡Impresionante! Gracias. Como estoy llamando a setMouseCallback desde una función miembro de Graph, cambié & processor a "this" y funciona muy bien. – Russbear

+0

¿es posible separar el mouseCallback y la persona que llama, me refiero a setMouseCallback, para ser parte de la clase y no en el programa principal? Creo que es más conveniente hacer que la clase tenga la función del mouse por sí misma. ¿¿posible?? ¡Gracias! –

1

También puede usar el método onMouse como método estático.

class Graph 
{ 
public: 
    static void onMouse(int event, int x, int y, void* param) 
    { 
      //Your code here 
    } 

    //Everything else you may need 
} 

Ahora usted debería ser capaz de llamar al método onMouse con:

cv::setMouseCallback(windowName, onMouse, (void*) param); 

El parámetro puede ser NULL o lo que usted quiere pasar como parámetro al método, pero tendrá que hacer un tipo de conversión al tipo deseado.

Espero que esto haya sido útil. Adiós.

Cuestiones relacionadas