检测两张图像之间的差异

我正在处理以下代码

#include <iostream>#include <opencv2/core/core.hpp>#include <string>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/video/background_segm.hpp>using namespace std;using namespace cv;int main(){    Mat current,currentGrey,next,abs;    VideoCapture cam1,cam2;    std:: vector<vector<Point>>contours;    vector<vector<Point>>contoursPoly(contours.size());    cam1.open(0);    cam2.open(0);    namedWindow("Normal");    namedWindow("Difference");    if(!cam1.isOpened())    {        cout << "Cam not found" << endl;        return -1;    }    while(true)    {        //Take the input        cam1 >> current;        currentGrey = current;        cam2 >> next;        //Convert to grey        cvtColor(currentGrey,currentGrey,CV_RGB2GRAY);        cvtColor(next,next,CV_RGB2GRAY);        //Reduce Noise        cv::GaussianBlur(currentGrey,currentGrey,Size(0,0),4);        cv::GaussianBlur(next,next,Size(0,0),4);        imshow("Normal",currentGrey);        //Get the absolute difference        absdiff(currentGrey,next,abs);        imshow("Difference",abs);       for(int i=0;i<abs.rows;i++)        {            for(int j=0;j<abs.cols;j++)            {                if(abs.at<int>(j,i)>0)                {                    cout << "Change Detected" << endl;                    j = abs.cols+1;                    i = abs.rows+1;                }            }        }        if(waitKey(30)>=0)        {            break;        }    }}

在这里,我试图在检测到图像之间的差异时打印一条消息。以下是技术部分

for(int i=0;i<abs.rows;i++)            {                for(int j=0;j<abs.cols;j++)                {                    if(abs.at<int>(j,i)>0)                    {                        cout << "Change Detected" << endl;                        j = abs.cols+1;                        i = abs.rows+1;                    }                }            }

遗憾的是,它并不是在检测到差异时才打印消息,而是总是打印消息。这是为什么呢?


回答:

您应该计算两帧之间的均方误差。

MSE = sum((frame1-frame2)^2 ) / 像素数量

OpenCV教程中有一个计算它的例子。

基于那个代码,您可以有以下内容

double getMSE(const Mat& I1, const Mat& I2){    Mat s1;    absdiff(I1, I2, s1);       // |I1 - I2|    s1.convertTo(s1, CV_32F);  // 不能对8位数进行平方运算    s1 = s1.mul(s1);           // |I1 - I2|^2    Scalar s = sum(s1);         // 按通道求和元素    double sse = s.val[0] + s.val[1] + s.val[2]; // 求和通道    if( sse <= 1e-10) // 对于小值返回零        return 0;    else    {        double  mse =sse /(double)(I1.channels() * I1.total());        return mse;        // 教程代码返回PSNR(如下),而不是返回MSE。        //double psnr = 10.0*log10((255*255)/mse);        //return psnr;    }}

您可以在代码中这样使用它:

   if(getMSE(currentGrey,next) > some_threshold)        cout << "Change Detected" << endl;

由您决定在什么样的MSE值以下认为图像是相同的。您还应该像您已经做的那样使用GaussianBlur()来预先过滤以减少噪声。@fatih_k建议的blur方法并不是高斯滤波器;它是一个方框滤波器,虽然速度更快,但可能会引入伪影。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注