版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/wxcdzhangping/article/details/37690991
第一步:批处理提取图像库的二维直方图,并存在到.xml中的featureHists中
【
第一个參数:图像的路径 文件夹.txt
第二个參数:图像特征 features.xml
[保存到features.xml中featureHists]
】
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
#include<opencv2imgprocimgproc.hpp>
#include<opencv2corecore.hpp>
#include<opencv2highguihighgui.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<opencv2corecore.hpp>
#include<opencv2highguihighgui.hpp>
#include<opencv2imgprocimgproc.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<opencv2corecore.hpp>
#include<opencv2highguihighgui.hpp>
#include<opencv2flannflann.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;
}
由于工作的须要把三部分分开了。