一种基于特征点匹配的图像检索方法的opencv实现
来源:互联网 发布:随机森林优化 编辑:程序博客网 时间:2024/05/17 20:15
由于最初这个方法是用qt界面的形式呈现了,没有平常见到的main函数执行图像检索的那样,我稍微做了下整理,提供出一个c++接口interface()可供调用。注释还比较少,后面有时间补上。
#ifndef IMAGERETRIVAL#define IMAGERETRIVAL//#include <cxcore.h>#include <opencv2\features2d\features2d.hpp>#include <opencv2\calib3d\calib3d.hpp>#include <opencv2\contrib\contrib.hpp>#include <opencv2/nonfree/nonfree.hpp>#include <highgui.h>#include <iostream>#include <map>#include <io.h>using namespace std ;using namespace cv;#define HessianThreshold 400#define MAX_Image_Num 1000#define MIN_Image_Similar_Threshold 0.001struct matDescToImgfile{ int i_begin_index ; int i_end_index ; string s_imge_filename ;};const string trainFileType = "jpg"; // "*" represent any file type.////////////////////////////////////////////////////////////////////////////从目录中读取文件名列表int readDirFile(const string dirName, const string fileType , vector<string> &allFilename){ int fileNum = 0 ; _finddata_t onefile ; long lFile ; string dirName_FileType = dirName + "\\*."+fileType; lFile = _findfirst(dirName_FileType.c_str() , &onefile) ; if (lFile == -1l ) //on such file, return -1l (long type) { cout << "can`t find the file"<<endl; return fileNum ; } else { //cout <<"the files of the folder:"<<endl ; do { //cout<<onefile.name <<endl ; allFilename.push_back(onefile.name) ; fileNum ++ ; } while (_findnext(lFile , &onefile) == 0); } _findclose(lFile) ; return fileNum ;}//////////////////////////////////////////////////////////////////////////void createDetectorDescriptor(const string trainDirName,vector<string> trainAllFileName, Mat& matTotalDesc,vector<matDescToImgfile>& vec_Desc_Imgfile){ //创建特征点提取器 cv::SurfFeatureDetector* m_pDector = new cv::SurfFeatureDetector(HessianThreshold); //HessianThreshold SurfDescriptorExtractor* m_pExtractor = new SurfDescriptorExtractor; //读取train中图片 //提取特征点及描述符 //描述符提取 Mat ImgMat ; vector<KeyPoint> veckps; Mat matDesc; matDescToImgfile one_img_log ; int img_num = 0 ; vector<string>::iterator imageName ; for (imageName = trainAllFileName.begin() ; imageName != trainAllFileName.end() ; imageName++) { veckps.clear(); matDesc.release(); ImgMat.release(); //cout<<trainDirName+"\\"+*imageName <<endl ; ImgMat = imread(trainDirName+"\\"+*imageName,CV_LOAD_IMAGE_ANYCOLOR) ; //CV_LOAD_IMAGE_ANYDEPTH m_pDector->detect(ImgMat,veckps); if(veckps.size() == 0) { return ; } m_pExtractor->compute(ImgMat,veckps,matDesc); matTotalDesc.push_back(matDesc) ;//集中所有matDesc形成matTotalDesc if (img_num == 0) { one_img_log.i_begin_index = 0 ; one_img_log.i_end_index = matDesc.rows-1 ; one_img_log.s_imge_filename = trainDirName+"\\"+*imageName ; } else { one_img_log.i_begin_index = one_img_log.i_end_index + 1; one_img_log.i_end_index = one_img_log.i_begin_index + matDesc.rows-1 ; one_img_log.s_imge_filename = trainDirName+"\\"+*imageName ; } img_num++; vec_Desc_Imgfile.push_back(one_img_log) ; } delete(m_pDector); delete(m_pExtractor);}vector<string> GetImageFromKNN(vector<matDescToImgfile> Desc_Imgfile ,cv::Mat Indices , const int Img_Num ,const double Max_Threshold,int rankNum){ int flag_count[200] ={0}; //cout << "Img_Num=" << Img_Num << endl; vector<matDescToImgfile>::iterator oneDescLog ; MatIterator_ <int> it_indice ; int key ; for (it_indice = Indices.begin<int>() ; it_indice!= Indices.end<int>() ; it_indice++) { key = *it_indice ; int i = 0 ; for (oneDescLog = Desc_Imgfile.begin() ; oneDescLog!=Desc_Imgfile.end(); oneDescLog++ , i ++) { if (key >= oneDescLog->i_begin_index && key <= oneDescLog->i_end_index) { flag_count[i] ++ ;//flag ++break; } } }//找到indices中相似描述符属于哪个区间 multimap<int,int> result; for(int j=0;j<Img_Num;j++){ result.insert(make_pair(flag_count[j],j)); //result[flag_count[j]] = j; } float max_flag = 0 ; int count_num =-1; vector<int> index; vector<string> resultStr; for (multimap<int, int>::reverse_iterator iter = result.rbegin();iter != result.rend();++iter){ index.push_back(iter->second); } assert(rankNum <= Img_Num); for (int i=0;i<rankNum;i++){ resultStr.push_back(Desc_Imgfile.at(index[i]).s_imge_filename); //cout << Desc_Imgfile.at(index[i]).s_imge_filename << endl; } return resultStr; /*for (int j = 0 ; j < Img_Num ; j++ ) { if (max_flag < flag_count[j]/float (Indices.rows)) { max_flag = flag_count[j]/float (Indices.rows) ; count_num = j ; } } //cout<<"max similarity ratio \t"<<max_flag<<endl; if (max_flag > Max_Threshold) { return Desc_Imgfile.at(count_num).s_imge_filename ; } else return "";*/}//////////////////////////////////////////////////////////////////////////vector<string> OneImageRetrival(cv::flann::Index& m_index, const string query_image_name , vector<matDescToImgfile>& vec_Desc_Imgfile,int kNum){ //创建特征点提取器 SurfFeatureDetector* m_pDector = new SurfFeatureDetector(HessianThreshold); //HessianThreshold SurfDescriptorExtractor* m_pExtractor = new SurfDescriptorExtractor; Mat QueryMat ; vector<KeyPoint> QueryVecKP ; Mat QueryMatDesc ; QueryMat = imread(query_image_name,CV_LOAD_IMAGE_ANYCOLOR);//QueryMat.resize(256,256); m_pDector->detect(QueryMat,QueryVecKP); m_pExtractor->compute(QueryMat,QueryVecKP,QueryMatDesc); cv::Mat indices(QueryMatDesc.rows, 1, CV_32S); cv::Mat dists(QueryMatDesc.rows , 1, CV_32F); m_index.knnSearch(QueryMatDesc, indices, dists, 10, cv::flann::SearchParams(512) ); vector<string> s_the_result_filename = GetImageFromKNN(vec_Desc_Imgfile , indices , vec_Desc_Imgfile.size() ,MIN_Image_Similar_Threshold,kNum) ; delete(m_pDector); delete(m_pExtractor); return s_the_result_filename;}////////////////////////////////////////////////////////////////////////////filename是想要检索的那个图片的包括绝对路径的名字,trainDirName是检索图像库的绝对路径,kNum是想要检索前多少个相似的图片,这个值一定要小于图片的数量vector<string> interface(string filename,string trainDirName,int kNum){ ////////////////////////////////////////////////////////////////////////// //cout<<"\n###step 1 --read the train file :"<<endl ; vector<string> trainAllFileName ; int readFileStatus = readDirFile(trainDirName , trainFileType,trainAllFileName) ; ////////////////////////////////////////////////////////////////////////// Mat matTotalDesc ; vector<matDescToImgfile> vec_Desc_Imgfile ; createDetectorDescriptor(trainDirName,trainAllFileName , matTotalDesc ,vec_Desc_Imgfile) ; //建立随机kd-tree cv::flann::Index m_index(matTotalDesc, cv::flann::KDTreeIndexParams(4)); vector<string> resultFIlename = OneImageRetrival(m_index, filename , vec_Desc_Imgfile,kNum) ; return resultFIlename;}#endif // IMAGERETRIVAL
效果展示如下图所示:
转载请注明地址:http://blog.csdn.net/xbcreal/article/details/70313907
0 0
- 一种基于特征点匹配的图像检索方法的opencv实现
- OpenCV-基于特征点的图像匹配
- 特征点匹配应用——图像拼接的原理与基于OpenCV的实现
- 基于opencv的特征点匹配法
- opencv基于直方图实现图像检索匹配
- 基于直方图的图像检索OpenCV实现
- 基于图像特征的检索
- 基于一种改进的提取形状特征向量方法,实现图像检索
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- 【opencv】特征点提取和匹配的通用方法
- OpenCV中特征点提取和匹配的通用方法
- 使用sklearn做单机特征工程
- iOS开发之多工程联编
- linux的nohup命令的用法
- Docker for Windows 中文文档(1)——Explore the application and run examples
- GPS数据处理
- 一种基于特征点匹配的图像检索方法的opencv实现
- iOS多线程编程篇: Operation 对象 与 Operation Queue
- ionic2/ionic3 启动慢问题解决(apk包也变小了)
- CodeForces
- docker数据卷
- Android Matrix的使用过程
- BootStrap基础入门
- Java核心技术II:解析XML文档
- SSM第一次握手