目标:选出一个参考图像,找出一组图像中与参考图像最相似的图像。 相似图像检索:基于图像内容的相似度检索,可以利用两幅图像的直方图特征,评估两幅图像的直方图相似度,进而得到两幅图像的相似度。
例:计算一张彩色图像的直方图特征
其中method参数,可以指定测量方法,可选值如下:
例:计算两个直方图的相似度
similar的值越大,相似度越高。
colorhistogram.h
源.cpp
第一步:直方图特征提取
函数calcHist用来计算图像直方图特征,函数原型如下:void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=false )
例:计算一张彩色图像的直方图特征
//初始化数据 int histSize[3];//容器数(0~255),256项 float hranges[2]; const float* ranges[3]; int channels[3]; histSize[0]= histSize[1]= histSize[2]= 256; hranges[0]= 0.0;// 像素的强度值范围 hranges[1]= 255.0; ranges[0]= hranges;// 所用通道的数值范围相同 ranges[1]= hranges; ranges[2]= hranges; channels[0]= 0;// 三通道 channels[1]= 1; channels[2]= 2; //计算直方图特征 cv::calcHist(&image, //图像 1, // 1张图片 channels, // 通道 cv::Mat(), // 掩码 hist, // 返回值,直方图特征类型为cv::MatND 3, // 3维 histSize, // 容器数量 ranges // 像素的强度值 范围 );
第二步 比较两幅图像相似度
两幅图像的相似度,可以用他们的直方图特征的相似度来代替。 函数compareHist计算两个直方图的相似度,其函数原型如下,double compareHist(const SparseMat& H1, const SparseMat& H2, int method)
其中method参数,可以指定测量方法,可选值如下:
CV_COMP_CORREL Correlation CV_COMP_CHISQR Chi-Square CV_COMP_INTERSECT Intersection CV_COMP_BHATTACHARYYA Bhattacharyya distance CV_COMP_HELLINGER Synonym for CV_COMP_BHATTACHARYYA
例:计算两个直方图的相似度
double similar=cv::compareHist(refHist, inputHist, CV_COMP_INTERSECT);
similar的值越大,相似度越高。
第三步 相似图像检索
通过前两步得到两幅图像的相似度,我们便可以进行相似图像检索,找出与参考图像最相似的图像。其代码如下:imagecompare.h#ifndef IMAGECOMPARE_H #define IMAGECOMPARE_H #include"colorhistogram.h" class ImageCompare { private: //参考图像 cv::Mat reference; //检测图像 cv::Mat input; //直方图数据 cv::MatND refHist; cv::MatND inputHist; ColorHistogram h; //减色变量 int div; public: ImageCompare() :div(32){} void setColorReduction(int factor) { div = factor; } int getColorRedutction()const { return div; } //设置参考图像 void setRerenceImage(const cv::Mat& image) { reference = image; refHist = h.getHistogram(image); //cv::normalize(refHist, refHist); } //比较两幅图像相似度 double compare(const cv::Mat &image) { input = image; inputHist = h.getHistogram(image); //cv::normalize(inputHist, inputHist); return cv::compareHist(refHist, inputHist, CV_COMP_INTERSECT); } }; #endif
colorhistogram.h
#ifndef COLHISTOGRAM #define COLHISTOGRAM #include <opencv2\core\core.hpp> #include <opencv2\imgproc\imgproc.hpp> #include<opencv2\highgui\highgui.hpp> class ColorHistogram { private: int histSize[3]; float hranges[2]; const float* ranges[3]; int channels[3]; public: ColorHistogram() { //初始化数据 histSize[0]= histSize[1]= histSize[2]= 256; hranges[0]= 0.0; // 像素的强度值范围 hranges[1]= 255.0; ranges[0]= hranges; // 所用通道的数值范围相同 ranges[1]= hranges; ranges[2]= hranges; channels[0]= 0; // 三通道 channels[1]= 1; channels[2]= 2; } // 计算直方图 cv::MatND getHistogram(const cv::Mat &image) { cv::MatND hist; // 彩色直方图 hranges[0]= 0.0; hranges[1]= 255.0; channels[0]= 0; channels[1]= 1; channels[2]= 2; // 计算直方图 cv::calcHist(&image, 1, // 1张图片 channels, // 通道 cv::Mat(), // 掩码 hist, // 直方图 3, // 3维 histSize, // 容器数量 ranges // 像素的强度值 范围 ); return hist; } }; #endif
源.cpp
#include"imagecompare.h" #include<iostream> int main() { //类对象 ImageCompare h; //参考图像 cv::Mat image = cv::imread("D:/images/beach.jpg"); //设置直方图数据 h.setRerenceImage(image); //定义double数组,保存相似度数据 double similar[4]; //group.jpg cv::Mat groupImage = cv::imread("D:/images/group.jpg"); similar[0] = h.compare(groupImage); std::cout << "group:" << similar[0] << std::endl; //dog.jpg cv::Mat dogImage = cv::imread("D:/images/dog.jpg"); similar[1] = h.compare(dogImage); std::cout << "dog:" << similar[1] << std::endl; //fundy.jpg cv::Mat fundyImage = cv::imread("D:/images/fundy.jpg"); similar[2] = h.compare(fundyImage); std::cout << "fundy:" << similar[2] << std::endl; //waves.jpg cv::Mat wavesImage = cv::imread("D:/images/waves.jpg"); similar[3] = h.compare(wavesImage); std::cout << "waves:" << similar[3] << std::endl; //找出相似度最大的数据 double max = similar[1]; int index = 0; for (int i = 0; i < 4; i++) { if (similar[i]>max) { max = similar[i]; index = i + 1; } } //显示最相似的图片 cv::namedWindow("最相似图片", CV_WINDOW_FREERATIO); switch (index) { case 1: cv::imshow("最相似图片", groupImage); break; case 2: cv::imshow("最相似图片", dogImage); break; case 3: cv::imshow("最相似图片", fundyImage); break; case 4: cv::imshow("最相似图片", wavesImage); break; default: break; } //显示原图 cv::namedWindow("原图", CV_WINDOW_FREERATIO); cv::imshow("原图", image); cv::waitKey(0); return 0; }
实验结果
与参考图像最相似的图像为:waves.jpg(从数据可以看出dog.jpg与waves.jpg,远比起其他两张图片,同参考图像beach.jpg相似) 收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2299
- 用户1336
- 访客10619057
每日一句
You leave, or I go with you.
你留下,或者我跟你走。——《海角七号》
你留下,或者我跟你走。——《海角七号》
新会员