检测2张图像之间的差异 [英] Detecting difference between 2 images

查看:88
本文介绍了检测2张图像之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理以下代码

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

}

在这里,我试图做的是每当检测到图像之间的差异时都打印一条消息.接下来的部分是技术

In here, what I am trying to do is print a message whenever a difference between images are detected. Following part is the technique

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

                }
            }

不幸的是,它不会在检测到差异时打印消息,而是始终打印消息.为什么是这样?

Unfortunately, instead of printing messages when a difference is detected, it prints the message always. Why is this?

推荐答案

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

You should calculate the mean square error between the two frames.

MSE = sum((frame1-frame2)^2 ) / no. of pixels

根据您可能拥有的代码

double getMSE(const Mat& I1, const Mat& I2)
{
    Mat s1;
    absdiff(I1, I2, s1);       // |I1 - I2|
    s1.convertTo(s1, CV_32F);  // cannot make a square on 8 bits
    s1 = s1.mul(s1);           // |I1 - I2|^2

    Scalar s = sum(s1);         // sum elements per channel

    double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels

    if( sse <= 1e-10) // for small values return zero
        return 0;
    else
    {
        double  mse =sse /(double)(I1.channels() * I1.total());
        return mse;
        // Instead of returning MSE, the tutorial code returned PSNR (below).
        //double psnr = 10.0*log10((255*255)/mse);
        //return psnr;
    }
}

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

You can use it in your code like this:

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

由您决定MSE的大小,低于该大小您认为图像是相同的.同样,您应该像以前一样使用 GaussianBlur()进行预过滤以减少噪声.@fatih_k建议的 blur 方法不是高斯滤波器.它是一种盒式过滤器,尽管速度更快可能会引入伪影.

It is up to you to decide the magnitude of MSE below which you consider the images to be the same. Also you should prefilter with GaussianBlur() to reduce noise, like you already do. The blur method suggested by @fatih_k is not a Gaussian filter; it is a box filter and although faster may introduce artifacts.

这篇关于检测2张图像之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆