日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV2.4.4中调用SIFT特征检测器进行图像匹配

發布時間:2025/3/21 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV2.4.4中调用SIFT特征检测器进行图像匹配 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

OpenCV中一些相關結構說明:

特征點類:

[cpp]?view plain?copy ?
  • class?KeyPoint??
  • {??
  • ???????Point2f??pt;??//坐標??
  • ???????float??size;?//特征點鄰域直徑??
  • ???????float??angle;?//特征點的方向,值為[0,360),負值表示不使用??
  • ???????float??response;?//??
  • ???????int??octave;?//特征點所在的圖像金字塔的組??
  • ???????int??class_id;?//用于聚類的id??
  • }??

  • 存放匹配結果的結構:

    [cpp]?view plain?copy ?
  • struct?DMatch??
  • {??
  • ???????//三個構造函數??
  • ????DMatch():?queryIdx(-1),?trainIdx(-1),imgIdx(-1),distance(std::numeric_limits<float>::max())?{}??
  • ????DMatch(int??_queryIdx,?int??_trainIdx,?float??_distance?)?:??
  • ?????????????????????queryIdx(?_queryIdx),trainIdx(?_trainIdx),?imgIdx(-1),distance(?_distance)?{}??
  • ????DMatch(int??_queryIdx,?int??_trainIdx,?int??_imgIdx,?float??_distance?)?:??
  • ????????????queryIdx(_queryIdx),?trainIdx(?_trainIdx),?imgIdx(?_imgIdx),distance(?_distance)?{}??
  • ??
  • ????intqueryIdx;??//此匹配對應的查詢圖像的特征描述子索引??
  • ????inttrainIdx;???//此匹配對應的訓練(模板)圖像的特征描述子索引??
  • ????intimgIdx;????//訓練圖像的索引(若有多個)??
  • ????float?distance;??//兩個特征向量之間的歐氏距離,越小表明匹配度越高。??
  • ????booloperator?<?(const?DMatch?&m)?const;??
  • };??
  • ?????? 說明:以兩個特征點描述子(特征向量)之間的歐氏距離作為特征點匹配的相似度準則,假設特征點對p和q的

    ????????????? ?特征描述子分別為Desp和Desq,則其歐氏距離定義為:


    ????????????? ? 所以每個匹配分別對應訓練圖像(train)和查詢圖像(query)中的一個特征描述子(特征向量)。



    [cpp]?view plain?copy ?
  • #include?"opencv2/highgui/highgui.hpp"??
  • #include?"opencv2/imgproc/imgproc.hpp"??
  • #include?"opencv2/nonfree/nonfree.hpp"??
  • #include?"opencv2/nonfree/features2d.hpp"??
  • #include?<iostream>??
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • ??
  • using?namespace?cv;??
  • using?namespace?std;??
  • ??
  • int?main()??
  • {??
  • ????initModule_nonfree();//初始化模塊,使用SIFT或SURF時用到??
  • ????Ptr<FeatureDetector>?detector?=?FeatureDetector::create(?"SIFT"?);//創建SIFT特征檢測器??
  • ????Ptr<DescriptorExtractor>?descriptor_extractor?=?DescriptorExtractor::create(?"SIFT"?);//創建特征向量生成器??
  • ????Ptr<DescriptorMatcher>?descriptor_matcher?=?DescriptorMatcher::create(?"BruteForce"?);//創建特征匹配器??
  • ????if(?detector.empty()?||?descriptor_extractor.empty()?)??
  • ????????cout<<"fail?to?create?detector!";??
  • ??
  • ????//讀入圖像??
  • ????Mat?img1?=?imread("desk.jpg");??
  • ????Mat?img2?=?imread("desk_glue.jpg");??
  • ??
  • ????//特征點檢測??
  • ????double?t?=?getTickCount();//當前滴答數??
  • ????vector<KeyPoint>?keypoints1,keypoints2;??
  • ????detector->detect(?img1,?keypoints1?);//檢測img1中的SIFT特征點,存儲到keypoints1中??
  • ????detector->detect(?img2,?keypoints2?);??
  • ????cout<<"圖像1特征點個數:"<<keypoints1.size()<<endl;??
  • ????cout<<"圖像2特征點個數:"<<keypoints2.size()<<endl;??
  • ??
  • ????//根據特征點計算特征描述子矩陣,即特征向量矩陣??
  • ????Mat?descriptors1,descriptors2;??
  • ????descriptor_extractor->compute(?img1,?keypoints1,?descriptors1?);??
  • ????descriptor_extractor->compute(?img2,?keypoints2,?descriptors2?);??
  • ????t?=?((double)getTickCount()?-?t)/getTickFrequency();??
  • ????cout<<"SIFT算法用時:"<<t<<"秒"<<endl;??
  • ??
  • ??
  • ????cout<<"圖像1特征描述矩陣大小:"<<descriptors1.size()??
  • ????????<<",特征向量個數:"<<descriptors1.rows<<",維數:"<<descriptors1.cols<<endl;??
  • ????cout<<"圖像2特征描述矩陣大小:"<<descriptors2.size()??
  • ????????<<",特征向量個數:"<<descriptors2.rows<<",維數:"<<descriptors2.cols<<endl;??
  • ??
  • ????//畫出特征點??
  • ????Mat?img_keypoints1,img_keypoints2;??
  • ????drawKeypoints(img1,keypoints1,img_keypoints1,Scalar::all(-1),0);??
  • ????drawKeypoints(img2,keypoints2,img_keypoints2,Scalar::all(-1),0);??
  • ????//imshow("Src1",img_keypoints1);??
  • ????//imshow("Src2",img_keypoints2);??
  • ??
  • ????//特征匹配??
  • ????vector<DMatch>?matches;//匹配結果??
  • ????descriptor_matcher->match(?descriptors1,?descriptors2,?matches?);//匹配兩個圖像的特征矩陣??
  • ????cout<<"Match個數:"<<matches.size()<<endl;??
  • ??
  • ????//計算匹配結果中距離的最大和最小值??
  • ????//距離是指兩個特征向量間的歐式距離,表明兩個特征的差異,值越小表明兩個特征點越接近??
  • ????double?max_dist?=?0;??
  • ????double?min_dist?=?100;??
  • ????for(int?i=0;?i<matches.size();?i++)??
  • ????{??
  • ????????double?dist?=?matches[i].distance;??
  • ????????if(dist?<?min_dist)?min_dist?=?dist;??
  • ????????if(dist?>?max_dist)?max_dist?=?dist;??
  • ????}??
  • ????cout<<"最大距離:"<<max_dist<<endl;??
  • ????cout<<"最小距離:"<<min_dist<<endl;??
  • ??
  • ????//篩選出較好的匹配點??
  • ????vector<DMatch>?goodMatches;??
  • ????for(int?i=0;?i<matches.size();?i++)??
  • ????{??
  • ????????if(matches[i].distance?<?0.31?*?max_dist)??
  • ????????{??
  • ????????????goodMatches.push_back(matches[i]);??
  • ????????}??
  • ????}??
  • ????cout<<"goodMatch個數:"<<goodMatches.size()<<endl;??
  • ??
  • ????//畫出匹配結果??
  • ????Mat?img_matches;??
  • ????//紅色連接的是匹配的特征點對,綠色是未匹配的特征點??
  • ????drawMatches(img1,keypoints1,img2,keypoints2,goodMatches,img_matches,??
  • ????????????????Scalar::all(-1)/*CV_RGB(255,0,0)*/,CV_RGB(0,255,0),Mat(),2);??
  • ??
  • ????imshow("MatchSIFT",img_matches);??
  • ????waitKey(0);??
  • ????return?0;??
  • }??

  • 結果:


    效果圖:




    源碼下載:

    http://download.csdn.net/detail/masikkk/5511831


    當然,這些匹配還沒有經過系統的篩選,還存在大量的錯配,關于匹配的篩選參見這篇文章:

    ?利用RANSAC算法篩選SIFT特征匹配

    以及RobHess的SIFT源碼分析系列文章:http://blog.csdn.net/masibuaa/article/details/9191309


    from:?http://blog.csdn.net/masibuaa/article/details/8998601

    總結

    以上是生活随笔為你收集整理的OpenCV2.4.4中调用SIFT特征检测器进行图像匹配的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。