PsP
PsP

Reputation: 696

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.

Upvotes: 0

Views: 486

Answers (1)

Haris
Haris

Reputation: 14053

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.

Upvotes: 1

Related Questions