简体   繁体   中英

why a vector of cv::mat always return the first image?

I'm reading video frames from a webcam and storing them in a std::vector < cv::mat > variable.

Each time I want to calculate the frame difference between two consecutive frames, I use the following code but the result is always zero and I get a zero matrix !! I have two threads in my program, one for reading video frames and one for processing the video frames. whenever I'm going to write into the vector I use a mutex in order to prevent any further problems in pushing back or removing frames.

Here is my pseudo code :

std::vector<cv::Mat> IMAGE_VEC;
Qmutex IMAGE_VEC_MUTEX;
Main_Thread()
{

while(1)
{
 cv::Mat Frame,Reserved_Frame;
 Camera.read(Frame);
 Frame.copyTo(Reserved_Frame);
 QMutexLocker Locker(&IMAGE_VEC_MUTEX);
 IMAGE_VEC.pushback(Reserved_Frame);
 Locker.unlock();
 cv::imshow("Frame",Frame);
 cv::waitKey();
}
}

And My process Thread is:

Process_Thread()
{

  for (; IMAGE_VEC.size() > 1 ;)
{
      cv::Mat frame1;
      IMAGE_VEC[0].copyTo(frame1);
      cv::Mat frame2;
      IMAGE_VEC[1].copyTo(frame2);
      cv::subtract(frame1,frame2,result);
      QMutexLocker Locker(&IMAGE_VEC_MUTEX);
      IMAGE_VEC[0].release();
      //qDebug()<<"IMAGE_VEC Step2 size  is: "<<IMAGE_VEC.size()<<"\n";
      IMAGE_VEC.erase(IMAGE_VEC.begin());
      Locker.unlock();
}
}

I calculated the mean and standard deviation of each frame in Process thread and they were always the same ! I could solve this problem by changing the thread process code to this code

 Process_Thread()
{

  for (; IMAGE_VEC.size() > 1 ;)
{
      cv::Mat frame1;
      IMAGE_VEC[0].copyTo(frame1);
      QMutexLocker Locker(&IMAGE_VEC_MUTEX);
      IMAGE_VEC[0].release();
      //qDebug()<<"IMAGE_VEC Step2 size  is: "<<IMAGE_VEC.size()<<"\n";
      IMAGE_VEC.erase(IMAGE_VEC.begin());
      Locker.unlock();
      delay_ms(1000); // more than 1 second delay !!!
      cv::Mat frame2;
      IMAGE_VEC[0].copyTo(frame2);
      cv::subtract(frame1,frame2,result);

}
}

why this happens ? why a delay more than 1 second should be used to make this code work ? I tried it with a delay less than 1 second and the result were as previous step ...

I'd appreciate your comments on this.

You may need to copy or clone your frame to another Mat, then push to your vector, change your code like

 cv::Mat Frame;
 Camera.read(Frame);

 Mat tmp=Frame.clone(); //clone frame to new Mat
 IMAGE_VEC.pushback(tmp);

Otherwise you are passing same pointer on each pushback.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM