第一步:批处理提取图像库的二维直方图,并存在到.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; //颜色空间的转换 BGR2HSV cvtColor(src,hsv,CV_BGR2HSV); //把H通道分为30个bin,把S通道分为32bin int hbins = 30; int sbins = 32; int histSize[] = { hbins , sbins}; //H的取值范围 0-179 float hranges[]= {0,180}; //S的取值范围 0-255 float sranges [] ={0,256}; const float* ranges [] ={hranges,sranges}; Mat hist2D,histRow,histRowDst; //我们根据图像的第一通道和第二通道,计算二维直方图,而且输出的hist2D为32F int 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; //颜色空间的转换BGR2HSV cvtColor(src,hsv,CV_BGR2HSV); //把H通道分为60个bin,S通道分为32个bin(可以修改) int hbins = 60; int sbins = 32; int histSize[] = { hbins ,sbins}; //H的取值范围 0-179 float hranges[]= {0,180}; //S的取值范围 0-255 float sranges[] = {0,256}; const float* ranges [] ={hranges,sranges}; Mat hist2D,histRow,histRowDst; //我们根据图像的第一和第二个通道,计算二维直方图,而且输出的hist2D为32F int 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; }
因为工作的需要把三部分分开了。
图像检索:二维直方图+flann+KNN+欧几里得距离
时间: 2024-10-12 11:30:08