Cómo utilizar cvSetMouseCallback de forma elegante en MFC
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;