¿Quien es el culpable el Thread o cvCam?

Estoy implementando una DLL para el asunto de mi tesis, eso de reconocer los gestos de manera monocular. Para ello necesito que mi programa sea una DLL que va a cargarse en otro programa al cual no tengo ningun acceso (uhm Closed Source, si!, maldicion!). Bueno, ya logré que se cargue, estuve analizando la DLL antigua y logré que mi DLL embonara en lo que el programito me pide.

Basicamente mi DLL debe exportar una única función importante la cual entrega coordenadas 3D. La primera vez que es llamada debe inicializarse sola y comenzar el rastreo. El modo de funcionamiento es el siguiente:

  1. (*) Aplicación pide coordenadas
  2. DLL debe:
    1. Si es primera vez. Responde (0,0,0) y lanza Thread par comenzar rastreo.
    2. Si no es primera vez. Responde con (x,y,z). El thread debería tenerlas ya detectadas.
    3. Avisar al thread cuando debe morirse.
  3. Ir a: (*)

El trabajo del Thread es el siguiente:

  1. Abrir cámara con resolución correcta (o morirse diciendo que no hay cámaras).
  2. Para cada FRAME capturado:
    1. Detectar objeto y obtener sus coordenadas.
    2. Actualizar variable global: coord = (x,y,z).  (global solo en la DLL)
  3. En caso  de aviso de muerte:
    1. Cerrar cámara correctamente
    2. Morirs y liberar recursos

Parece  muy fácil. Aja!, tengo varios dias atorado en la manera de anunciar al Thread que ya debe morirse. No se si sea OpenCV el que no cierra la cámara o el Thread que no se muere. Ya me estoy hartando, y lo malo es que estaba acostumbrado a que en Linux y OSS en general hay forums de IRC donde ayudan, pero busqué en freenet y no encontré nada decente para ambientes de Microsoft.

Si alguien sabe algo, avisenme. Estoy usando algo como esto:

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved ){
    switch (ul_reason_for_call)    {
    case DLL_PROCESS_ATTACH:
        hthread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)threadInit, NULL , 0, &threadId);
        break;
    case DLL_THREAD_ATTACH:       
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:                  
        shutdown = 1;
        hEvent = CreateEvent(NULL,FALSE,FALSE,(LPCWSTR)"Test");
        WaitForSingleObject(hEvent,INFINITE);
        CloseHandle(hEvent);
        CloseHandle(hthread);
        cvDestroyAllWindows();
        break;
    }

Y en la función del Thread es algo extremadamente simple también:

void threadInit(){
 int ncams = cvcamGetCamerasCount()
 fprintf(stderr,"\nDetected cams: [%i]", ncams);
 var_have_camera = ncams;
 if (ncams > 0){
 	cvNamedWindow("Video");
 	window = (HWND)cvGetWindowHandle( "Video" );
 	cvcamSetProperty(0, CVCAM_PROP_WINDOW, &window);
 	cvcamSetProperty(0, CVCAM_PROP_ENABLE, CVCAMTRUE);
 	cvcamSetProperty(0, CVCAM_RNDWIDTH, &var_video_w);
 	cvcamSetProperty(0, CVCAM_RNDHEIGHT, &var_video_h);
 	cvcamSetProperty(0, CVCAM_PROP_CALLBACK, process_frame );
 	cvcamInit();
 	cvcamStart();
 	while (shutdown!=1){
 		cvWaitKey(1);
	}
 	cvcamStop();
 	cvcamExit();
 }
 SetEvent(hEvent);
 ExitThread(0);
 return;
}

De manera interesante si quito el while y lo cambio por un simple WaitKey(1000) todo sale bién pues el thread se cierra y el programa libera recursos de manera correcta. Al parecer la variable shutdown no se pone a 1 y al salir, el programa no libera nada y la aplicacion cierra su ventana pero el proceso sigue corriendo y hay que matarlo usando el  Administrador de Tareas de Windows.

0 Responses to “¿Quien es el culpable el Thread o cvCam?”


  1. No Comments

Leave a Reply