導航:首頁 > 源碼編譯 > flann匹配演算法

flann匹配演算法

發布時間:2023-06-10 02:03:36

㈠ 什麼是PCL編程

PCL(Point Cloud Library)是在吸收了前人點雲相關研究基礎上建立起來的大型跨平台開源C++編程庫,它實現了大量點雲相關的通用演算法和高效數據結構,涉及到點雲獲取、濾波、分割、配准、檢索、特徵提取、識別、追蹤、曲面重建、可視化等。

支持多種操作系統平台,可在Windows、Linux、Android、Mac OS X、部分嵌入式實時系統上運行。如果說OpenCV是2D信息獲取與處理的結晶,那麼PCL就在3D信息獲取與處理上具有同等地位,PCL是BSD授權方式,可以免費進行商業和學術應用。

(1)flann匹配演算法擴展閱讀

PCL利用OpenMP、GPU、CUDA等先進高性能計算技術,通過並行化提高程序實時性。K近鄰搜索操作的構架是基於FLANN (Fast Library for Approximate Nearest Neighbors)所實現的,速度也是目前技術中最快的。

PCL中的所有模塊和演算法都是通過Boost共享指針來傳送數據的,因而避免了多次復制系統中已存在的數據的需要,從0.6版本開始,PCL就已經被移入到Windows,MacOS和Linux系統,並且在Android系統也已經開始投入使用,這使得PCL的應用容易移植與多方發布。

參考資料來源:網路-PCL

㈡ opencv2.4.5中cvStereoGCState在哪個模塊

一、模塊:
①core. 該模塊定義了OpenCV的基本數據結構,包括多維數組(Multi-dimensional Array)和用於其它模塊的基本函數;
②imgproc. 該模塊用於圖像處理(Image Processing)。它包括線性和非線性的圖像濾波(Linear and Non-Linear Image Filtering)、幾何圖像變換(Geometrical image Transformations),包括縮放(Resize), affine and perspective warping, generic table-based remapping、顏色空間變換(Color Space Conversion)、直方圖(Histograms)等;
③video. 這是一個視頻分析模塊,包含運動估計(Motion Estimation)、背景消除/背景差分(Background Subtraction)和物體跟蹤(Object Tracking)演算法;
④calib3d. 該模塊包括基本的多視圖集合演算法(Multiple-View Geometry Algorithms)、單體和立體相機的標定(Single and Stereo Camera Calibration)、對象姿態估計(Object Pose Estimation)、雙目立體匹配(Stereo Correspondence)演算法和元素的三維重建(Elements of 3D Reconstruction);
⑤features2d. 包括顯著特徵檢測器(Salient Feature Detectors)、描述符(Descriptors)和描述符匹配器(Descriptor Matchers);
⑥objdetect. 包括預定義的目標和實例的檢測,如臉、眼、杯子、人以及汽車等; ⑦highgui. 該模塊擁有一個簡單易用的視頻捕捉(Video Capturing)、圖像及視頻解碼(Image and Video Codecs)以及簡單的UI介面;
⑧gpu. 包含不同模塊的GPU加速演算法。
另外還有其它的輔助模塊,比如FLANN以及Google的測試包、Python bindings等。

二、簡介:
OpenCV(Open Source Computer Vision)是一個用於實時處理的計算機視覺函數庫,它基於BSD許可證授權並且可免費用於學術研究和商業應用。它擁有C/C++、Python、和Java(僅用於Android)介面,並可在Windows、Linux、Mac和Android平台上運行。OpenCV庫包含大於2500個優化演算法,擁有5M的下載量和47K+的用戶群體。

㈢ opencv surf演算法連線顏色怎麼設置一樣

/**
* @file SURF_Homography
* @brief SURF detector + descriptor + FLANN Matcher + FindHomography
* @author A. Huaman
*/

#include <stdio.h>
#include <iostream>
#include <cv.h>
#include "opencv2/core/core.hpp"
#include <opencv2/opencv.hpp>
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/nonfree/nonfree.hpp>

using namespace cv;
using namespace std;

#ifdef _DEBUG
#pragma comment (lib, "opencv_calib3d246d.lib")
#pragma comment (lib, "opencv_contrib246d.lib")
#pragma comment (lib,"opencv_imgproc246d.lib")
#pragma comment (lib, "opencv_core246d.lib")
#pragma comment (lib, "opencv_features2d246d.lib")
#pragma comment (lib, "opencv_flann246d.lib")
#pragma comment (lib, "opencv_gpu246d.lib")
#pragma comment (lib, "opencv_highgui246d.lib")
#pragma comment (lib, "opencv_legacy246d.lib")
#pragma comment (lib, "opencv_ml246d.lib")
#pragma comment (lib, "opencv_objdetect246d.lib")
#pragma comment (lib, "opencv_ts246d.lib")
#pragma comment (lib, "opencv_video246d.lib")
#pragma comment (lib, "opencv_nonfree246d.lib")
#else
#pragma comment (lib, "opencv_calib3d246.lib")
#pragma comment (lib, "opencv_contrib246.lib")
#pragma comment (lib, "opencv_imgproc246.lib")
#pragma comment (lib, "opencv_core246.lib")
#pragma comment (lib, "opencv_features2d246.lib")
#pragma comment (lib, "opencv_flann246.lib")
#pragma comment (lib, "opencv_gpu246.lib")
#pragma comment (lib, "opencv_highgui246.lib")
#pragma comment (lib, "opencv_legacy246.lib")
#pragma comment (lib, "opencv_ml246.lib")
#pragma comment (lib, "opencv_objdetect246.lib")
#pragma comment (lib, "opencv_ts246.lib")
#pragma comment (lib, "opencv_video246.lib")
#pragma comment (lib, "opencv_nonfree246.lib")
#endif

int main()
{
initMole_nonfree();//初始化模塊,使用SIFT或SURF時用到
Ptr<FeatureDetector> detector = FeatureDetector::create( "SURF" );//創建SIFT特徵檢測器,可改成SURF/ORB
Ptr<DescriptorExtractor> descriptor_extractor = DescriptorExtractor::create( "SURF" );//創建特徵向量生成器,可改成SURF/ORB
Ptr<DescriptorMatcher> descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//創建特徵匹配器
if( detector.empty() || descriptor_extractor.empty() )
cout<<"fail to create detector!";

//讀入圖像
Mat img1 = imread("1.jpg");
Mat img2 = imread("2.jpg");

//特徵點檢測
double t = getTickCount();//當前滴答數
vector<KeyPoint> m_LeftKey,m_RightKey;
detector->detect( img1, m_LeftKey );//檢測img1中的SIFT特徵點,存儲到m_LeftKey中
detector->detect( img2, m_RightKey );
cout<<"圖像1特徵點個數:"<<m_LeftKey.size()<<endl;
cout<<"圖像2特徵點個數:"<<m_RightKey.size()<<endl;

//根據特徵點計算特徵描述子矩陣,即特徵向量矩陣
Mat descriptors1,descriptors2;
descriptor_extractor->compute( img1, m_LeftKey, descriptors1 );
descriptor_extractor->compute( img2, m_RightKey, 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_m_LeftKey,img_m_RightKey;
drawKeypoints(img1,m_LeftKey,img_m_LeftKey,Scalar::all(-1),0);
drawKeypoints(img2,m_RightKey,img_m_RightKey,Scalar::all(-1),0);
//imshow("Src1",img_m_LeftKey);
//imshow("Src2",img_m_RightKey);

//特徵匹配
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.2 * max_dist)
{
goodMatches.push_back(matches[i]);
}
}
cout<<"goodMatch個數:"<<goodMatches.size()<<endl;

//畫出匹配結果
Mat img_matches;
//紅色連接的是匹配的特徵點對,綠色是未匹配的特徵點
drawMatches(img1,m_LeftKey,img2,m_RightKey,goodMatches,img_matches,
Scalar::all(-1)/*CV_RGB(255,0,0)*/,CV_RGB(0,255,0),Mat(),2);

imshow("MatchSIFT",img_matches);
IplImage result=img_matches;

waitKey(0);

//RANSAC匹配過程
vector<DMatch> m_Matches=goodMatches;
// 分配空間
int ptCount = (int)m_Matches.size();
Mat p1(ptCount, 2, CV_32F);
Mat p2(ptCount, 2, CV_32F);

// 把Keypoint轉換為Mat
Point2f pt;
for (int i=0; i<ptCount; i++)
{
pt = m_LeftKey[m_Matches[i].queryIdx].pt;
p1.at<float>(i, 0) = pt.x;
p1.at<float>(i, 1) = pt.y;

pt = m_RightKey[m_Matches[i].trainIdx].pt;
p2.at<float>(i, 0) = pt.x;
p2.at<float>(i, 1) = pt.y;
}

// 用RANSAC方法計算F
Mat m_Fundamental;
vector<uchar> m_RANSACStatus; // 這個變數用於存儲RANSAC後每個點的狀態
findFundamentalMat(p1, p2, m_RANSACStatus, FM_RANSAC);

// 計算野點個數

int OutlinerCount = 0;
for (int i=0; i<ptCount; i++)
{
if (m_RANSACStatus[i] == 0) // 狀態為0表示野點
{
OutlinerCount++;
}
}
int InlinerCount = ptCount - OutlinerCount; // 計算內點
cout<<"內點數為:"<<InlinerCount<<endl;

// 這三個變數用於保存內點和匹配關系
vector<Point2f> m_LeftInlier;
vector<Point2f> m_RightInlier;
vector<DMatch> m_InlierMatches;

m_InlierMatches.resize(InlinerCount);
m_LeftInlier.resize(InlinerCount);
m_RightInlier.resize(InlinerCount);
InlinerCount=0;
float inlier_minRx=img1.cols; //用於存儲內點中右圖最小橫坐標,以便後續融合

for (int i=0; i<ptCount; i++)
{
if (m_RANSACStatus[i] != 0)
{
m_LeftInlier[InlinerCount].x = p1.at<float>(i, 0);
m_LeftInlier[InlinerCount].y = p1.at<float>(i, 1);
m_RightInlier[InlinerCount].x = p2.at<float>(i, 0);
m_RightInlier[InlinerCount].y = p2.at<float>(i, 1);
m_InlierMatches[InlinerCount].queryIdx = InlinerCount;
m_InlierMatches[InlinerCount].trainIdx = InlinerCount;

if(m_RightInlier[InlinerCount].x<inlier_minRx) inlier_minRx=m_RightInlier[InlinerCount].x; //存儲內點中右圖最小橫坐標

InlinerCount++;
}
}

// 把內點轉換為drawMatches可以使用的格式
vector<KeyPoint> key1(InlinerCount);
vector<KeyPoint> key2(InlinerCount);
KeyPoint::convert(m_LeftInlier, key1);
KeyPoint::convert(m_RightInlier, key2);

// 顯示計算F過後的內點匹配
Mat OutImage;
drawMatches(img1, key1, img2, key2, m_InlierMatches, OutImage);
cvNamedWindow( "Match features", 1);
cvShowImage("Match features", &IplImage(OutImage));
waitKey(0);

cvDestroyAllWindows();

//矩陣H用以存儲RANSAC得到的單應矩陣
Mat H = findHomography( m_LeftInlier, m_RightInlier, RANSAC );

//存儲左圖四角,及其變換到右圖位置
std::vector<Point2f> obj_corners(4);
obj_corners[0] = Point(0,0); obj_corners[1] = Point( img1.cols, 0 );
obj_corners[2] = Point( img1.cols, img1.rows ); obj_corners[3] = Point( 0, img1.rows );
std::vector<Point2f> scene_corners(4);
perspectiveTransform( obj_corners, scene_corners, H);

//畫出變換後圖像位置
Point2f offset( (float)img1.cols, 0);
line( OutImage, scene_corners[0]+offset, scene_corners[1]+offset, Scalar( 0, 255, 0), 4 );
line( OutImage, scene_corners[1]+offset, scene_corners[2]+offset, Scalar( 0, 255, 0), 4 );
line( OutImage, scene_corners[2]+offset, scene_corners[3]+offset, Scalar( 0, 255, 0), 4 );
line( OutImage, scene_corners[3]+offset, scene_corners[0]+offset, Scalar( 0, 255, 0), 4 );
imshow( "Good Matches & Object detection", OutImage );

waitKey(0);
imwrite("warp_position.jpg",OutImage);

int drift = scene_corners[1].x; //儲存偏移量

㈣ 求在vs2010和opencv 2.2環境下 sift匹配圖像源碼,求大神。

#include<ctime>

#include<iostream>

#include"opencv2/core/core.hpp"

#include"opencv2/features2d/features2d.hpp"

#include"opencv2/highgui/highgui.hpp"

#include"opencv2/calib3d/calib3d.hpp"

usingnamespacecv;

usingnamespacestd;

voidreadme();

//主函數

intmain(intargc,char*argv[])

{

if(argc>3)

{

readme();

return-1;

}

//默認參數

if(argc<3)

{

argv[1]="box.png";

argv[2]="box_in_scene.png";

}

//載入圖像

Matimg_object=imread(argv[1],CV_LOAD_IMAGE_GRAYSCALE);

Matimg_scene=imread(argv[2],CV_LOAD_IMAGE_GRAYSCALE);

if(!img_object.data||!img_scene.data)

{

std::cout<<"--(!)Errorreadingimages"<<std::endl;

return-1;

}

doublebegin=clock();

//第一步:用SIFT運算元檢測關鍵點

SiftFeatureDetectordetector;//構造函數採用默認的

std::vector<KeyPoint>keypoints_object,keypoints_scene;//構造2個專門由點組成的點向量用來存儲特徵點

detector.detect(img_object,keypoints_object);//將img_object圖像中檢測到的特徵點存儲起來放在keypoints_object中

detector.detect(img_scene,keypoints_scene);//同理

//在圖像中畫出特徵點

Matimg_keypoints_object,img_keypoints_scene;

//先在內存中繪制

drawKeypoints(img_object,keypoints_object,img_keypoints_object,Scalar::all(-1),DrawMatchesFlags::DEFAULT);//在內存中畫出特徵點

drawKeypoints(img_scene,keypoints_scene,img_keypoints_scene,Scalar::all(-1),DrawMatchesFlags::DEFAULT);

//再顯示

imshow("sift_keypoints_object",img_keypoints_object);

imshow("sift_keypoints_scene",img_keypoints_scene);

//第二步:計算特徵向量

;//定義描述子對象

Matdescriptors_1,descriptors_2;//存放特徵向量的矩陣

//計算特徵向量

extractor.compute(img_object,keypoints_object,descriptors_1);

extractor.compute(img_scene,keypoints_scene,descriptors_2);

//第三步,用FLANN進行匹配特徵向量

FlannBasedMatchermatcher;//定義一個FlannBasedMatcher對象

std::vector<DMatch>matches;

matcher.match(descriptors_1,descriptors_2,matches);

doublemax_dist=0;

doublemin_dist=100;

//計算特徵點間的最大最小距離

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

{

doubledist=matches[i].distance;

if(dist<min_dist)min_dist=dist;

if(dist>max_dist)max_dist=dist;

}

printf("--Maxdist:%f ",max_dist);

printf("--Mindist:%f ",min_dist);

//只保留好的匹配:特徵點距離小於3倍最小距離

std::vector<DMatch>good_matches;

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

{

if(matches[i].distance<3*min_dist)

{

good_matches.push_back(matches[i]);

}

}

//在內存中繪制保留的好的匹配

Matimg_matches;

drawMatches(img_object,keypoints_object,img_scene,keypoints_scene,

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

vector<char>(),DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);

//在場景中定位目標圖像

std::vector<Point2f>obj;

std::vector<Point2f>scene;

std::cout<<"good_matches.size():"<<good_matches.size()<<" ";

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

{

//從好的匹配中找到特徵點

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

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

}

//基於匹配的關鍵點找出相應的變換

cv::MatH=cv::findHomography(cv::Mat(obj),cv::Mat(scene),CV_RANSAC);

//找到目標的角點

std::vector<Point2f>obj_corners(4);

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

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

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

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

std::vector<Point2f>scene_corners(4);

//映射點群,在場景中獲取目標的坐標

cv::perspectiveTransform(cv::Mat(obj_corners),cv::Mat(scene_corners),H);

//目標的角點之間連線(框出目標)

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

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

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

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

//顯示保留的好的匹配

imshow("GoodMatches&Objectdetection-SIFT",img_matches);

imwrite("GoodMatches&Objectdetection-SIFT.png",img_matches);

doubleend=clock();

cout<<" SURF-elapsedtimeis:"<<(end-begin)/CLOCKS_PER_SEC*1000<<"ms ";

waitKey(0);

return0;

}

/**

*@函數readme

*/

voidreadme()

{

std::cout<<"Usage:./cv_sift_demo<img1><img2>"<<std::endl;

}


box_in_scene.png

㈤ 使用OpenCV和Python進行圖像拼接

么是圖像拼接呢?簡單來說,對於輸入應該有一組圖像,輸出是合成圖像。同時,必須保留圖像之間的邏輯流。

首先讓我們了解圖像拼接的概念。基本上,如果你想捕捉一個大的場景,你的相機只能提供一個特定解析度的圖像(如:640×480),這當然不足以捕捉大的全景。所以,我們可以做的是捕捉整個場景的多個圖像,然後把所有的碎片放在一起,形成一個大的圖像。這些有序的照片被稱為全景。獲取多幅圖像並將其轉換成全景圖的整個過程稱為圖像拼接。

首先,需要安裝opencv 3.4.2.16。

接下來我們將導入我們將在Python代碼中使用的庫:

在我們的教程中,我們將拍攝這張精美的照片,我們會將其分成兩張左右兩張照片,然後我們會嘗試拍攝相同或非常相似的照片。

因此,我將此圖像切成兩個圖像,它們會有某種重疊區域:

在此,我們將列出我們應採取的步驟,以取得最終的結果:

因此,從第一步開始,我們將導入這兩個圖像並將它們轉換為灰度,如果您使用的是大圖像,我建議您使用cv2.resize,因為如果您使用較舊的計算機,它可能會非常慢並且需要很長時間。如果要調整圖像大小,即調整50%,只需將fx = 1更改為fx = 0.5即可。

我們還需要找出兩幅圖像中匹配的特徵。我們將使用opencv_contrib的SIFT描述符。SIFT (Scale constant Feature Transform)是一種非常強大的OpenCV演算法。這些最匹配的特徵作為拼接的基礎。我們提取兩幅圖像的關鍵點和sift描述符如下:

kp1和kp2是關鍵點,des1和des2是圖像的描述符。如果我們用特徵來畫這幅圖,它會是這樣的:

左邊的圖像顯示實際圖像。右側的圖像使用SIFT檢測到的特徵進行注釋:

一旦你有了兩個圖像的描述符和關鍵點,我們就會發現它們之間的對應關系。我們為什麼要這么做?為了將任意兩個圖像連接成一個更大的圖像,我們必須找到重疊的點。這些重疊的點會讓我們根據第一幅圖像了解第二幅圖像的方向。根據這些公共點,我們就能知道第二幅圖像是大是小還是旋轉後重疊,或者縮小/放大後再fitted。所有此類信息的產生是通過建立對應關系來實現的。這個過程稱為registration。

對於匹配圖像,可以使用opencv提供的FLANN或BFMatcher方法。我會寫兩個例子證明我們會得到相同的結果。兩個示例都匹配兩張照片中更相似的特徵。當我們設置參數k = 2時,這樣我們就要求knnMatcher為每個描述符給出2個最佳匹配。「matches」是列表的列表,其中每個子列表由「k」個對象組成。以下是Python代碼:

FLANN匹配代碼:

BFMatcher匹配代碼:

通常在圖像中,圖像的許多地方可能存在許多特徵。所以我們過濾掉所有的匹配來得到最好的。因此我們使用上面得到的前2個匹配項進行比值檢驗。如果下面定義的比值大於指定的比值,則考慮匹配。

現在我們定義在圖像上繪制線條的參數,並給出輸出以查看當我們在圖像上找到所有匹配時的樣子:

這是輸出的匹配圖像:

這部分完整Python代碼:

因此,一旦我們獲得了圖像之間的最佳匹配,我們的下一步就是計算單應矩陣。如前所述,單應矩陣將與最佳匹配點一起使用,以估計兩個圖像內的相對方向變換。

在OpenCV中估計單應性是一項簡單的任務,只需一行代碼:

在開始編碼拼接演算法之前,我們需要交換圖像輸入。所以img_現在會取右圖像img會取左圖像。

那麼讓我們進入拼接編碼:

因此,首先,我們將最小匹配條件count設置為10(由MIN_MATCH_COUNT定義),並且只有在匹配良好的匹配超出所需匹配時才進行拼接。否則,只需顯示一條消息,說明匹配不夠。

因此,在if語句中,我們將關鍵點(從匹配列表)轉換為findHomography()函數的參數。

只需在這段代碼中討論cv2.imshow(「original_image_overlapping.jpg」,img2),我們就會顯示我們收到的圖像重疊區域:

因此,一旦我們建立了單應性,我們需要扭曲視角,我們將以下單應矩陣應用於圖像:

所以我們使用如下:

在上面兩行Python代碼中,我們從兩個給定的圖像中獲取重疊區域。然後在「dst」中我們只接收到沒有重疊的圖像的右側,因此在第二行代碼中我們將左側圖像放置到最終圖像。所以在這一點上我們完全拼接了圖像:

剩下的就是去除圖像的黑色,所以我們將編寫以下代碼來從所有圖像邊框中刪除黑邊:

這是我們調用修剪邊界的最終定義函數,同時我們在屏幕上顯示該圖像。如果您願意,也可以將其寫入磁碟:

使用上面的Python代碼,我們將首先收到原始圖片:

這是完整的最終代碼:

在本教程中,我們學習了如何使用OpenCV執行圖像拼接和全景構造,並編寫了最終的圖像拼接代碼。

我們的圖像拼接演算法需要四個主要步驟:檢測關鍵點和提取局部不變描述符; 獲得圖像之間的匹配描述符; 應用RANSAC估計單應矩陣; 使用單應矩陣應用warping transformation。

當僅為兩個圖像構建全景圖時,該演算法在實踐中工作良好。

閱讀全文

與flann匹配演算法相關的資料

熱點內容
怎麼批量有順序的命名文件夾 瀏覽:209
杭州程序員健身 瀏覽:17
dvd光碟存儲漢子演算法 瀏覽:758
蘋果郵件無法連接伺服器地址 瀏覽:963
phpffmpeg轉碼 瀏覽:672
長沙好玩的解壓項目 瀏覽:145
專屬學情分析報告是什麼app 瀏覽:564
php工程部署 瀏覽:833
android全屏透明 瀏覽:737
阿里雲伺服器已開通怎麼辦 瀏覽:803
光遇為什麼登錄時伺服器已滿 瀏覽:302
PDF分析 瀏覽:486
h3c光纖全工半全工設置命令 瀏覽:143
公司法pdf下載 瀏覽:383
linuxmarkdown 瀏覽:350
華為手機怎麼多選文件夾 瀏覽:683
如何取消命令方塊指令 瀏覽:350
風翼app為什麼進不去了 瀏覽:779
im4java壓縮圖片 瀏覽:362
數據查詢網站源碼 瀏覽:151