Red de conocimiento informático - Material del sitio web - Cómo utilizar cvSetMouseCallback de forma elegante en MFC

Cómo utilizar cvSetMouseCallback de forma elegante en MFC

MFC y cvSetMouseCallback de opencv se sienten muy incompatibles cuando se usan.

Muchas veces, cvSetMouseCallback solo se puede usar para obtener un cuadro rectangular, dibujar un punto u otros gráficos simples. La información de los parámetros de la interacción del mouse se puede obtener llamando a esta función.

Sin embargo, un requisito tan simple no es muy conveniente para invocarlo en el marco MFC.

Al leer el código fuente de muestra proporcionado oficialmente por opencv, hay una clase GCApplication en grabcut, que se utiliza para controlar u obtener información de dibujo. Lo encuentro muy conveniente, así que lo simplificaré de la siguiente manera:

#Definición? ¿GC_BGD? 0 #definir? ¿GC_FGD? 1#Definición? ¿GC_PR_BGD? 2#Definición? ¿GC_PR_FGD? 3constante? ¿Escalar? ¿verde? =?escalar(0,255,0);clase? GCApp

{Público:

Enumeración{? ¿No estás configurado? =?0,?en proceso? =?1,?conjunto? =?2?};Público:

¿No válido? Clic del mouse (?int? event,?int?x,?int?y,?int?flag?void*?param?);

¿Nulo? setImageAndWinName(?const?Mat amp?_image,?const?string&string.?_winName);

¿No es válido? reset();

¿No es válido? mostrarImagen()? const public:

¿Recto? recto

Uchar? estadorect

const? Estera*? Imagen;

¿Mat? Máscara;

constante? Cadena*? winName

}; ¿no es válido? GCApp::reset()

{

if (?! mask.empty()?)

máscara setto(Scalar::all(GC _. BGD));

rectState? =?NOT _ SET

}¿No válido? GCApp::setImageAndWinName(?const?Mat&?_image,?const?string&string.

? _winName)

{

Si (?_image.empty()?||?_winName.empty()?)

Devolver;

Imagen? =? amp_ imagen

winName? =? amp_ winName

mask.create(?image-gt;size(),?CV_8uc1);

reset();

} ¿Nulo? GCApp::mostrarImagen()? constante {

if (?image->empty()?||?win name->empty()?)

return;

Mat ? res

Imagen - gt; copyTo(?res?);

if (?rectState?==?en proceso?||?rectState?==?set?)

p>

rectángulo(?res,?punto(?rect.x,?rect.y?),?punto(rect.x??ancho del rectángulo,?rect.y??alto del rectángulo?), ?verde? 2);

imshow(?*winName,?res?);

}¿No es válido? GCApp::MouseClick(?int?event,?int?x,?int?y,?int?flag?void*?)

{

Cambiar(?event? )

{

¿Caso? CV_EVENT_LBUTTONDOWN:? //?¿configuración? ¿recto? ¿aún? ¿GC_BGD(GC_FGD)? etiqueta

{

if (?rectState?==?not_set?)

{

rectState? =?En proceso;

rect? =?Rect(?x,?y,?1,?1?);

}

mostrarImagen();

}

Romper;

¿Caso? CV_EVENT_MOUSEMOVE:

Si (?rectState?==?Proceso?)

{

rect? =?Rect(?Point(rect.x,?rect.y),?Point(x,y)?);

showImage();

}

Rotura;

¿Caso? CV_EVENT_LBUTTONUP:

Si (?rectState?==?Proceso?)

{

rect? =?Rect(?Point(rect.x,?rect.y),?Point(x,y)?);

rectState? =?Set;

showImage();

Break;

}

}Debido a que cvSetMouseCallback necesita volver a llamar a la función on_mouse, declarar una función on_mouse.

¿Tenga en cuenta que debe ser estático?

¿GCApp? gcapp

¿Electricidad estática? ¿Vacío? Ratón encendido(?int?event,?int?x,?int?y,?int?flag?void*?param?)

{

gcapp.mouseClick(?event ,?

constante? ¿Cadena? ganarNombre? =?"draw region";

cvNamedWindow(?winName.c_str(),?CV_WINDOW_AUTOSIZE?);

cvSetMouseCallback(?winName.c_str(),?on_mouse,?0? );

gcapp.setImageAndWinName(?img,?winName?);

Aplicación GC . show image();

¿Para qué? (;;)

{

int? ¿do? =?cvWaitKey(0);

//////ESC? ¿llave? Fin

¿Y si? (char(c)?==?\x1b '? amp amp?gcapp.rectState?==?gcapp.set)

{

Rotura;

}

}

¿Correcto? ¿recto? =?Aplicación GC .rect;