Opencv2.4.9源码分析要点摘录
生活随笔
收集整理的這篇文章主要介紹了
Opencv2.4.9源码分析要点摘录
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以下摘錄自
http://blog.csdn.net/zhaocj?viewmode=contents
Opencv2.4.9源碼分析要點摘錄
Boosting
AdaBoost的計算步驟:
1、設有n個樣本x1, …, xn,它們所希望得到的輸出(即分類)為y1, …, yn,y∈{-1, 1};
2、初始化每個樣本的權值;
3、進行迭代:m = 1, …, M
①找到使誤差率 最小的弱分類器km(x);
②計算km(x)的權值;
③得到新的強分類器;
④更新每個樣本的權值;
⑤對權值wi(m+1)進行歸一化處理,使∑iwi(m+1)= 1;
4、得到最終的強分類器
構建Boosting的參數:
CvBoostParams::CvBoostParams() ?
{ ?
......?
} ?
CvBoostParams::CvBoostParams( int _boost_type, int _weak_count, ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? double _weight_trim_rate, int _max_depth, ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? bool _use_surrogates, const float* _priors ) ?
{ ?
......
}
其中參數的含義為:
boost_type表示Boosting算法的類型,可以是CvBoost::DISCRETE、CvBoost::REAL、CvBoost::LOGIT或
CvBoost::GENTLE這4類中的任意一個,OpenCV推薦使用GentleAdaBoost或Real AdaBoost算法
_weak_count表示弱分類器的數量,即迭代的次數
_weight_trim_rate表示裁剪率,在0~1之間,默認值為0.95,在迭代過程中,那些歸一化后的樣本權值
wi(m)小于該裁剪率的樣本將不進入下次迭代
_max_depth表示構建決策樹的最大深度
_use_surrogates表示在構建決策樹時,是否使用替代分叉屬性
_priors表示樣本的先驗概率
CvBoost類的兩個構造函數: ?
CvBoost::CvBoost( const Mat& _train_data, int _tflag, ?
? ? ? ? ? ? ? ?const Mat& _responses, const Mat& _var_idx, ?
? ? ? ? ? ? ? ?const Mat& _sample_idx, const Mat& _var_type, ?
? ? ? ? ? ? ? ?const Mat& _missing_mask, ?
? ? ? ? ? ? ? ?CvBoostParams _params ) ?
{
......
}
CvBoost::CvBoost() ?
{ ?
......
}?
兩個train函數:
bool CvBoost::train( CvMLData* _data, ? ?//訓練樣本數據 ?
? ? ? ? ? ? ?CvBoostParams _params, ? ?//構建Boosting的參數 ?
? ? ? ? ? ? ?bool update ) ?
//update表示是更新分類器,還是重新創建分類器,默認是false,表示重新創建 ?
{ ?
......
}
bool ?
CvBoost::train( const CvMat* _train_data, int _tflag, ?
? ? ? ? ? ? ? const CvMat* _responses, const CvMat* _var_idx, ?
? ? ? ? ? ? ? const CvMat* _sample_idx, const CvMat* _var_type, ?
? ? ? ? ? ? ? const CvMat* _missing_mask, ?
? ? ? ? ? ? ? CvBoostParams _params, bool _update ) ?
{ ?
......
}
更新權值函數,當要初始化權值時,參數tree為0,表示此時還沒有弱分類器:
void ?
CvBoost::update_weights( CvBoostTree* tree ) { ?
......?
} ?
更新權值的核心函數:
void ?
CvBoost::update_weights_impl( CvBoostTree* tree, double initial_weights[2] ) ?
{
......
}
從上面的train函數可以看出,它主要是調用do_train函數,而CvBoostTree類沒有do_train函數,因此
train函數是調用CvBoostTree類的父類CvDTree中的do_train函數:
bool CvDTree::do_train( const CvMat* _subsample_idx ) ?
{ ?
......
}
遞歸調用try_split_node函數,完成決策樹的構造:
void ?
CvBoostTree::try_split_node( CvDTreeNode* node ) ?
{?
......
}
預測函數predict:
float ?
CvBoost::predict( const CvMat* _sample, const CvMat* _missing, ?
? ? ? ? ? ? ? ? ? CvMat* weak_responses, CvSlice slice, ?
? ? ? ? ? ? ? ? ? bool raw_mode, bool return_sum ) const?
{
......
}
OpenCV是用決策樹來得到弱分類器的,因此實現弱分類器的類CvBoostTree繼承于構建決策樹的類
CvDTree,CvBoostTree類內的train函數和try_split_node函數都是虛函數,它們是針對用于弱分類器設
計的決策樹的特殊性而重寫的函數,這樣的虛函數還有許多,如find_surrogate_split_ord、
find_split_ord_class、calc_node_value等。與CvDTree類的不同的地方;
1、構建弱分類器的每個樣本都有權值,即wi(m),在決策樹中被稱為是先驗概率;
2、用于衡量分類樹純度的不僅有基尼指數,還有錯誤分類率這種方法;
3、弱分類器只是一個用于研究兩類問題的決策樹,所有要相對簡單一點;
4、不同的弱分類器所應用的訓練樣本的數量可能會不同。
HoughLines
霍夫變換是一種特征提取技術。經典的霍夫變換能夠識別出圖像中的直線,后來又發展到能夠識別出任
意形狀,但更常見的識別形狀是圓和橢圓。函數HoughLines的作用就是能夠檢測出邊緣圖像中的直線。
函數HoughLines的霍夫變換直線檢測的步驟:
1、對邊緣圖像進行霍夫空間變換;
2、在4鄰域內找到霍夫空間變換的極大值;
3、對這些極大值安裝由大到小順序進行排序,極大值越大,越有可能是直線;
4、輸出直線。
?
函數HoughLines的原型為:
void HoughLines(InputArray image,OutputArray lines, double rho, double theta, int?
threshold, double srn=0,double stn=0 )
image為輸入圖像,要求是單通道的二值圖像
lines為輸出直線向量,兩個元素的向量(ρ,θ)代表一條直線,ρ是從原點(圖像的左上角)的距離
,θ是直線的角度(單位是弧度),0表示垂直線,π/2表示水平線
rho為距離分辨率
theta為角度分辨率
threshold為閾值,在步驟2中,只有大于該值的點才有可能被當作極大值,即至少有多少條正弦曲線交
于一點才被認為是直線
srn和stn在多尺度霍夫變換的時候才會使用,在這里我們只研究經典霍夫變換
HoughLines函數是在sources/modules/imgproc/src/hough.cpp文件中定義的;
?
cvHoughLines2函數是霍夫變換直線檢測的關鍵,函數的輸出為所檢測到的直線序列,它的第3個形
參“srn == 0 && stn == 0 ? CV_HOUGH_STANDARD :CV_HOUGH_MULTI_SCALE”表示的是該霍夫變換是經
典霍夫變換還是多尺度霍夫變換,它是由變量srn和stn決定的,只要這兩個變量有一個不為0,就進行多
尺度霍夫變換,否則為經典霍夫變換。另外cvHoughLines2函數不僅可以用于經典霍夫變換和多尺度霍夫
變換,還可以用于概率霍夫變換。
CV_IMPL CvSeq* ?
cvHoughLines2( CvArr* src_image, void* lineStorage, int method, ?
? ? ? ? ? ? ? ?double rho, double theta, int threshold, ?
? ? ? ? ? ? ? ?double param1, double param2 ) ?
{ ?
......
} ?
?
對于經典霍夫變換,調用的是icvHoughLinesStandard函數:
static void ?
icvHoughLinesStandard( const CvMat* img, float rho, float theta, ?
? ? ? ? ? ? ? ? ? ? ? ?int threshold, CvSeq *lines, int linesMax ) ?
{ ?
......
} ?
由于函數HoughLines只輸出直線所對應的角度和距離,所以在進行直線檢測的時候還要把其轉換為直角
坐標系下的數據,另外輸入圖像還必須是邊緣圖像;
總結
以上是生活随笔為你收集整理的Opencv2.4.9源码分析要点摘录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图解 windbg设置符号文件路径和使用
- 下一篇: 关于RasASM的一个编译错误