就是首先隨機抽取觀測資料子集,我們假設視為這子集就是「內點」(局內點或者局內資料)。然後用這子集進行相關的擬合來計算模型引數(或者估計函式)。找到這模型(或者函式)以後,利用觀測點(資料)進行是否正確,如果求出來的模型能夠滿足足夠多的資料,我們視為很正確的資料。最後我們採納。但是,如果不適合,也就是說求出來的模型(或者函式,也可以是模型引數)滿足的資料點很少,我們就放棄,從新隨機抽取觀測資料子集,再進行上述的操作。這樣的運算進行n次,然後進行比較,如果第m(m(1)從surf 演算法預匹配資料集中隨機取出一些匹配點對,計算出變換矩陣h,記為模型m。理論上只需要4對點。
(2)計算資料集中所有資料與模型m的投影誤差,若誤差小於閾值,加入內點集 i ;
(3)如果當前內點集 i 元素個數大於最優內點集i_best
, 則更新 i_best = i,同時更新迭代次數k ;
(4) 如果迭代次數大於k,則退出 ; 否則迭代次數加1,並重複上述步驟;
注:在opencv中迭代次數k在不大於最大迭代次數的情況下,是在不斷更新而不是固定的;
其中,p為置信度,一般取0.995;w為」內點」的比例 ; m為計算模型所需要的最少樣本數=4;
在opencv裡,findfundamentalmat函式來得到變換模型。
(1)cv::findfundamentalmat()返回乙個基礎矩陣。
_points1:影象1的座標點
_points2:影象2的座標點
cv::mat cv::findfundamentalmat( inputarray _points1, inputarray _points2,
int method, double
param1, double
param2,
outputarray _mask )
intn = cvfindfundamentalmat
( &_pt1, &_pt2, &matf, method, param1, param2, p_mask );
//見(2)
if( n <= 0 )
f = scalar(0);
if( n == 1 )
f = f.rowrange(0, 3);
return f;
}
(2)cvfindfundamentalmat()返回乙個整數值
cv_impl int cvfindfundamentalmat( const cvmat* points1, const cvmat* points2,
cvmat* fmatrix, int method,
double param1, double param2, cvmat* mask )
if( mask || count >= 8 )
tempmask = cvcreatemat( 1, count, cv_8u );
if( !tempmask.empty() )
cvset( tempmask, cvscalarall(1.) );
cvfmestimator estimator(7);
if( count == 7 )
result = estimator.run7point(m1, m2, &_f9x3);
else
if( method == cv_fm_8point )
result = estimator.run8point(m1, m2, &_f3x3);
else
if( result )
cvconvert( fmatrix->rows == 3 ? &_f3x3 : &_f9x3, fmatrix );
if( mask && tempmask )
return result;
}
(3)
maxiters:最大迭代次數
m1,m2 :資料樣本
model:變換矩陣
reprojthreshold:投影誤差閾值 3
confidence:置信度 0.99
bool cvmodelestimator2::runransac( const cvmat* m1, const cvmat* m2, cvmat* model,
cvmat* mask0, double reprojthreshold,
double confidence, int maxiters )
else
//等於4個點
for( iter = 0; iter < niters; iter++ ) //不斷迭代
} nmodels = runkernel( ms1, ms2, models ); //估算近似變換矩陣,返回1 見(7)
if( nmodels <= 0 )
continue;
for( i = 0; i < nmodels; i++ )//執行一次
} }
if( maxgoodcount > 0 )
return result;
}
(4)getsubset()得到子集
bool cvmodelestimator2::getsubset( const cvmat* m1, const cvmat* m2,
cvmat* ms1, cvmat* ms2, int maxattempts )
if( checkpartialsubsets && (!checksubset( ms1, i+1 ) || !checksubset( ms2, i+1 )))//檢測點之間是否共線
i++;
} if( !checkpartialsubsets && i == modelpoints &&
(!checksubset( ms1, i ) || !checksubset( ms2, i )))
continue;
break;
} return i == modelpoints && iters < maxattempts; //返回找到的樣本點個數
}
(5)findinliers()找內點
int cvmodelestimator2::findinliers( const cvmat* m1, const cvmat* m2,
const cvmat* model, cvmat* _err,
cvmat* _mask, double threshold )
//--------------------------------------
void cvhomographyestimator::computereprojerror( const cvmat* m1, const cvmat* m2,const cvmat* model, cvmat* _err )
}
(6)cvransacupdatenumiters
對應上述k的計算公式
p:置信度
ep:外點比例
cvransacupdatenumiters( double p, double ep,
int model_points, int max_iters )
(7)
int cv::affine3destimator::runkernel( const cvmat* m1, const cvmat* m2, cvmat* model )
}cvmat cva = a;
cvmat cvb = b;
cvmat cvx;
cvreshape(model, &cvx, 1, 12);
cvsolve(&cva, &cvb, &cvx, cv_svd );//基於奇異值分解的最小二乘法
return
1;}
RANSAC演算法的簡單理解
影象拼接中看到了特徵匹配的部分,特徵匹配主要是特徵點的匹配。在特徵點匹配的時候,首先進行粗匹配,粗匹配通常是進行一對匹配點進行對比,誤差越小越可能是一對匹配點 精匹配方法中,我們可以用到ransac random sample consensus 隨機抽樣一致性 演算法。ransac可以用於的拼接技...
opencv3 2中的SURF用法
opencv3.2中surffeaturedetector surfdescriptorextractor bruteforcematcher這三個的使用方法已經和原先2.4版本前不一樣了。使用方法示例如下 ptrdetector surf create minhessian detector de...
python的演算法是指 python中的演算法
演算法定義 演算法 algorithm 是指解題方 而完整的描述,是一系列解決問題的清晰指令,演算法代表著用系統的方法描述解決問題的策略機制。也就是說,能夠對一定規範的輸入,在有限時間內獲得所要求的輸出。如果乙個演算法有缺陷,或不適合於某個問題,執行這個演算法將不會解決這個問題。不同的演算法可能用不...