影象檢索:二維直方圖+flann+KNN+歐幾里得距離
阿新 • • 發佈:2019-01-04
第一步:批處理提取影象庫的二維直方圖,並存在到.xml中的featureHists中
【
第一個引數:影象的路徑 目錄.txt
第二個引數:影象特徵 features.xml
[儲存到features.xml中featureHists]
】
第二步:提取查詢影象的二維直方圖特徵,並儲存到.xml中#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的路徑
第三個引數:特徵的名字
】
第三步:從影象庫中用K-最近鄰演算法中,查詢和查詢影象相似的圖片#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; }
#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; }
因為工作的需要把三部分分開了。