图像检索:二维直方图+flann+KNN+欧几里得距离

来源:互联网 发布:cimatrone11编程 编辑:程序博客网 时间:2024/04/29 21:31

第一步:批处理提取图像库的二维直方图,并存在到.xml中的featureHists中

第一个参数:图像的路径 目录.txt

第二个参数:图像特征   features.xml

[保存到features.xml中featureHists]


#include<iostream>#include<fstream>#include<string>using namespace std;#include<opencv2\imgproc\imgproc.hpp>#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>using namespace cv;//计算二维直方图特征Mat hist2d(const Mat& src);int main(int argc,char* argv[]){if(argc !=3){cerr << "Wrong Argument !" <<endl;return -1;}//定义文件流,只能读取ifstream inPutFile(argv[1],ios::in);if(! inPutFile){cerr << "File Open Erro !" <<endl;return -1;}//读取文件流中的每一行,并赋值给fileName,读取每一幅图像string fileName ;Mat image;Mat featureHist;Mat featureHists;while (getline(inPutFile,fileName)){image = imread(fileName,1);//计算二维直方图特征featureHist = hist2d(image);//按行存储每一幅图像的二维直方图特征featureHists.push_back(featureHist);}    //注意一定要记得关闭文件流inPutFile.close();/*第五步,把图像特征保存到.xml文件中*/FileStorage fs(argv[2],FileStorage::WRITE);fs<<"featureHists"<<featureHists;fs.release();return 0;}Mat hist2d(const Mat& src){Mat hsv;//颜色空间的转换 BGR2HSVcvtColor(src,hsv,CV_BGR2HSV);//把H通道分为30个bin,把S通道分为32binint hbins = 30;int sbins = 32;int histSize[] = { hbins , sbins};//H的取值范围 0-179float hranges[]= {0,180};//S的取值范围 0-255float sranges [] ={0,256};const float* ranges [] ={hranges,sranges};Mat hist2D,histRow,histRowDst;//我们根据图像的第一通道和第二通道,计算二维直方图,而且输出的hist2D为32Fint channels [] ={0,1};calcHist(&hsv,1,channels,Mat(),hist2D,2,histSize,ranges,true,false);//把直方图特征按一行来存储histRow=hist2D.reshape(1,1);//把直方图归一化normalize(histRow,histRowDst,1,0,NORM_L1);return histRowDst;}
第二步:提取查询图像的二维直方图特征,并保存到.xml中

第一个参数:查询图像的路径

第二个参数:保存查询图像特征的.xml的路径

第三个参数:特征的名字

#include<iostream>#include<string>using namespace std;#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>#include<opencv2\imgproc\imgproc.hpp>using namespace cv;int main(int argc,char* argv[]){Mat src = imread(argv[1],1);if(! src.data){cout <<"No Image" << endl;return -1;}Mat hsv;//颜色空间的转换BGR2HSVcvtColor(src,hsv,CV_BGR2HSV);//把H通道分为60个bin,S通道分为32个bin(可以修改)int hbins = 60;int sbins = 32;int histSize[] = { hbins ,sbins};//H的取值范围 0-179float hranges[]= {0,180};//S的取值范围 0-255float sranges[] = {0,256};const float* ranges [] ={hranges,sranges};Mat hist2D,histRow,histRowDst;//我们根据图像的第一和第二个通道,计算二维直方图,而且输出的hist2D为32Fint channels [] ={0,1};calcHist(&hsv,1,channels,Mat(),hist2D,2,histSize,ranges,true,false);//把直方图特征按一行来存储histRow=hist2D.reshape(1,1);//把直方图归一化normalize(histRow,histRowDst,1,0,NORM_L1);FileStorage fs(argv[2],FileStorage::WRITE);//把histRowDst保存到.xml文件中fs << argv[3] << histRowDst;fs.release(); return 0;}
第三步:从图像库中用K-最近邻算法中,查找和查询图像相似的图片


#include<iostream>using namespace std;#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>#include<opencv2\flann\flann.hpp>using namespace cv;int main(int argc,char* argv[]){FileStorage dataBase(argv[1],FileStorage::READ);Mat features;dataBase["featureHists"]>>features;dataBase.release();FileStorage queryImage(argv[2],FileStorage::READ);Mat queryFeature;queryImage[argv[3]]>>queryFeature;queryImage.release();flann::Index fl(features,flann::KDTreeIndexParams(4));Mat index,distance;fl.knnSearch(queryFeature,index,distance,1);queryImage.release();return 0;}

因为工作的需要把三部分分开了。

1 0