Click here to Skip to main content
15,890,282 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, Dear Coders,

I had a project: grab an image, then process the image.
Process like this:
1)In thread 1(file1.c): ... -> grab image start -> wait for grab finished flag -> process image -> ...
2)In thread 2 (file2.c): grab image, need call the camera API to grab image; when grab finished, set the grab finished flag on;
3)In file3.c: grab image API

My problem is: failed to get the grab finished flag.

Below is my code snippets:

a) file1.c: image grab & processing

C#
//grab image
DWORD dwRet=0.0;
SetEvent(st3SnapStartEv);
//printf("send out snap start signal 1\n");
dwRet=WaitForSingleObject(st3SnapEndEv,1000.0);
switch(dwRet)
{
    case WAIT_FAILED:
        sprintf(tmp,"%s","Snapping St3 image failed");
        WriteSt3ErrorLog(tmp);
        break;
    case WAIT_TIMEOUT:
        sprintf(tmp,"%s","Snapping St3 image timeout");
        WriteSt3ErrorLog(tmp);
        break;
    case WAIT_OBJECT_0:
        break;
}
//printf("snap image 1 finished\n");


b)file2.c: image grabbing thread

C#
DWORD WINAPI St3SnapImageThread(LPVOID arg)
{
	int retV=0; 
	double starttime,endtime;
	char tmp[128]="";
	char logMsg[128]=""; 
	DWORD dwRet;
	
	//printf("I am in St3SnapImageThread...\n");
	while(1)
	{
		ProcessSystemEvents();
		
		ProcessDrawEvents();
		
		dwRet=WaitForSingleObject(st3SnapStartEv,INFINITE);
		switch(dwRet)
		{
			case WAIT_FAILED:
				EnterCriticalSection(GetLogFileCS());
				sprintf(logMsg,"%s \t %s \n",TimeStr(),"wait for St3 snap start signals failed");
				WriteLogFile(logMsg);
				LeaveCriticalSection(GetLogFileCS());
				break;
			case WAIT_TIMEOUT:
				break;
			case WAIT_OBJECT_0:
				//printf("Snap St3 image in\n");
				EnterCriticalSection(GetLtControllerCS());
				OpenSt3BarLight(gparam.st3cam.barlightVal);
				LeaveCriticalSection(GetLtControllerCS());
	
				Delay(0.1);
		
				GetCurrentDateTime(&starttime);
				
				EnterCriticalSection(GetCameraCS());  
				retV=SnapMyImage(ST3CAM);
				LeaveCriticalSection(GetCameraCS());
		
				while(!IsSnapOK(ST3CAM))
				{
					GetCurrentDateTime(&endtime);
					if((endtime-starttime) > 1.0)
					{
						sprintf(tmp,"%s %lf, return value=%d","St3SnapImageThread:ST3 image snapping time cost=",(endtime-starttime),retV);  
						WriteSt3ErrorLog(tmp);
						break;
					}
					DelayWithEventProcessing(0.005);	
				}
				EnterCriticalSection(GetLtControllerCS());  
				CloseSt3BarLight();
				LeaveCriticalSection(GetLtControllerCS()); 
		
				SetEvent(st3SnapEndEv);
				break;
		}
	
		ProcessSystemEvents();
		
		ProcessDrawEvents();
		
		if (GetExitThreadsStatus())					//this part used when we click the 'Close' button on top-right corner 
		{
			EnterCriticalSection(GetLogFileCS());
			sprintf(logMsg,"%s \t %s \n",TimeStr(),"got exit signal in St3 image snapping thread");
			WriteLogFile(logMsg);
			LeaveCriticalSection(GetLogFileCS());
			break; 
		}
	}
	
	return 0;
}


c)file3.c: using API provided by camera vendor to grab an image
C#
int SnapMyImage(int camId)
{
    if (0 == avtcam[camId])
    {
        if (OpenAVTCamera(camId) < 0)
        {
            return -1;
        }
    }

    mbSnapOK[camId] = 0;

    // Start capture engine on the host
    VmbCaptureStart( avtcam[camId] );

    if(camId==0)
        VmbCaptureFrameQueue( avtcam[camId] , &frames[camId], FrameDoneCallback1A );
    else
        VmbCaptureFrameQueue( avtcam[camId] , &frames[camId], FrameDoneCallback2A );

    // Start acquisition on the camera
    VmbFeatureCommandRun( avtcam[camId] , "AcquisitionStart" );

    return 0;
}


In above code, need call a callback function:
C#
FrameDoneCallback1A
;
C#
FrameDoneCallback2A
, as shown below:
C#
void VMB_CALL FrameDoneCallback1A( const VmbHandle_t hCamera , VmbFrame_t *pFrame )
{
    if (VmbFrameStatusComplete == pFrame ->receiveStatus)
    {
        imaqArrayToImage(SourceImage[0], pFrame->buffer, pFrame->width, pFrame->height);
        imaqResample (DestImage[0], SourceImage[0], mnwndWidth[0], mnwndHeight[0], IMAQ_ZERO_ORDER, IMAQ_NO_RECT);

        DisplayMyImage(mnwnd[0], DestImage[0]);;

        mbSnapOK[0] = 1;
        //printf("Snap 0 OK\n");

        if (avtcam[0])      //handle is available
        {
            VmbFeatureCommandRun( avtcam[0] , "AcquisitionStop" );
            VmbCaptureEnd(avtcam[0]);
        }
    }
    else
    {
        VmbCaptureFrameQueue( hCamera , pFrame , FrameDoneCallback1 );
        //printf("Snap 0 failed, try again\n");
    }
}


As we will check snapping status in file2.c:
C#
while(!IsSnapOK(ST3CAM))

So I provide function
C#
IsSnapOK(int camId)
in file3.c as:
C#
int IsSnapOK(int camNum)
{
    return mbSnapOK[camNum];
}


My problem: In single thread, grab single image will be finished in 0.3s, but in multithread (10 threads in total), I will received this line each time:
St3SnapImageThread:ST3 image snapping time cost=1.0320

which means image grabbing will cost more than 1s.

I checked the image grabbed, it is correct.

If In enlong the timeout from 1.0s to 3.0s, the log file will shown as:
St3SnapImageThread:ST3 image snapping time cost=3.036

which means image grabbing will cost more than 3s.

I wonder: why I failed to get the grabbing status: mnSnapOk[0], mnSnapOk[1]?

A): Can you show me why I failed on this?
B): How can I fix this issue?

May I show my problem clearly.
Thank you very much.
Posted
Comments
KarstenK 14-Jul-15 9:24am    
Can it be that your image grabbing is single threaded? Starting some threads also means overhead. You better make a sound concept which tasks to outsource in threads and which one only gets quequeded. Only one image grabbing and one file processing thread with queues to avoid statup and shutdown of API/dlls ?
yuzaihuan 14-Jul-15 20:24pm    
Hi, Karstenk, thanks for your attention.

I am not quite understand what your said. Could you show more detail?

In this project, I had two seperate cameras (two seperate threads/files, same as file1.c); image grabbing finished by two similar & seperate threads (in file2.c); of course, in file3.c, I provided two seperate call-backs, two seperate image buffers, two flags (mbSnapOk[0],mbSnapOk[1]).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900