轮廓处理函数详细(转)
輪廓處理函數詳細
ApproxChains
用多邊形曲線逼近 Freeman 鏈
CvSeq* cvApproxChains( CvSeq* src_seq, CvMemStorage* storage, int method=CV_CHAIN_APPROX_SIMPLE, double parameter=0, int minimal_perimeter=0, int recursive=0 );?
src_seq這是一個單獨的逼近程序。 對同樣的逼近標識,函數 cvApproxChains 與 cvFindContours 的工作方式一模一樣。它返回發現的第一個輪廓的指針。其它的逼近模塊,可以用返回結構中的 v_next 和 v_next 域來訪問
StartReadChainPoints
初始化鏈讀取
void cvStartReadChainPoints( CvChain* chain, CvChainPtReader* reader );?
? 鏈的指針
reader
? 鏈的讀取狀態
函數 cvStartReadChainPoints 初始化一個特殊的讀取器 (參考 Dynamic Data Structures以獲得關于集合與序列的更多內容).
ReadChainPoint
得到下一個鏈的點
CvPoint cvReadChainPoint( CvChainPtReader* reader );?
reader函數 cvReadChainPoint返回當前鏈的點,并且更新讀取位置。
ApproxPoly
用指定精度逼近多邊形曲線
CvSeq* cvApproxPoly( const void* src_seq, int header_size, CvMemStorage* storage, int method, double parameter, int parameter2=0 );?
src_seq函數 cvApproxPoly逼近一個或多個曲線,并返回逼近結果。對多個曲線的逼近,生成的樹將與輸入的具有同樣的結構。(1:1 的對應關系).
BoundingRect
計算點集的最外面(up-right)矩形邊界
CvRect cvBoundingRect( CvArr* points, int update=0 );?
points- update=0, contour ~ CvContour*: 不計算矩形邊界,但直接由輪廓頭的 rect域得到。
- update=1, contour ~ CvContour*: 計算矩形邊界,而且將結果寫入到輪廓頭的 rect域中 header.
- update=0, contour ~ CvSeq* or CvMat*: 計算并返回邊界矩形
- update=1, contour ~ CvSeq* or CvMat*: 產生運行錯誤 (runtime error is raised)
函數 cvBoundingRect返回二維點集的最外面 (up-right)矩形邊界。
ContourArea
計算整個輪廓或部分輪廓的面積
double cvContourArea( const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ );?
contour函數 cvContourArea計算整個輪廓或部分輪廓的面積。 對后面的情況,面積表示輪廓部分和起始點連線構成的封閉部分的面積。如下圖所示:
?
NOTE: 輪廓的方向影響面積的符號。因此函數也許會返回負的結果。應用函數 fabs()得到面積的絕對值。
ArcLength
計算輪廓周長或曲線長度
double cvArcLength( const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 );?
curve- is_closed=0 - 假設曲線不閉合
- is_closed>0 - 假設曲線閉合
- is_closed<0 - 若曲線是序列,檢查 ((CvSeq*)curve)->flags 中的標識 CV_SEQ_FLAG_CLOSED 來確定曲線是否閉合。否則 (曲線由點集的數組 (CvMat*) 表示) 假設曲線不閉合。
函數 cvArcLength通過依次計算序列點之間的線段長度,并求和來得到曲線的長度。
CreateContourTree
創建輪廓的繼承表示形式
CvContourTree* cvCreateContourTree( const CvSeq* contour, CvMemStorage* storage, double threshold );?
contour函數 cvCreateContourTree 為輸入輪廓 contour 創建一個二叉樹,并返回樹根的指針。如果參數 threshold 小于或等于 0 ,則函數創建一個完整的二叉樹。如果 threshold 大于 0 , 函數用 threshold指定的精度創建二叉樹:如果基線的截斷區域頂點小于threshold,該數就停止生長并作為函數的最終結果返回。
ContourFromContourTree
由樹恢復輪廓
CvSeq* cvContourFromContourTree( const CvContourTree* tree, CvMemStorage* storage, CvTermCriteria criteria );?
tree函數 cvContourFromContourTree 從二叉樹恢復輪廓。參數 criteria決定了重構的精度和使用樹的數目及層次。所以它可建立逼近的輪廓。 函數返回重構的輪廓。
MatchContourTrees
用樹的形式比較兩個輪廓
double cvMatchContourTrees( const CvContourTree* tree1, const CvContourTree* tree2, int method, double threshold );?
tree1函數 cvMatchContourTrees 計算兩個輪廓樹的匹配值。從樹根開始通過逐層比較來計算相似度。如果某層的相似度小于 threshold, 則中斷比較過程,且返回當前的差值。
計算幾何
MaxRect
對兩個給定矩形,尋找矩形邊界
CvRect cvMaxRect( const CvRect* rect1, const CvRect* rect2 );?
rect1函數 cvMaxRect尋找包含兩個輸入矩形的具有最小面積的矩形邊界。
CvBox2D
旋轉的二維盒子
typedef struct CvBox2D { CvPoint2D32f center; CvSize2D32f size; float angle; } CvBox2D;BoxPoints
尋找盒子的頂點
void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] );?
box函數 cvBoxPoints計算輸入的二維盒子的定點。下面是函數代碼:
void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] ) { float a = (float)cos(box.angle)*0.5f; float b = (float)sin(box.angle)*0.5f; pt[0].x = box.center.x - a*box.size.height - b*box.size.width; pt[0].y = box.center.y + b*box.size.height - a*box.size.width; pt[1].x = box.center.x + a*box.size.height - b*box.size.width; pt[1].y = box.center.y - b*box.size.height - a*box.size.width; pt[2].x = 2*box.center.x - pt[0].x; pt[2].y = 2*box.center.y - pt[0].y; pt[3].x = 2*box.center.x - pt[1].x; pt[3].y = 2*box.center.y - pt[1].y; }FitEllipse
二維點集的橢圓擬合
CvBox2D cvFitEllipse2( const CvArr* points );?
points函數 cvFitEllipse 對給定的一組二維點集作橢圓的最佳擬合(最小二乘意義上的)。返回的結構與 cvEllipse 中的意義類似,除了 size表示橢圓軸的整個長度,而不是一半長度。
FitLine
2D 或 3D 點集的直線擬合
void cvFitLine( const CvArr* points, int dist_type, double param, double reps, double aeps, float* line );?
points函數 cvFitLine 通過求 sumiρ(ri) 的最小值方法,用 2D 或 3D 點集擬合直線,其中 ri是第 i 個點到直線的距離, ρ(r) 是下面的距離函數之一:
dist_type=CV_DIST_L2 (L 2): ρ(r)=r 2/2 (最簡單和最快的最小二乘法) dist_type=CV_DIST_L1 (L 1): ρ(r)=r dist_type=CV_DIST_L12 (L 1-L 2): ρ(r)=2?[sqrt(1+r 2/2) - 1] dist_type=CV_DIST_FAIR (Fair): ρ(r)=C 2?[r/C - log(1 + r/C)], C=1.3998 dist_type=CV_DIST_WELSCH (Welsch): ρ(r)=C 2/2?[1 - exp(-(r/C) 2)], C=2.9846 dist_type=CV_DIST_HUBER (Huber): ρ(r)= r 2/2, if r < C C?(r-C/2), otherwise; C=1.345ConvexHull2
發現點集的凸外形
CvSeq* cvConvexHull2( const CvArr* input, void* hull_storage=NULL, int orientation=CV_CLOCKWISE, int return_points=0 );?
points函數 cvConvexHull2 使用 Sklansky 算法計算 2D 點集的凸外形。如果 hull_storage 是內存存儲倉, 函數根據 return_points 的值,創建一個包含外形的點集或指向這些點的指針的序列。
例子. 由點集序列或數組創建凸外形
#include "cv.h" #include "highgui.h" #include <stdlib.h> #define ARRAY 0 void main( int argc, char** argv ) { IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 ); cvNamedWindow( "hull", 1 ); #if !ARRAY CvMemStorage* storage = cvCreateMemStorage(); #endif for(;;) { int i, count = rand()0 + 1, hullcount; CvPoint pt0; #if !ARRAY CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage ); CvSeq* hull; for( i = 0; i < count; i++ ) { pt0.x = rand() % (img->width/2) + img->width/4; pt0.y = rand() % (img->height/2) + img->height/4; cvSeqPush( ptseq, &pt0 ); } hull = cvConvexHull2( ptseq, 0, CV_CLOCKWISE, 0 ); hullcount = hull->total; #else CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0])); int* hull = (int*)malloc( count * sizeof(hull[0])); CvMat point_mat = cvMat( 1, count, CV_32SC2, points ); CvMat hull_mat = cvMat( 1, count, CV_32SC1, hull ); for( i = 0; i < count; i++ ) { pt0.x = rand() % (img->width/2) + img->width/4; pt0.y = rand() % (img->height/2) + img->height/4; points[i] = pt0; } cvConvexHull2( &point_mat, &hull_mat, CV_CLOCKWISE, 0 ); hullcount = hull_mat.cols; #endif cvZero( img ); for( i = 0; i < count; i++ ) { #if !ARRAY pt0 = *CV_GET_SEQ_ELEM( CvPoint, ptseq, i ); #else pt0 = points[i]; #endif cvCircle( img, pt0, 2, CV_RGB( 255, 0, 0 ), CV_FILLED ); } #if !ARRAY pt0 = **CV_GET_SEQ_ELEM( CvPoint*, hull, hullcount - 1 ); #else pt0 = points[hull[hullcount-1]]; #endif for( i = 0; i < hullcount; i++ ) { #if !ARRAY CvPoint pt = **CV_GET_SEQ_ELEM( CvPoint*, hull, i ); #else CvPoint pt = points[hull[i]]; #endif cvLine( img, pt0, pt, CV_RGB( 0, 255, 0 )); pt0 = pt; } cvShowImage( "hull", img ); int key = cvWaitKey(0); if( key == 27 ) // 'ESC' break; #if !ARRAY cvClearMemStorage( storage ); #else free( points ); free( hull ); #endif } }CheckContourConvexity
測試輪廓的凸性
int cvCheckContourConvexity( const CvArr* contour );?
contour函數 cvCheckContourConvexity輸入的輪廓是否為凸的。必須是簡單輪廓,比如沒有自交叉。
CvConvexityDefect
用來描述一個簡單輪廓凸性缺陷的結構體
typedef struct CvConvexityDefect { CvPoint* start; CvPoint* end; CvPoint* depth_point; float depth; } CvConvexityDefect;Picture. Convexity defects of hand contour.
ConvexityDefects
發現輪廓凸形缺陷
CvSeq* cvConvexityDefects( const CvArr* contour, const CvArr* convexhull, CvMemStorage* storage=NULL );?
contour函數 cvConvexityDefects 發現輸入輪廓的所有凸性缺陷,并且返回 CvConvexityDefect結構序列。
MinAreaRect2
對給定的 2D 點集,尋找最小面積的包圍矩形
CvBox2D cvMinAreaRect2( const CvArr* points, CvMemStorage* storage=NULL );?
points函數 cvMinAreaRect2通過建立凸外形并且旋轉外形以尋找給定 2D 點集的最小面積的包圍矩形.
Picture. Minimal-area bounding rectangle for contour
MinEnclosingCircle
對給定的 2D 點集,尋找最小面積的包圍圓形
int cvMinEnclosingCircle( const CvArr* points, CvPoint2D32f* center, float* radius );?
points函數 cvMinEnclosingCircle對給定的 2D 點集迭代尋找最小面積的包圍圓形。如果產生的圓包含所有點,返回非零。否則返回零(算法失敗)。
CalcPGH
計算輪廓的 pair-wise 幾何直方圖
void cvCalcPGH( const CvSeq* contour, CvHistogram* hist );?
contour函數 cvCalcPGH 計算輪廓的 2D pair-wise(Hunnish: 不知如何翻譯,只好保留) 幾何直方圖 (pair-wise geometrical histogram :PGH), 算法描述見 [Iivarinen97]. 算法考慮的每一對輪廓邊緣。計算每一對邊緣之間的夾角以及最大最小距離。具體做法是,輪流考慮每一個邊緣做為基準,函數循環遍歷所有邊緣。在考慮基準邊緣和其它邊緣的時候, 選擇非基準線上的點到基準線上的最大和最小距離。邊緣之間的角度定義了直方圖的行,而在其中增加對應計算出來的最大和最小距離的所有直方塊, (即直方圖是 [Iivarninen97] 定義中的轉置). 該直方圖用來做輪廓匹配。
轉載于:https://www.cnblogs.com/xingma0910/archive/2013/03/13/2957925.html
總結
以上是生活随笔為你收集整理的轮廓处理函数详细(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ZOJ-2770 Burn the Li
- 下一篇: 算法题007 计算n的阶乘