#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 << "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_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
const int FEATURE = 1000;
Ptr
Mat descriptors_1, descriptors_2;
orb->detectAndCompute(srcOneGray, Mat(), keyPoints_1, descriptors_1);
orb->detectAndCompute(srcTwoGray, Mat(), keyPoints_2, descriptors_2);
BFMatcher matcher;
vector
//Ptr
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 = "< if (matches[i].distance <= 0.6*max_dist) {
//good_matches.push_back(matches[i]);
countMatch++;
}
}
cout <<"countMatch = " <
float match = ((float)countMatch) / FEATURE;
cout << "match = " << match << endl;
end = GetTickCount();
cout << "times = " << (end - start) << "ms" << endl;
return 1;
}