检测2张图像之间的差异 [英] Detecting difference between 2 images
问题描述
我正在处理以下代码
#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屋!