3

我试图找出 OpenCv 中两个 cv::Mat 帧之间的区别。所以这是我尝试过的,

 #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);
     }
  }

结果总是相同的 0 矩阵,知道我在这里做错了什么吗?在此先感谢您的帮助。

4

4 回答 4

11

Mat 对象是指针类型的。在使用 frame1 = frame 直接将 frame1 设置为 frame 后,两个矩阵也显示相同的点和相同的框架。您必须使用 Mat 的“copyTo”方法复制帧值。

于 2013-05-23T06:49:48.180 回答
7

OpenCV 矩阵在内部使用指针

Mat 类型的文档指出:

Mat 基本上是一个包含两个数据部分的类:矩阵头和指向包含像素值的矩阵的指针。[...] 每当有人复制 Mat 对象的标题时,矩阵的计数器就会增加。每当清除标头时,此计数器就会减少。当计数器达到零时,矩阵也被释放。有时您也想复制矩阵本身,因此 OpenCV 提供了 clone() 和 copyTo() 函数

cv::Mat F = A.clone();
cv::Mat G;
A.copyTo(G);
于 2013-05-23T06:56:10.847 回答
4

OpenCV 重载cv::Mat对象上的矫揉造作运算符,因此该行mat1 = mat2仅影响指向数据的指针mat1(指向与 相同的数据mat2)。这避免了所有图像数据的耗时副本。

如果你想保存矩阵的数据,你必须写mat1 = mat2.clone()or mat2.copyTo(mat1)

于 2013-05-23T06:57:13.233 回答
0

我正在寻找一个类似的程序,我遇到了你的帖子,这是我为 frameDifferencing 编写的一个示例,希望这会有所帮助,下面的函数将为您提供两个框架之间的差异

/** @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;
} 
于 2013-09-30T01:56:25.760 回答