Reputation: 5432
I'm trying to get the the difference between two cv::Mat frames in OpenCv. So here is what I tried,
#include<opencv2\opencv.hpp>
#include<opencv2\calib3d\calib3d.hpp>
#include<opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
int main ()
{
cv::VideoCapture cap(0);
cv::Mat frame, frame1,frame2;
int key=0;
while(key!=27){
cap >> frame;
if(key=='c'){
frame1 = frame;
key = 0;
}
if(key =='x'){
cv::absdiff(frame, frame1, frame2); // I also tried frame2= (frame -frame1)*255;
cv::imshow("difference ",frame2);
key =0;
}
cv::imshow("stream",frame);
key = cv::waitKey(10);
}
}
the result is always the same a 0 Matrix, any idea what I'm doing wrong here? thanks in advance for your help.
Upvotes: 3
Views: 13892
Reputation: 131
I was looking for a similar program and I came across your post, here is a sample I have written for frameDifferencing, hope this helps, the below function will give you the difference between two frames
/** @function differenceFrame */
Mat differenceFrame( Mat prev_frame, Mat curr_frame )
{
Mat image = prev_frame.clone();
printf("frame rows %d Cols %d\n" , image.rows, image.cols);
for (int rows = 0; rows < image.rows; rows++)
{
for (int cols = 0; cols < image.cols; cols++)
{
/* printf("BGR value %lf %lf %lf\n" , abs(prev_frame.at<cv::Vec3b>(rows,cols)[0] -
curr_frame.at<cv::Vec3b>(rows,cols)[0]),
abs(prev_frame.at<cv::Vec3b>(rows,cols)[1] -
curr_frame.at<cv::Vec3b>(rows,cols)[0]),
abs(prev_frame.at<cv::Vec3b>(rows,cols)[2] -
curr_frame.at<cv::Vec3b>(rows,cols)[0]));
*/
image.at<cv::Vec3b>(rows,cols)[0] = abs(prev_frame.at<cv::Vec3b>(rows,cols)[0] -
curr_frame.at<cv::Vec3b>(rows,cols)[0]);
image.at<cv::Vec3b>(rows,cols)[1] = abs(prev_frame.at<cv::Vec3b>(rows,cols)[1] -
curr_frame.at<cv::Vec3b>(rows,cols)[1]);
image.at<cv::Vec3b>(rows,cols)[2] = abs(prev_frame.at<cv::Vec3b>(rows,cols)[2] -
curr_frame.at<cv::Vec3b>(rows,cols)[2]);
}
}
return image;
}
Upvotes: 0
Reputation: 9379
OpenCV overloads the affectation operator on cv::Mat
objects so that the line mat1 = mat2
only affects the pointer to the data in mat1
(that points to the same data as mat2
). This avoids time consuming copies of all the image data.
If you want to save the data of a matrix, you have to write mat1 = mat2.clone()
or mat2.copyTo(mat1)
.
Upvotes: 4
Reputation: 6757
The documentation of the Mat type states:
Mat is basically a class with two data parts: the matrix header and a pointer to the matrix containing the pixel values. [...] Whenever somebody copies a header of a Mat object, a counter is increased for the matrix. Whenever a header is cleaned this counter is decreased. When the counter reaches zero the matrix too is freed. Sometimes you will want to copy the matrix itself too, so OpenCV provides the clone() and copyTo() functions.
cv::Mat F = A.clone();
cv::Mat G;
A.copyTo(G);
Upvotes: 7
Reputation: 1055
Mat objects are pointer typed. After setting frame1 to frame directly using frame1 = frame, both matrices show the same point and same frame also. You have to copy frame value using "copyTo" method of Mat.
Upvotes: 11