2009-12-24 90 views
3

是否有一個簡單快捷的OpenCV解決方案,可將一組定義多邊形的CvPoint頂點轉換爲具有更多頂點的輪廓?OpenCV中的多邊形輪廓?例如cvApproxPoly()的反義詞?

我在一個空間中有簡單的多邊形,我想要將多邊形轉換爲另一個空間,直線將變爲曲線。因此,重要的是我添加更多的頂點到我的直線上。這將與cvApproxPoly()相反。

內部cvPolyLine()正在做我想要的。有什麼方法可以訪問嗎?

我正在使用OpenCV 1.1。

+0

你有沒有發現一種內置的方式來做到這一點,也許與新版本的OpenCV?我想要做同樣的事情。 – KobeJohn

+0

對不起。我沒有檢查過。不過,我確實使用了我經常在下面提交的代碼,我對它的性能感到滿意。 – AndyL

+0

這很好聽。感謝您的問題,解決方案和更新。 – KobeJohn

回答

4

所以我寫了我自己的函數GetLineFromEndPts(),它應該以一種方式解決這個問題。給定兩點a和b,該函數在連接a和b的連線上輸出點列表。因此,爲了從多個頂點定義的多邊形中找到具有許多點的輪廓,我可以在連續的頂點對上運行此函數。

/* 
* Given two points a and b , and a sequence of CvPoints 
* this function will find the points that walk the line 
* between a and b and append those 
* the end of the sequence 
* 
* Note that the output includes point a, but not point b. 
*/ 
int GetLineFromEndPts(CvPoint a, CvPoint b, CvSeq* contour){ 
    if (contour==NULL) { 
     printf("ERROR! contour in GetLineFromEndPts() is NULL!\n"); 
     return -1; 
    } 
    float d=dist(a,b); 
    /** Normalized vector with components i and j pointing along the line**/ 
    float ihat= ((float) (b.x -a.x)) /d; 
    float jhat= ((float) (b.y -a.y)) /d; 

    CvPoint currPt; /* Current Point On integer grid*/ 
    CvPoint prevPt=a; /* Prev Point on integer grid */ 
    currPt=a; 

    /** Prepare Writer for Appending Points to Seq **/ 
    CvSeqWriter writer; 
    cvStartAppendToSeq(contour, &writer); 

    int t; 
    float tempPtx; 
    float tempPty; 
    int signx=1; 
    int signy=1; 

    for (t = 0; t < (int) (d+0.5) ; ++t) { 

     /** Our target point is now defined by a parametric equation **/ 
     tempPtx=(float) t * ihat + (float) a.x; 
     tempPty=(float) t * jhat + (float) a.y; 

     /** We will want to round and we need to know the number's sign to round correctly **/ 
     if (tempPtx<0) { 
      signx=-1; 
     } else { 
      signx=1; 
     } 
     if (tempPty<0) { 
      signy=-1; 
     } else{ 
      signy=1; 
     } 


     /** Round to an integer value. Note that we need the sign before we add/subtract .5 **/ 
     currPt=cvPoint((int) (tempPtx + (float) signx * 0.5) , 
        (int) (tempPty + (float) signy * 0.5)); 


     /** If first point, OR the current approx point is not the same as prev **/ 
     if (t==0 || !(currPt.x == prevPt.x && currPt.y == prevPt.y ) ){ 

      /** Write out the point **/ 
      CV_WRITE_SEQ_ELEM(currPt, writer); 

     printf(" t=%d\n",t); 
     printf(" currPt.x=%d\n",currPt.x); 
     printf(" currPt.y=%d\n",currPt.y); 


     } 
     prevPt=currPt; 
    } 
    cvEndWriteSeq(&writer); 
    return 1; 
} 

和相關的功能:

/* 
* Returns the squared distance between two points 
*/ 
int sqDist(CvPoint pta, CvPoint ptb){ 
    return ( ((pta.x - ptb.x)*(pta.x - ptb.x)) + ((pta.y - ptb.y)*(pta.y - ptb.y) )); 
} 

最後:

/* 
* Finds the distance between two points 
* and returns the value as a float 
*/ 
float dist(CvPoint a, CvPoint b){ 
    return (sqrt((float) sqDist(a,b)) ); 
} 

因此,例如,如果調用:

GetLineFromEndPts(cvPoint(0,0),cvPoint(10,15),test); 

函數輸出:

t=0 
currPt.x=0 
currPt.y=0 
t=1 
currPt.x=1 
currPt.y=1 
t=2 
currPt.x=1 
currPt.y=2 
t=3 
currPt.x=2 
currPt.y=2 
t=4 
currPt.x=2 
currPt.y=3 
t=5 
currPt.x=3 
currPt.y=4 
t=6 
currPt.x=3 
currPt.y=5 
t=7 
currPt.x=4 
currPt.y=6 
t=8 
currPt.x=4 
currPt.y=7 
t=9 
currPt.x=5 
currPt.y=7 
t=10 
currPt.x=6 
currPt.y=8 
t=11 
currPt.x=6 
currPt.y=9 
t=12 
currPt.x=7 
currPt.y=10 
t=13 
currPt.x=7 
currPt.y=11 
t=14 
currPt.x=8 
currPt.y=12 
t=16 
currPt.x=9 
currPt.y=13 
t=17 
currPt.x=9 
currPt.y=14