目标:选出一个参考图像,找出一组图像中与参考图像最相似的图像。 相似图像检索:基于图像内容的相似度检索,可以利用两幅图像的直方图特征,评估两幅图像的直方图相似度,进而得到两幅图像的相似度。
例:计算一张彩色图像的直方图特征
其中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; }
实验结果
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2305
- 用户1336
- 访客11455720
每日一句
Talent without working hard is nothing.
没有努力,天份不代表什么。
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器
新会员