主要是把灰度图像转换为直方图,然后通过直方图的参数(
CV_COMP_CORREL(相关度),
CV_COMP_CHISQR(卡方系数),
CV_COMP_INTERSECT(相交系数),
CV_COMP_BHATTACHARYYA)来进行相似度的比较。
实现的程序代码如下:
/*利用直方图计算两张大小一致的图像的匹配时间*/
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cv.hpp>
#include <iostream>
using namespace std;
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
//定义灰度图像的读取路径
char const *imagefile1 = "E:\\图像匹配\\测试图像\\14.jpg";
char const *imagefile2 = "E:\\图像匹配\\测试图像\\15.jpg";
//设置直方图的参数
int HistogramBins = 256;
float HistogramRange1[] = { 0, 255 };
float *HisotgramRange[1] = { HistogramRange1 };
//加载灰度图像
IplImage *image1 = cvLoadImage(imagefile1, CV_LOAD_IMAGE_UNCHANGED);
IplImage *image2 = cvLoadImage(imagefile2, CV_LOAD_IMAGE_UNCHANGED);
//创建一个直方图,1代表数组长度,HistogramBins代表整数数组,CV_HIST_ARRAY代表密集多维矩阵结构,
CvHistogram *Histogram1 = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, HisotgramRange);
CvHistogram *Histogram2 = cvCreateHist(1, &HistogramBins, CV_HIST_ARRAY, HisotgramRange);
//直方图比较函数
int CompareHist(const char* imagefile1, const char* imagefile2)
{
//从图像中自动地计算直方图
cvCalcHist(&image1, Histogram1);
cvCalcHist(&image2, Histogram2);
//直方图归一化
cvNormalizeHist(Histogram1, 1);
cvNormalizeHist(Histogram2, 1);
//执行完匹配后,清除直方图的数据
cvClearHist(Histogram1);
cvClearHist(Histogram2);
//定义循环次数i,定义数组a[20]来存放20次匹配运算的时间
int i = 0;
double a[20];
while (true)
{
for (i; i < 20; i++)
{
//打开文件,进行写操作
FILE *fp = fopen("E:\\1.txt", "w");
for (int j = 0; j < 20; j++)
{
//计算匹配的时间t
double t = (double)cvGetTickCount();
//printf("CV_COMP_CHISQR 相同为0,相似度范围为[ 0, +inf ) : %.4f\n", cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR));
//cvCompareHist(Histogram1, Histogram2, CV_COMP_CHISQR);
//用相关系数CV_COMP_CORREL来计算直方图运算匹配时间, CV_COMP_CHISQR卡方比较,CV_COMP_BHATTACHARYYA常态分布比较,CV_COMP_INTERSECT交集法比较
cvCompareHist(Histogram1, Histogram2, CV_COMP_CORREL);
t = ((double)cvGetTickCount() - t) / ((double)cvGetTickFrequency() * 1000);
a[j] = t;
fprintf(fp, "运算的时间是(ms):%.4f\n", a[j]);
//cout << "运算的时间是(ms):" << a[j] << endl;
}
//剔除第一个运算时间,求剩下时间的平均值average
double sum = 0;
double average;
for (i = 1; i< 20; i++)
{
sum += a[i];
}
average = sum / i;
fprintf(fp, "平均运算时间(ms):%.4f\n", average);
fclose(fp);
//cout << "平均运算时间(ms):" << average << endl;
}
}
getchar();
return 0;
}
int main(int argc, char *argv[])
{
//直方图比较函数的调用
CompareHist(argv[1], argv[2]);
cvWaitKey(100);
//释放灰度图像
cvReleaseImage(&image1);
cvReleaseImage(&image2);
//释放直方图
cvReleaseHist(&Histogram1);
cvReleaseHist(&Histogram2);
return 0;
}
测试数据分析:
当 pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") 这句代码取消注销时,在生成的EXE窗口中的时间是不符合要求的,如下图所示:
通过分析可知,运算的时间等价于了EXE窗口生成打开的时间加上匹配运算的时间,所以会导致每次运算时间的不一致。
解决方法:
把生成的运算时间保存到文本中,同时屏蔽掉EXE窗口的显示(#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\""))。运算的测试数据如下:
通过数据可知,除了第一次运算时间和其他的时间有较大的差异之外,其余的运算时间都是比较接近的。而第一次出现时间差别较大的原因是:在通过比较直方图时,需要调用OpenCV中自带的函数cvCompareHist,同时也需要申请内存;因而运算的时间较长一点。