Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Semaphore based synchronization for opencv based image processing

I am trying to use semaphores to synchronize two threads of OpenCV image processes. One thread keeps capturing frames from the webcam and pushes it into a circular buffer and the other stream pulls an image from the buffer and processes them. I am deleting the frame that I use after I process them.

I am using boost circular buffer libraries to implement the buffer.

Please find the exact code snippet below. I have eliminated most part of the initialization and highlighting thats necessary. The problem that I am facing is that I am able to stream and capture my webcam's frames. But the window just freezes after sometimes. On some occasions, the captured frames are not displayed correctly. May I know where am I going wrong?

    sem_t semaphore;

  using namespace cvb;

  using namespace std;



  CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );

    IplImage* img0;

    IplImage* img1;

    sem_t semaphore;

   boost::circular_buffer<IplImage*> cb1(200);

   int ret = sem_init(&semaphore, 1, 10); //Initializing the semaphore


void* Capture(void* arg){    



       while(1) {           
                     sem_wait(&semaphore);

             img0 = cvQueryFrame( capture );        

             cb1.push_back(img0);

            cvShowImage( "mywindow", img0 );

            sem_post(&semaphore);


        if ( (cvWaitKey(10) & 255) == 27 ) break;

                } 



}

    void* ImageProcessing(void* arg) {      

                    while(1) {                          


            if(!cb1.empty()) {
                                   sem_wait(&semaphore);
                               img2 =  cvShowImage("result",img2);                      

                                   cb1.pop_front();          
                            sem_post(&semaphore);
                                }


                        if ( (cvWaitKey(10) & 255) == 27 ) break;

                        }   
                                cvReleaseCapture( &capture );

                                cvReleaseImage( &img2 );

                    }
like image 928
Sai Avatar asked Nov 13 '22 19:11

Sai


1 Answers

Capture and ImageProcessing are being run in different threads, aren't they? I once tried to update HighGui windows from different threads, but it didn't work.

This is actually a problem with most if not all windowing systems: you can't make calls from different threads to update a window.

Try putting both cvShowImage calls in the same thread. Calls to cvWaitKey probably have to be made from within the same thread too.

It may be the case that cvShowImage must be called in the same thread in which you initialize the windows using cvNamedWindow. I'm not sure about this, though.

like image 78
Jong Bor Lee Avatar answered Dec 05 '22 09:12

Jong Bor Lee