是否有一个简单快速的OpenCV解决方案将一组定义多边形的CvPoint顶点转换为具有更多顶点的轮廓?
我在一个空间中有简单的多边形,我想将多边形转换为另一个空间,直线会弯曲。因此,重要的是我在直线上添加了更多顶点。这与cvApproxPoly()
相反。
内部cvPolyLine()
正在做我想要的事情。有没有办法访问?
我正在使用OpenCV 1.1。
答案 0 :(得分: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