輪廓處理函數
[ 編輯]
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涉及其它鏈的鏈指針storage存儲多邊形線段位置的緩存method逼近方法 (見函數 cvFindContours 的描述).parameter方法參數(現在不用).minimal_perimeter僅逼近周長大於 minimal_perimeter 輪廓。其它的鏈從結果中除去。recursive如果非 0, 函數從 src_seq 中利用 h_next 和 v_next links 連接逼近所有可訪問的鏈。如果為 0, 則僅逼近單鏈。
這是一個單獨的逼近程序。 對同樣的逼近標識,函數 cvApproxChains 與 cvFindContours 的工作方式一模一樣。它返回發現的第一個輪廓的指針。其它的逼近模塊,可以用返回結構中的 v_next 和 v_next 域來訪問
[ 編輯]
StartReadChainPoints
初始化鏈讀取
void cvStartReadChainPoints( CvChain* chain, CvChainPtReader* reader );
chain鏈的指針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點集數組序列header_size逼近曲線的頭尺寸storage逼近輪廓的容器。如果為 NULL, 則使用輸入的序列method逼近方法。目前僅支持 CV_POLY_APPROX_DP , 對應 Douglas-Peucker 算法.parameter方法相關參數。對 CV_POLY_APPROX_DP 它是指定的逼近精度parameter2如果 src_seq 是序列,它表示要麼逼近單個序列,要麼在 src_seq 的同一個或低級層次上逼近所有序列 (參考 cvFindContours 中對輪廓繼承結構的描述). 如果 src_seq 是點集的數組 (CvMat*) , 參數指定曲線是閉合 (parameter2!=0) 還是非閉合 (parameter2=0).
函數 cvApproxPoly 逼近一個或多個曲線,並返回逼近結果。對多個曲線的逼近,生成的樹將與輸入的具有同樣的結構。(1:1 的對應關係).
[ 編輯]
BoundingRect
計算點集的最外面(up-right)矩形邊界
CvRect cvBoundingRect( CvArr* points, int update=0 );
points二維點集,點的序列或向量 (CvMat)update更新標識。下面是輪廓類型和標識的一些可能組合:
- 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輪廓 (邊界點的序列或數組).slice感興趣輪廓部分的起始點,缺省是計算整個輪廓的面積。
函數 cvContourArea 計算整個輪廓或部分輪廓的面積。 對後面的情況,面積表示輪廓部分和起始點連線構成的封閉部分的面積。如下圖所示:
備註: 輪廓的方向影響面積的符號。因此函數也許會返回負的結果。應用函數 fabs() 得到面積的絕對值。
[ 編輯]
ArcLength
計算輪廓周長或曲線長度
double cvArcLength( const void* curve, CvSlice slice=CV_WHOLE_SEQ, int is_closed=-1 );
curve曲線點集序列或數組slice曲線的起始點,缺省是計算整個曲線的長度is_closed表示曲線是否閉合,有三種情況:
- 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輸入的輪廓storage輸出樹的容器threshold逼近精度
函數 cvCreateContourTree 為輸入輪廓 contour 創建一個二叉樹,並返回樹根的指針。如果參數 threshold 小於或等於 0 ,則函數創建一個完整的二叉樹。如果 threshold 大於 0 , 函數用 threshold 指定的精度創建二叉樹:如果基線的截斷區域頂點小於threshold,該數就停止生長並作為函數的最終結果返回。
[ 編輯]
ContourFromContourTree
由樹恢復輪廓
CvSeq* cvContourFromContourTree( const CvContourTree* tree, CvMemStorage* storage,
CvTermCriteria criteria );
tree輪廓樹storage重構的輪廓容器criteria停止重構的準則
函數 cvContourFromContourTree 從二叉樹恢復輪廓。參數 criteria 決定了重構的精度和使用樹的數目及層次。所以它可建立逼近的輪廓。 函數返回重構的輪廓。
[ 編輯]
MatchContourTrees
用樹的形式比較兩個輪廓
double cvMatchContourTrees( const CvContourTree* tree1, const CvContourTree* tree2,
int method, double threshold );
tree1第一個輪廓樹tree2第二個輪廓樹method相似度。僅支持 CV_CONTOUR_TREES_MATCH_I1 。threshold相似度閾值
函數 cvMatchContourTrees 計算兩個輪廓樹的匹配值。從樹根開始通過逐層比較來計算相似度。如果某層的相似度小於 threshold, 則中斷比較過程,且返回當前的差值。
[ 編輯]
計算幾何
[ 編輯]
MaxRect
對兩個給定矩形,尋找矩形邊界
CvRect cvMaxRect( const CvRect* rect1, const CvRect* rect2 );
rect1第一個矩形rect2第二個矩形
函數 cvMaxRect 尋找包含兩個輸入矩形的具有最小面積的矩形邊界。
[ 編輯]
CvBox2D
旋轉的二維盒子
typedef struct CvBox2D
{
CvPoint2D32f center; /* 盒子的中心 */
CvSize2D32f size; /* 盒子的長和寬 */
float angle; /* 水平軸與第一個邊的夾角,用角度度表示*/
}
CvBox2D;
[ 編輯]
PointSeqFromMat
從點向量中初始化點序列頭部
CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* mat,
CvContour* contour_header,
CvSeqBlock* block );
seq_kind
點序列的類型:一系列點(0),曲線(CV_SEQ_KIND_CURVE),封閉曲線(CV_SEQ_KIND_CURVE+CV_SEQ_FLAG_CLOSED) 等等。
mat輸入矩陣。輸入應該是連續的一維點向量,類型也應該是CV_32SC2或者CV_32FC2.contour_header輪廓頭部,被函數初始化。block序列塊頭部,被函數初始化。
函數cvPointSeqFromMat 初始化序列頭部,用來創建一個將給定矩陣中的元素形成的"虛擬"序列。沒有數據被拷貝。被初始化的頭部可以傳遞給其他任何包含輸入點序列的函數。沒有額外的元素加入序列,但是一些可能被移除。函數是cvMakeSeqHeaderForArray 的一個特別的變量,然後在內部使用。它返回初始化頭部的指針。需要注意的是,包含的邊界矩形(CvContour 的rect字段)沒有被初始化,如果你需要使用,需要自己調用cvBoundingRect。
以下是使用例子。
CvContour header;
CvSeqBlock block;
CvMat* vector = cvCreateMat( 1, 3, CV_32SC2 );
CV_MAT_ELEM( *vector, CvPoint, 0, 0 ) = cvPoint(100,100);
CV_MAT_ELEM( *vector, CvPoint, 0, 1 ) = cvPoint(100,200);
CV_MAT_ELEM( *vector, CvPoint, 0, 2 ) = cvPoint(200,100);
IplImage* img = cvCreateImage( cvSize(300,300), 8, 3 );
cvZero(img);
cvDrawContours( img, cvPointSeqFromMat(CV_SEQ_KIND_CURVE+CV_SEQ_FLAG_CLOSED,
vector, &header, &block), CV_RGB(255,0,0), CV_RGB(255,0,0), 0, 3, 8, cvPoint(0,0));
[ 編輯]
BoxPoints
尋找盒子的頂點
void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] );
box盒子pt頂點數組
函數 cvBoxPoints 計算輸入的二維盒子的頂點。下面是函數代碼:
void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] )
{
double angle = box.angle*CV_PI/180.
float a = (float)cos(angle)*0.5f;
float b = (float)sin(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 );
points2D 或 3D 點集,32-比特整數或浮點數座標dist_type擬合的距離類型 (見討論).param對某些距離的數字參數,如果是 0, 則選擇某些最優值reps, aeps半徑 (座標原點到直線的距離) 和角度的精度,一般設為0.01。line輸出的直線參數。2D 擬合情況下,它是包含 4 個浮點數的數組 (vx, vy, x0, y0),其中 (vx, vy) 是線的單位向量而 (x0, y0) 是線上的某個點. 對 3D 擬合,它是包含 6 個浮點數的數組 (vx, vy, vz, x0, y0, z0), 其中 (vx, vy, vz) 是線的單位向量,而 (x0, y0, z0) 是線上某點。
函數 cvFitLine 通過求 sumi:ρ(ri) 的最小值方法,用 2D 或 3D 點集擬合直線,其中 ri 是第 i 個點到直線的距離, ρ(r) 是下面的距離函數之一:
dist_type=CV_DIST_L2 (L2): ρ(r)=r2/2 (最簡單和最快的最小二乘法)
dist_type=CV_DIST_L1 (L1): ρ(r)=r
dist_type=CV_DIST_L12 (L1-L2): ρ(r)=2•[sqrt(1+r2/2) - 1]
dist_type=CV_DIST_FAIR (Fair): ρ(r)=C2•[r/C - log(1 + r/C)], C=1.3998
dist_type=CV_DIST_WELSCH (Welsch): ρ(r)=C2/2•[1 - exp(-(r/C)2)], C=2.9846
dist_type=CV_DIST_HUBER (Huber): ρ(r)= r2/2, if r < C; C•(r-C/2), otherwise; C=1.345
[ 編輯]
ConvexHull2
發現點集的凸外形
CvSeq* cvConvexHull2( const CvArr* input, void* hull_storage=NULL,
int orientation=CV_CLOCKWISE, int return_points=0 );
points2D 點集的序列或數組,32-比特整數或浮點數座標hull_storage輸出的數組(CvMat*) 或內存緩存 (CvMemStorage*),用以存儲凸外形。 如果是數組,則它應該是一維的,而且與輸入的數組/序列具有同樣數目的元素。輸出時,通過修改頭結構將數組裁減到凸外形的尺寸。orientation凸外形的旋轉方向: 逆時針或順時針 (CV_CLOCKWISE or CV_COUNTER_CLOCKWISE)return_points如果非零,hull_storage 為數組情況下,點集將以外形 (hull) 存儲,而不是頂點形式 (indices)。如果 hull_storag 為內存存儲模式下則存儲為點集形式(points)。
函數 cvConvexHull2 使用 Sklansky 算法計算 2D 點集的凸外形。如果 hull_storage 是內存存儲倉, 函數根據 return_points 的值,創建一個包含外形的點集或指向這些點的指針的序列。
例子. 由點集序列或數組創建凸外形
#include "cv.h"
#include "highgui.h"
#include <stdlib.h>
#define ARRAY 0 /* switch between array/sequence method by replacing 0<=>1 */
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()%100 + 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. 手部輪廓的凸形缺陷.
[ 編輯]
ConvexityDefects
發現輪廓凸形缺陷
CvSeq* cvConvexityDefects( const CvArr* contour, const CvArr* convexhull,
CvMemStorage* storage=NULL );
contour輸入輪廓convexhull用 cvConvexHull2 得到的凸外形,它應該包含輪廓的定點的指針或下標,而不是外形點的本身,即cvConvexHull2 中的參數 return_points 應該設置為 0.storage凸性缺陷的輸出序列容器。如果為 NULL, 使用輪廓或外形的存儲倉。
函數 cvConvexityDefects 發現輸入輪廓的所有凸性缺陷,並且返回 CvConvexityDefect 結構序列。
[ 編輯]
PointPolygonTest
測試點是否在多邊形中
double cvPointPolygonTest( const CvArr* contour,
CvPoint2D32f pt, int measure_dist );
contour輸入輪廓.pt針對輪廓需要測試的點。measure_dist如果非0,函數將估算點到輪廓最近邊的距離。
函數cvPointPolygonTest 決定測試點是否在輪廓內,輪廓外,還是輪廓的邊上(或者共邊的交點上),它的返回值是正負零,相對應的,當measure_dist=0時,返回值是1, -1,0, 同樣當 measure_dist≠0 ,它是返回一個從點到最近的邊的帶符號距離。
下面是函數輸出的結果,用圖片的每一個象素去測試輪廓的結果。
[ 編輯]
MinAreaRect2
對給定的 2D 點集,尋找最小面積的包圍矩形
CvBox2D cvMinAreaRect2( const CvArr* points, CvMemStorage* storage=NULL );
points點序列或點集數組storage可選的臨時存儲倉
函數 cvMinAreaRect2 通過建立凸外形並且旋轉外形以尋找給定 2D 點集的最小面積的包圍矩形.
Picture. Minimal-area bounding rectangle for contour
[ 編輯]
MinEnclosingCircle
對給定的 2D 點集,尋找最小面積的包圍圓形
int cvMinEnclosingCircle( const CvArr* points, CvPoint2D32f* center, float* radius );
points點序列或點集數組center輸出參數:圓心radius輸出參數:半徑
函數 cvMinEnclosingCircle 對給定的 2D 點集迭代尋找最小面積的包圍圓形。如果產生的圓包含所有點,返回非零。否則返回零(算法失敗)。
[ 編輯]
CalcPGH
計算輪廓的 pair-wise 幾何直方圖
void cvCalcPGH( const CvSeq* contour, CvHistogram* hist );
contour輸入輪廓,當前僅僅支持具有整數座標的點集hist計算出的直方圖,必須是兩維的。
函數 cvCalcPGH 計算輪廓的 2D pair-wise 幾何直方圖 (2D pair-wise geometrical histogram :PGH), 算法描述見 [Iivarinen97]. 算法考慮的每一對輪廓邊緣。計算每一對邊緣之間的夾角以及最大最小距離。具體做法是,輪流考慮每一個邊緣做為基準,函數循環遍歷所有其他的邊緣。在考慮基準邊緣和其它邊緣的時候, 選擇非基準線上的點到基準線上的最大和最小距離。邊緣之間的角度定義了直方圖的行,而在其中增加對應計算出來的最大和最小距離的所有直方塊, (即直方圖是 [Iivarninen97] 定義中的轉置). 該直方圖用來做輪廓匹配。
[ 編輯]
平面劃分
[ 編輯]
CvSubdiv2D
平面劃分
#define CV_SUBDIV2D_FIELDS() \
CV_GRAPH_FIELDS() \
int quad_edges; \
int is_geometry_valid; \
CvSubdiv2DEdge recent_edge; \
CvPoint2D32f topleft; \
CvPoint2D32f bottomright;
typedef struct CvSubdiv2D
{
CV_SUBDIV2D_FIELDS()
}
CvSubdiv2D;
平面劃分是將一個平面分割為一組互不重疊的能夠覆蓋整個平面的區域P(facets)。上面結構描述了建立在 2D 點集上的劃分結構,其中點集互相連接並且構成平面圖形,該圖形通過結合一些無限連接外部劃分點(稱為凸形點)的邊緣,將一個平面用邊按照其邊緣劃分成很多小區域(facets)。
對於每一個劃分操作,都有一個對偶劃分與之對應,對偶的意思是小區域和點(劃分的頂點)變換角色,即在對偶劃分中,小區域被當做一個頂點(以下稱之為虛擬點),而原始的劃分頂點被當做小區域。在如下所示的圖例中,原始的劃分用實線來表示,而對偶劃分用點線來表示。
OpenCV 使用Delaunay's 算法將平面分割成小的三角形區域。分割的實現通過從一個假定的三角形(該三角形確保包括所有的分割點)開始不斷迭代來完成。在這種情況下,對偶劃分就是輸入的2d點集的 Voronoi圖表。這種劃分可以用於對一個平面的3d分段變換、形態變換、平面點的快速定位以及建立特定的圖結構 (比如 NNG,RNG等等)。
[ 編輯]
CvQuadEdge2D
平面劃分中的Quad-edge(四方邊緣結構)
/* quad-edge中的一條邊緣,低兩位表示該邊緣的索引號,其它高位表示邊緣指針。 */
typedef long CvSubdiv2DEdge;
/* 四方邊緣的結構場 */
#define CV_QUADEDGE2D_FIELDS() \
int flags; \
struct CvSubdiv2DPoint* pt[4]; \
CvSubdiv2DEdge next[4];
typedef struct CvQuadEdge2D
{
CV_QUADEDGE2D_FIELDS()
}
CvQuadEdge2D;
Quad-edge(譯者注:以下稱之為四方邊緣結構)是平面劃分的基元,其中包括四個邊緣 (e, eRot(紅色) 以及它們的逆(綠色))。
[ 編輯]
CvSubdiv2DPoint
原始和對偶劃分點
#define CV_SUBDIV2D_POINT_FIELDS()\
int flags; \
CvSubdiv2DEdge first; \
CvPoint2D32f pt;
#define CV_SUBDIV2D_VIRTUAL_POINT_FLAG (1 << 30)
typedef struct CvSubdiv2DPoint
{
CV_SUBDIV2D_POINT_FIELDS()
}
CvSubdiv2DPoint;
[ 編輯]
Subdiv2DGetEdge
返回給定的邊緣之一
CvSubdiv2DEdge cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type );
#define cvSubdiv2DNextEdge( edge ) cvSubdiv2DGetEdge( edge, CV_NEXT_AROUND_ORG )
edge劃分的邊緣 (並不是四方邊緣結構)type確定函數返回哪條相關邊緣,是下面幾種之一:
- CV_NEXT_AROUND_ORG - 邊緣原點的下一條 (eOnext on the picture above if e is the input edge)
- CV_NEXT_AROUND_DST - 邊緣頂點的下一條 (eDnext)
- CV_PREV_AROUND_ORG - 邊緣原點的前一條 (reversed eRnext)
- CV_PREV_AROUND_DST - 邊緣終點的前一條 (reversed eLnext)
- CV_NEXT_AROUND_LEFT - 左區域的下一條 (eLnext)
- CV_NEXT_AROUND_RIGHT - 右區域的下一條(eRnext)
- CV_PREV_AROUND_LEFT - 左區域的前一條 (reversed eOnext)
- CV_PREV_AROUND_RIGHT - 右區域的前一條 (reversed eDnext)
函數 cvSubdiv2DGetEdge 返回與輸入邊緣相關的邊緣
[ 編輯]
Subdiv2DRotateEdge
返回同一個四方邊緣結構中的另一條邊緣
CvSubdiv2DEdge cvSubdiv2DRotateEdge( CvSubdiv2DEdge edge, int rotate );
edge劃分的邊緣 (並不是四方邊緣結構)type確定函數根據輸入的邊緣返回同一四方邊緣結構中的哪條邊緣,是下面幾種之一:
- 0 - 輸入邊緣 (上圖中的e,如果e是輸入邊緣)
- 1 - 旋轉邊緣 (eRot)
- 2 -逆邊緣 ( e的反向邊緣)
- 3 - 旋轉邊緣的反向邊緣(eRot的反向邊緣, 圖中綠色)
函數 cvSubdiv2DRotateEdge 根據輸入的邊緣返回四方邊緣結構中的一條邊緣
[ 編輯]
Subdiv2DEdgeOrg
返回邊緣的原點
CvSubdiv2DPoint* cvSubdiv2DEdgeOrg( CvSubdiv2DEdge edge );
edge劃分的邊緣 (並不是四方邊緣結構)
函數 cvSubdiv2DEdgeOrg 返回邊緣的原點。如果該邊緣是從對偶劃分得到並且虛點座標還沒有計算出來,可能返回空指針。虛點可以用函數來cvCalcSubdivVoronoi2D計算。
[ 編輯]
Subdiv2DEdgeDst
Returns edge destination
CvSubdiv2DPoint* cvSubdiv2DEdgeDst( CvSubdiv2DEdge edge );
edge劃分的邊緣 (並不是四方邊緣結構)
函數 cvSubdiv2DEdgeDst 返回邊緣的終點。如果該邊緣是從對偶劃分得到並且虛點座標還沒有計算出來,可能返回空指針。虛點可以用函數來cvCalcSubdivVoronoi2D計算。
[ 編輯]
CreateSubdivDelaunay2D
生成的空Delaunay 三角測量
CvSubdiv2D* cvCreateSubdivDelaunay2D( CvRect rect, CvMemStorage* storage );
rectRectangle包括所有待加入劃分操作的2d點的四方形。storage劃分操作的存儲器
函數 cvCreateSubdivDelaunay2D 生成一個空的Delaunay 劃分, 其中2d points可以進一步使用函數 cvSubdivDelaunay2DInsert來添加。所有的點一定要在指定的四方形中添加,否則就會報運行錯誤。
[ 編輯]
SubdivDelaunay2DInsert
向 Delaunay三角測量中插入一個點
CvSubdiv2DPoint* cvSubdivDelaunay2DInsert( CvSubdiv2D* subdiv, CvPoint2D32f pt);
subdiv通過函數 cvCreateSubdivDelaunay2D.生成的Delaunay劃分pt待插入的點
函數 cvSubdivDelaunay2DInsert 向劃分的結構中插入一個點並且正確地改變劃分的拓樸結構。如果劃分結構中已經存在一個相同的座標點,則不會有新點插入。該函數返回指向已插入點的指針。在這個截斷,不計算任何虛點座標。
[ 編輯]
Subdiv2DLocate
在 Delaunay三角測量中定位輸入點
CvSubdiv2DPointLocation cvSubdiv2DLocate( CvSubdiv2D* subdiv, CvPoint2D32f pt,
CvSubdiv2DEdge* edge,
CvSubdiv2DPoint** vertex=NULL );
subdivDelaunay 或者是其它分割結構.pt待定位的輸入點edge與輸入點對應的輸入邊緣(點在其上或者其右)vertex與輸入點對應的輸出頂點座標(指向double類型),可選。
函數 cvSubdiv2DLocate 在劃分中定位輸入點,共有5種類型:
- 輸入點落入某小區域內。 函數返回參數 CV_PTLOC_INSIDE 且*edge 中包含小區域的邊緣之一。
- 輸入點落p在邊緣之上。 函數返回參數 CV_PTLOC_ON_EDGE 且 *edge 包含此邊緣。
- 輸入點與劃分的頂點之一相對應。 函數返回參數 CV_PTLOC_VERTEX 且 *vertex 中包括指向該頂點的指針;
- 輸入點落在劃分的參考區域之外。 函數返回參數 CV_PTLOC_OUTSIDE_RECT且不填寫任何指針。
- 輸入參數之一有誤。函數報運行錯誤(如果已經選則了沉默或者父母出錯模式,則函數返回CV_PTLOC_ERROR) 。
[ 編輯]
FindNearestPoint2D
根據輸入點,找到其最近的劃分頂點
CvSubdiv2DPoint* cvFindNearestPoint2D( CvSubdiv2D* subdiv, CvPoint2D32f pt );
subdivDelaunay或者其它劃分方式pt輸入點
函數 cvFindNearestPoint2D 是另一個定位輸入點的函數。該函數找到輸入點的最近劃分頂點。儘管劃分出的小區域(facet)被用來作為起始點,但是輸入點不一定非得在最終找到的頂點所在的小區域之內。該函數返回指向找到的劃分頂點的指針。
[ 編輯]
CalcSubdivVoronoi2D
計算Voronoi圖表的細胞結構
void cvCalcSubdivVoronoi2D( CvSubdiv2D* subdiv );
subdivDelaunay 劃分,其中所有的點已經添加 。
函數 cvCalcSubdivVoronoi2D 計算虛點的座標,所有與原劃分中的某頂點相對應的虛點形成了(當他們相互連接時)該頂點的Voronoi 細胞的邊界。
[ 編輯]
ClearSubdivVoronoi2D
移除所有的虛點
void cvClearSubdivVoronoi2D( CvSubdiv2D* subdiv );
subdivDelaunay 劃分
函數 cvClearSubdivVoronoi2D 移除所有的虛點。當劃分的結果被函數cvCalcSubdivVoronoi2D的前一次調用更改時,該函數被cvCalcSubdivVoronoi2D內部調用 。
還有一些其它的底層處理函數與平面劃分操作協同工作,參見 cv.h 及源碼。生成 delaunay.c 三角測量以及2d隨機點集的Voronoi 圖表的演示代碼可以在 opencv/samples/c目錄下的delaunay.c 文件中找到。