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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

opencv检测相交点_OpenCV特征点检测------ORB特征

發布時間:2023/12/2 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv检测相交点_OpenCV特征点检测------ORB特征 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ORB是是ORiented Brief的簡稱。ORB的描述在下面文章中:

Ethan Rublee and Vincent Rabaud and Kurt Konolige and Gary Bradski, ORB: an efcient alternative to SIFT or SURF, ICCV 2011

沒有加上鏈接是因為作者確實還沒有放出論文,不過OpenCV2.3RC中已經有了實現,WillowGarage有一個talk也提到了這個算法,因此我不揣淺陋,在這里總結一下。

Brief是Binary Robust Independent Elementary Features的縮寫。這個特征描述子是由EPFL的Calonder在ECCV2010上提出的。主要思路就是在特征點附近隨機選取若干點對,將這些點對的灰度值的大小,組合成一個二進制串,并將這個二進制串作為該特征點的特征描述子。詳細算法描述參考如下論文:

注意在BRIEF eccv2010的文章中,BRIEF描述子中的每一位是由隨機選取的兩個像素點做二進制比較得來的。文章同樣提到,在此之前,需要選取合適的gaussian kernel對圖像做平滑處理。(為什么要強調這一點,因為下述的ORB對此作了改進。)

BRIEF的優點在于速度,缺點也相當明顯:

1:不具備旋轉不變性。

2:對噪聲敏感

3:不具備尺度不變性。

ORB就是試圖解決上述缺點中的1和2.

如何解決旋轉不變性:

在ORB的方案中,是采用了FAST作為特征點檢測算子。FAST應用的很多了,是出名的快,以防有人不知道,請看這里:

在Sift的方案中,特征點的主方向是由梯度直方圖的最大值和次大值所在的bin對應的方向決定的。略嫌耗時。

在ORB的方案中,特征點的主方向是通過矩(moment)計算而來,公式如下:

有了主方向之后,就可以依據該主方向提取BRIEF描述子。但是由此帶來的問題是,由于主方向會發生變化,隨機點對的相關性會比較大,從而降低描述子的判別性。解決方案也很直接,采取貪婪的,窮舉的方法,暴力找到相關性較低的隨機點對。

如何解決對噪聲敏感的問題:

在前面提到過,在最早的eccv2010的文章中,BRIEF使用的是pixel跟pixel的大小來構造描述子的每一個bit。這樣的后果就是對噪聲敏感。因此,在ORB的方案中,做了這樣的改進,不再使用pixel-pair,而是使用9×9的patch-pair,也就是說,對比patch的像素值之和。(可以通過積分圖快速計算)。

關于尺度不變性:

ORB沒有試圖解決尺度不變性,(因為FAST本身就不具有尺度不變性。)但是這樣只求速度的特征描述子,一般都是應用在實時的視頻處理中的,這樣的話就可以通過跟蹤還有一些啟發式的策略來解決尺度不變性的問題。

關于計算速度:

ORB是sift的100倍,是surf的10倍。

關于性能:

下面是一個性能對比,ORB還是很給力。點擊看大圖。

Related posts

看到OpenCV2.3.1里面ORB特征提取算法也在里面了,套用給的SURF特征例子程序改為ORB特征一直提示錯誤,類型不匹配神馬的,由于沒有找到示例程序,只能自己找答案。

(ORB特征論文:ORB: an efficient alternative to SIFT or SURF.點擊下載論文)

經過查找發現:

描述符數據類型有是float的,比如說SIFT,SURF描述符,還有是uchar的,比如說有ORB,BRIEF

對于float 匹配方式有:

FlannBased

BruteForce >

BruteForce >

BruteForce >

對于uchar有:

BruteForce

BruteForce

BruteForceMatcher< L2 > matcher;//改動的地方

完整代碼如下:

#include

#include "opencv2/core/core.hpp"

#include "opencv2/features2d/features2d.hpp"

#include "opencv2/highgui/highgui.hpp"

#include

#include

using namespace cv;

using namespace std;

int main()

{

Mat img_1 = imread("D:\\image\\img1.jpg");

Mat img_2 = imread("D:\\image\\img2.jpg");

if (!img_1.data || !img_2.data)

{

cout << "error reading images " << endl;

return -1;

}

ORB orb;

vector keyPoints_1, keyPoints_2;

Mat descriptors_1, descriptors_2;

orb(img_1, Mat(), keyPoints_1, descriptors_1);

orb(img_2, Mat(), keyPoints_2, descriptors_2);

BruteForceMatcher matcher;

vector matches;

matcher.match(descriptors_1, descriptors_2, matches);

double max_dist = 0; double min_dist = 100;

//-- Quick calculation of max and min distances between keypoints

for( int i = 0; i < descriptors_1.rows; i++ )

{

double dist = matches[i].distance;

if( dist < min_dist ) min_dist = dist;

if( dist > max_dist ) max_dist = dist;

}

printf("-- Max dist : %f \n", max_dist );

printf("-- Min dist : %f \n", min_dist );

//-- Draw only "good" matches (i.e. whose distance is less than 0.6*max_dist )

//-- PS.- radiusMatch can also be used here.

std::vector< DMatch > good_matches;

for( int i = 0; i < descriptors_1.rows; i++ )

{

if( matches[i].distance < 0.6*max_dist )

{

good_matches.push_back( matches[i]);

}

}

Mat img_matches;

drawMatches(img_1, keyPoints_1, img_2, keyPoints_2,

good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),

vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

imshow( "Match", img_matches);

cvWaitKey();

return 0;

}

另外: SURF SIFT

/*

SIFT sift;

sift(img_1, Mat(), keyPoints_1, descriptors_1);

sift(img_2, Mat(), keyPoints_2, descriptors_2);

BruteForceMatcher >? matcher;

*/

/*

SURF surf;

surf(img_1, Mat(), keyPoints_1);

surf(img_2, Mat(), keyPoints_2);

SurfDescriptorExtractor extrator;

extrator.compute(img_1, keyPoints_1, descriptors_1);

extrator.compute(img_2, keyPoints_2, descriptors_2);

BruteForceMatcher >? matcher;

*/

效果:

另外一個是尋找目標匹配

在右邊的場景圖里面尋找左邊那幅圖的starbucks標志

效果如下:

需要在之前的那個imshow之前加上如下代碼即可完成一個簡單的功能展示:

// localize the object

std::vector obj;

std::vector scene;

for (size_t i = 0; i < good_matches.size(); ++i)

{

// get the keypoints from the good matches

obj.push_back(keyPoints_1[ good_matches[i].queryIdx ].pt);

scene.push_back(keyPoints_2[ good_matches[i].trainIdx ].pt);

}

Mat H = findHomography( obj, scene, CV_RANSAC );

// get the corners from the image_1

std::vector obj_corners(4);

obj_corners[0] = cvPoint(0,0);

obj_corners[1] = cvPoint( img_1.cols, 0);

obj_corners[2] = cvPoint( img_1.cols, img_1.rows);

obj_corners[3] = cvPoint( 0, img_1.rows);

std::vector scene_corners(4);

perspectiveTransform( obj_corners, scene_corners, H);

// draw lines between the corners (the mapped object in the scene - image_2)

line( img_matches, scene_corners[0] + Point2f( img_1.cols, 0), scene_corners[1] + Point2f( img_1.cols, 0),Scalar(0,255,0));

line( img_matches, scene_corners[1] + Point2f( img_1.cols, 0), scene_corners[2] + Point2f( img_1.cols, 0),Scalar(0,255,0));

line( img_matches, scene_corners[2] + Point2f( img_1.cols, 0), scene_corners[3] + Point2f( img_1.cols, 0),Scalar(0,255,0));

line( img_matches, scene_corners[3] + Point2f( img_1.cols, 0), scene_corners[0] + Point2f( img_1.cols, 0),Scalar(0,255,0));

代碼片:

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/features2d/features2d.hpp"

#include

int main( )

{

cv::Ptr<:featuredetector> detector = cv::FeatureDetector::create( "SIFT" );

cv::Ptr<:descriptorextractor> extractor = cv::DescriptorExtractor::create("SIFT" );

cv::Mat im = cv::imread("box.png", CV_LOAD_IMAGE_COLOR );

std::vector<:keypoint> keypoints;

cv::Mat descriptors;

detector->detect( im, keypoints);

extractor->compute( im,keypoints,descriptors);

int duplicateNum = 0;

for (int i=0;i

{

for (int j=i+1;j

{

float dist = abs((keypoints[i].pt.x-keypoints[j].pt.x))+abs((keypoints[i].pt.y-keypoints[j].pt.y));

if (dist == 0)

{

cv::Mat descriptorDiff = descriptors.row(i)-descriptors.row(j);

double diffNorm = cv::norm(descriptorDiff);

std::cout<

duplicateNum++;

}

}

}

std::cout<

return 1;

}

本文同步分享在 博客“shiter”(CSDN)。

如有侵權,請聯系 support@oschina.cn 刪除。

本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

總結

以上是生活随笔為你收集整理的opencv检测相交点_OpenCV特征点检测------ORB特征的全部內容,希望文章能夠幫你解決所遇到的問題。

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