opencv 实现YUV 图片差异对比

#include
#include 
#include
#include
//#include
#include
#include
#include
using namespace std;
using namespace cv;
//Hist 基于图片直方图做匹配
double CompareHist(Mat srcOneGray, Mat srcTwoGray);


double getPSNR(Mat srcOneGray, Mat srcTwoGray);
double CompareWithPSNR(Mat srcOneGray, Mat srcTwoGray);


Scalar  CompareWithSSIM(Mat i1, Mat  i2);


double CompareContour(Mat srcOneGray, Mat srcTwoGray);


double ComparePHashCode(Mat srcOneGray, Mat srcTwoGray);


double CompareWithORB(Mat srcOneGray, Mat srcTwoGray);


int mainmain() {
string imagefile1;
string imagefile2;
char *path = "picture2/";
for (int i = 1; i < 2; i++)
{
ostringstream oss1, oss2;
oss1 << path << "video" << i+1 << ".jpg";
oss2 << path << "video" << (i+455) << ".jpg";
imagefile1 = oss1.str();
imagefile2 = oss2.str();
cout << "file path 1 = " << imagefile1 << endl;
cout << "file path 2 = " << imagefile2 << endl;
Mat srcOne, srcOneGray, srcTwo, srcTwoGray;
srcOne = imread(imagefile1);
srcTwo = imread(imagefile2);


if (!srcOne.data || !srcTwo.data)           // Check for success
{
cout << "Couldn't read the image";
system("pause");
return 0;
}


cvtColor(srcOne, srcOneGray, COLOR_BGR2GRAY);
cvtColor(srcTwo, srcTwoGray, COLOR_BGR2GRAY);




cout << "(1) CompareHist start " << endl;
CompareHist(srcOneGray, srcTwoGray);
cout << "CompareHist end ! " << endl;


cout << "\n" << "(2) Compare PSNR start " << endl;
CompareWithPSNR(srcOneGray, srcTwoGray);  // 0 & 数据值越大相似度越高
cout << "Compare PSNR end ! " << endl;


cout << "\n" << "(3) Compare SSIM start " << endl;
CompareWithSSIM(srcOneGray, srcTwoGray);
cout << "Compare SSIM end ! " << endl;




cout << "\n" << "(4) Compare Contour start " << endl;
CompareContour(srcOneGray, srcTwoGray);
cout << "Compare Contour end ! " << endl;


cout << "\n" << "(5) Compare PHashCode start " << endl;
ComparePHashCode(srcOneGray, srcTwoGray);
cout << "Compare PHashCode end ! " << endl;


}
//cout<


/*
cout << "\n" << "(6) Compare CompareWithORB start " << endl;
CompareWithORB(srcOneGray, srcTwoGray);
cout << "Compare CompareWithORB end ! " << endl;*/


system("pause");
return 0;
}


double CompareHist(Mat srcOneGray, Mat srcTwoGray) {
Mat srcOneReSizeGray, srcTwoReSizeGray;
DWORD start, end;
start = GetTickCount();
int method1 = CV_COMP_CHISQR;  //值越小,说明图形越相似  CV_COMP_CHISQR = 1  CV_COMP_BHATTACHARYYA = 3
int method2 = CV_COMP_CORREL;  //值越大,说明图形越相似  CV_COMP_CORREL = 0  CV_COMP_INTERSECT = 2
MatND dstOneHist, dstTwoHist;
int dims = 1;
float hranges[] = { 0, 256};
const float *ranges[] = {hranges};
int size = 256;


resize(srcOneGray, srcOneReSizeGray, Size(864, 480));
resize(srcTwoGray, srcTwoReSizeGray, Size(864, 480));


calcHist(&srcOneReSizeGray, 1, 0, Mat(), dstOneHist, dims, &size, ranges);
calcHist(&srcTwoReSizeGray, 1, 0, Mat(), dstTwoHist, dims, &size, ranges);


normalize(dstOneHist, dstOneHist, 0, 1, NORM_MINMAX, -1, Mat());
normalize(dstTwoHist, dstTwoHist, 0, 1, NORM_MINMAX, -1, Mat());


double disc0 = compareHist(dstOneHist, dstTwoHist, CV_COMP_CORREL);
// double disc1 = compareHist(dstOneHist, dstTwoHist, CV_COMP_CHISQR);
// double disc2 = compareHist(dstOneHist, dstTwoHist, CV_COMP_INTERSECT);
double disc3 = compareHist(dstOneHist, dstTwoHist, CV_COMP_BHATTACHARYYA);
double disc = 0;
if (disc0 < 0)
{
disc0 = 0;
}
if (disc3 < 100 && disc3 > 0) {
disc = (disc0 * 100 + (100 - (disc3 * 100))) / 2.0;
}
else {
disc = disc0 * 100;
}
cout << "disc0 = " << disc0<< "  "< cout << "disc = " < end = GetTickCount();
cout << "times = " << (end-start) <<"ms"<< endl;
return disc;
}


double CompareWithPSNR(Mat srcOneGray, Mat srcTwoGray)
{
DWORD start, end;
start = GetTickCount();
double result;
result = getPSNR(srcOneGray, srcTwoGray);
cout << "disc = " << result << endl;
end = GetTickCount();
cout << "times = " << (end - start) << "ms" << endl;
return result;


}
double getPSNR(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());
double psnr = 10.0*log10((255 * 255) / mse);
return psnr;
}
}
Scalar  CompareWithSSIM(Mat i1, Mat  i2) {
DWORD start, end;
start = GetTickCount();
const double C1 = 6.5025, C2 = 58.5225;
/***************************** INITS **********************************/
int d = CV_32F;


Mat I1, I2;
i1.convertTo(I1, d);           // cannot calculate on one byte large values
i2.convertTo(I2, d);


Mat I2_2 = I2.mul(I2);        // I2^2
Mat I1_2 = I1.mul(I1);        // I1^2
Mat I1_I2 = I1.mul(I2);        // I1 * I2


  /*************************** END INITS **********************************/


Mat mu1, mu2;   // PRELIMINARY COMPUTING
GaussianBlur(I1, mu1, Size(11, 11), 1.5);
GaussianBlur(I2, mu2, Size(11, 11), 1.5);


Mat mu1_2 = mu1.mul(mu1);
Mat mu2_2 = mu2.mul(mu2);
Mat mu1_mu2 = mu1.mul(mu2);


Mat sigma1_2, sigma2_2, sigma12;


GaussianBlur(I1_2, sigma1_2, Size(11, 11), 1.5);
sigma1_2 -= mu1_2;


GaussianBlur(I2_2, sigma2_2, Size(11, 11), 1.5);
sigma2_2 -= mu2_2;


GaussianBlur(I1_I2, sigma12, Size(11, 11), 1.5);
sigma12 -= mu1_mu2;


///////////////////////////////// FORMULA ////////////////////////////////
Mat t1, t2, t3;


t1 = 2 * mu1_mu2 + C1;
t2 = 2 * sigma12 + C2;
t3 = t1.mul(t2);              // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))


t1 = mu1_2 + mu2_2 + C1;
t2 = sigma1_2 + sigma2_2 + C2;
t1 = t1.mul(t2);               // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2))


Mat ssim_map;
divide(t3, t1, ssim_map);      // ssim_map =  t3./t1;


Scalar mssim = mean(ssim_map); // mssim = average of ssim map


cout << "disc = " << mssim.val[0] * 100<<"%"<< endl;
end = GetTickCount();
cout << "times = " << (end - start) << "ms" << endl;
return mssim;
}


double CompareContour(Mat srcOneGray, Mat srcTwoGray) {
DWORD start, end;
start = GetTickCount();
Mat srcOneThresholdGray, srcTwoThresholdGray;
//使用 canny 可能 更准确些
threshold(srcOneGray, srcOneThresholdGray, 70, 255, CV_THRESH_BINARY);
threshold(srcTwoGray, srcTwoThresholdGray, 70, 255, CV_THRESH_BINARY);

//查找轮廓
Mat roi_one_contours_image, roi_two_contours_image;
vector> roi_one_contours, roi_two_contours;
roi_one_contours_image = srcOneThresholdGray.clone();
roi_two_contours_image = srcTwoThresholdGray.clone();


findContours(roi_one_contours_image, roi_one_contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
findContours(roi_two_contours_image, roi_two_contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);


//CV_CONTOURS_MATCH_I1   CV_CONTOURS_MATCH_I2   CV_CONTOURS_MATCH_I3
double disc = matchShapes(roi_one_contours_image, roi_two_contours_image, CV_CONTOURS_MATCH_I2, 0.0);
cout << "disc = " << disc << endl;
end = GetTickCount();
cout << "times = " << (end - start) << "ms" << endl;


/*imshow("test", srcOneThresholdGray);
waitKey(3000);
imshow("test", roi_one_contours_image);
waitKey(10000);*/
return disc;
}


// get hamming distance of two hash code  
int calHammingDistance(Mat modelHashCode, Mat testHashCode)
{
return countNonZero(modelHashCode != testHashCode);
}
// calculate the pHash code of image  
Mat calPHashCode(Mat image)
{
Mat floatImage, imageDct, imageResize;
resize(image, imageResize, Size(32, 32));
imageResize.convertTo(floatImage, CV_32FC1);
dct(floatImage, imageDct);
Rect roi(0, 0, 8, 8);
Scalar imageMean = mean(imageDct(roi));
return (imageDct(roi) > imageMean[0]);
}
double ComparePHashCode(Mat srcOneGray, Mat srcTwoGray)
{
DWORD start, end;
start = GetTickCount();
int disc = calHammingDistance(calPHashCode(srcOneGray), calPHashCode(srcTwoGray));


cout << "disc = " << disc<< endl;
end = GetTickCount();
cout << "times = " << (end - start) << "ms" << endl;
return disc;
}


double CompareWithORB(Mat srcOneGray, Mat srcTwoGray)
{
DWORD start, end;
start = GetTickCount();
vector keyPoints_1, keyPoints_2;
const int FEATURE = 1000;
Ptr orb = ORB::create(FEATURE, 1.2f, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, 20);
Mat descriptors_1, descriptors_2;
orb->detectAndCompute(srcOneGray, Mat(), keyPoints_1, descriptors_1);
orb->detectAndCompute(srcTwoGray, Mat(), keyPoints_2, descriptors_2);

BFMatcher matcher;
vector matches;
//Ptr matcherss = DescriptorMatcher::create("BruteForce");
matcher.match(descriptors_1, descriptors_2, matches);

double max_dist = 0; double min_dist = 0;
for (int i = 0; i < descriptors_1.rows; i++) {
double dist = matches[i].distance;
if (dist < min_dist) min_dist = dist;
if (dist > max_dist) max_dist = dist;
}
cout << "min_dist = " << min_dist << "max_dist =" << max_dist << endl;

//vector< DMatch > good_matches;
int countMatch = 0;
for (int i = 0; i < descriptors_1.rows; i++) {
//cout << "i = "< return 1;
}

你可能感兴趣的:(opencv,算法,图像处理)