Skip to content

Instantly share code, notes, and snippets.

@lxfly2000
Created January 27, 2018 05:50
Show Gist options
  • Save lxfly2000/f2a8edecddb2b17f7112b0d0d9ff3a3f to your computer and use it in GitHub Desktop.
Save lxfly2000/f2a8edecddb2b17f7112b0d0d9ff3a3f to your computer and use it in GitHub Desktop.
比较两个图像是否相似或一致。(https://pan.baidu.com/s/1htqQ5pi
//采用OpenCV轮廓匹配判断两个简单图片是否相似或一致
#include <iostream>
#include <opencv/cv.hpp>
//测试图片B是否与图片A相似,越接近0表示越相似,反之不相似
//IplImage到Mat转换:http://blog.sina.com.cn/s/blog_534497fd01015k7z.html
//参考:http://blog.csdn.net/qq_18343569/article/details/48004201
//参考:http://blog.csdn.net/qq_15947787/article/details/72773893
double TestDifference(const IplImage *imgA, const IplImage *imgB, int method = CV_CONTOURS_MATCH_I1,
double thresholdA1 = 50, double thresholdA2 = 60, double thresholdB1 = 50, double thresholdB2 = 60)
{
IplImage* bw_mode = cvCreateImage(cvGetSize(imgA), imgA->depth, 1);
IplImage* bw_test = cvCreateImage(cvGetSize(imgB), imgA->depth, 1);
IplImage* canny_mode = cvCreateImage(cvGetSize(imgA), imgA->depth, 1);
IplImage* canny_test = cvCreateImage(cvGetSize(imgB), imgA->depth, 1);
CvMemStorage *mode_mems = cvCreateMemStorage();
CvSeq *mode_seqs;
CvMemStorage *test_mems = cvCreateMemStorage();
CvSeq *test_seqs;
cvCvtColor(imgA, bw_mode, CV_RGB2GRAY);
cvCvtColor(imgB, bw_test, CV_RGB2GRAY);
//model contours
cvCanny(bw_mode, canny_mode, thresholdA1, thresholdA2);
cvFindContours(canny_mode, mode_mems, &mode_seqs, sizeof(CvContour), CV_RETR_TREE);
//test contours
cvCanny(bw_test, canny_test, thresholdB1, thresholdB2);
cvFindContours(canny_test, test_mems, &test_seqs, sizeof(CvContour), CV_RETR_TREE);
double desimilarity = cvMatchShapes(test_seqs, mode_seqs, method);
cvReleaseImage(&bw_mode);
cvReleaseImage(&bw_test);
cvReleaseImage(&canny_mode);
cvReleaseImage(&canny_test);
return desimilarity;
}
std::string TrimPath(const char *p)
{
std::string path(p);
if (path[0] == '"')
path = path.substr(1, path.size() - 2);
return path;
}
template<typename T>T TrimNum(const char *p)
{
std::stringstream ss;
T d;
ss << p;
ss >> d;
return d;
}
int main(int argc, char *argv[])
{
double ta1 = 50, ta2 = 60, tb1 = 50, tb2 = 60;
int m = CV_CONTOURS_MATCH_I1;
IplImage *imgA, *imgB;
switch (argc)
{
case 8:tb2 = TrimNum<double>(argv[7]);
case 7:tb1 = TrimNum<double>(argv[6]);
case 6:ta2 = TrimNum<double>(argv[5]);
case 5:ta1 = TrimNum<double>(argv[4]);
case 4:m = TrimNum<int>(argv[3]);
case 3:
imgA = cvLoadImage(TrimPath(argv[1]).c_str());
imgB = cvLoadImage(TrimPath(argv[2]).c_str());
break;
default:
std::cout << "命令行:\n" << argv[0] << " <图A> <图B> [匹配方法(1|2|3)] [阈值A1] [阈值A2] [阈值B1] [阈值B2]\n";
return 0;
}
std::cout << "差异:" << TestDifference(imgA, imgB, m, ta1, ta2, tb1, tb2) << std::endl;
cvReleaseImage(&imgA);
cvReleaseImage(&imgB);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment