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

第一步:批处理提取图像库的二维直方图,并存在到.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;
}

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

你可能感兴趣的:(图像检索,K最近邻,二维直方图,flann)