cvhough.cpp.svn-base
来自「非结构化路识别」· SVN-BASE 代码 · 共 1,035 行 · 第 1/3 页
SVN-BASE
1,035 行
i = ti0;
caccum[i]++;
cmaccum = caccum[i];
ri = ri1;
ti = ti0;
for( ti1 = 1; ti1 < halftn; ti1++ )
{
rv = r * SIN( ti1 );
ri1 = ROUNDR( rv * irho );
i = ri1 * tn + ti1 + ti0;
caccum[i]++;
if( cmaccum < caccum[i] )
{
cmaccum = caccum[i];
ri = ri1;
ti = ti1 + ti0;
}
}
r = ri * rho + rho / 2;
t = ti * theta + theta / 2;
if( caccum[ri * tn + ti] < threshold )
{
continue;
}
/* Unvote all the pixels from the detected line */
caccum[ri * tn + ti] = 0;
}
/* Find a longest segment representing the line */
/* Use an algorithm like Bresenheim one */
ml = 0;
for( i = 0; i < 7; i++ )
{
switch (i)
{
case 0:
break;
case 1:
r = ri * rho;
t = ti * theta - halfPi + 0.1f * theta;
break;
case 2:
r = ri * rho;
t = (ti + 1) * theta - halfPi - 0.1f * theta;
break;
case 3:
r = (ri + 1) * rho - 0.1f * rho;
t = ti * theta - halfPi + 0.1f * theta;
break;
case 4:
r = (ri + 1) * rho - 0.1f * rho;
t = (ti + 1) * theta - halfPi - 0.1f * theta;
break;
case 5:
r = ri * rho + 0.1f * rho;
t = ti * theta - halfPi + 0.5f * theta;
break;
case 6:
r = (ri + 1) * rho - 0.1f * rho;
t = ti * theta - halfPi + 0.5f * theta;
break;
}
if( t > Pi )
{
t = t - 2 * Pi;
}
if( t >= 0 )
{
if( t <= Pi / 2 )
{
dx = -(float) sin( t );
dy = (float) cos( t );
if( r < (w - 1) * fabs( dy ))
{
ax = (float) cvFloor( r / dy ) + 0.5f;
ay = 0.5f;
}
else
{
ax = (float) w - 0.5f;
ay = (float) cvFloor( (r - (w - 1) * dy) / (float) fabs( dx )) + 0.5f;
}
}
else
{
/* Pi/2 < t < Pi */
dx = (float) sin( t );
dy = -(float) cos( t );
ax = 0.5f;
ay = (float) cvFloor( r / dx ) + 0.5f;
}
}
else
{
/* -Pi/2 < t < 0 */
dx = -(float) sin( t );
dy = (float) cos( t );
ax = (float) cvFloor( r / dy ) + 0.5f;
ay = 0.5f;
}
cl = 0;
cg = 0;
ox = cvFloor( ax );
oy = cvFloor( ay );
while( ox >= 0 && ox < w && oy >= 0 && oy < h )
{
if( _POINT( oy, ox ))
{
if( cl == 0 )
{
/* A line has started */
curx = ax;
cury = ay;
}
cl++;
cg = 0; /* No gaps so far */
}
else if( cl )
{
if( ++cg > lineGap )
{
/* This is not a gap, the line has finished */
/* Let us remember it's parameters */
if( ml < cl )
{
msx = curx;
msy = cury;
mex = ax;
mey = ay;
mdx = dx;
mdy = dy;
ml = cl;
}
cl = 0;
cg = 0;
}
}
ax += dx;
ay += dy;
ox = cvFloor( ax );
oy = cvFloor( ay );
}
/* The last line if there was any... */
if( ml < cl )
{
msx = curx;
msy = cury;
mex = ax;
mey = ay;
mdx = dx;
mdy = dy;
ml = cl;
}
}
if( ml == 0 )
{
// no line...
continue;
}
/* Now let's remove all the pixels in the segment from the input image */
cl = 0;
cg = 0;
ax = msx;
ay = msy;
ox = cvFloor( msx );
oy = cvFloor( msy );
while( (ox != cvFloor( mex ) || oy != cvFloor( mey )) && fn > 0 )
{
image_src[oy * step + ox] = 0;
index0 = map[oy * w + ox];
if( index0 != -1 )
{
if( index0 != fn - 1 )
{
/* Exchange the point with the last one */
_EXCHANGE( x[index0], x[fn - 1] );
_EXCHANGE( y[index0], y[fn - 1] );
_EXCHANGE( map[y[index0] * w + x[index0]],
map[y[fn - 1] * w + x[fn - 1]] );
}
fn--;
}
ax += mdx;
ay += mdy;
ox = cvFloor( ax );
oy = cvFloor( ay );
}
if( ml >= lineLength )
{
CvRect line;
line.x = cvFloor( msx );
line.y = cvFloor( msy );
line.width = cvFloor( mex );
line.height = cvFloor( mey );
cvSeqPush( lines, &line );
if( lines->total >= linesMax || fn == 0 )
goto func_exit;
}
}
func_exit:
icvFree( &x );
icvFree( &y );
icvFree( &map );
icvFree( &sinTable );
icvFree( &iaccum );
icvFree( &caccum );
return CV_OK;
}
/* Wrapper function for standard hough transform */
CV_IMPL CvSeq*
cvHoughLines2( CvArr* src_image, void* lineStorage, int method,
double rho, double theta, int threshold,
double param1, double param2 )
{
CvSeq* result = 0;
CV_FUNCNAME( "cvHoughLines" );
__BEGIN__;
CvMat stub, *img = (CvMat*)src_image;
CvMat* mat = 0;
CvSeq* lines = 0;
CvSeq lines_header;
CvSeqBlock lines_block;
int lineType, elemSize;
int linesMax = INT_MAX;
CV_CALL( img = cvGetMat( img, &stub ));
if( !CV_IS_MASK_ARR(img))
CV_ERROR( CV_StsBadArg, "The source image must be 8-bit, single-channel" );
if( !lineStorage )
CV_ERROR( CV_StsNullPtr, "NULL destination" );
if( rho <= 0 || theta <= 0 || threshold <= 0 )
CV_ERROR( CV_StsOutOfRange, "rho, theta and threshold must be positive" );
if( method != CV_HOUGH_PROBABILISTIC )
{
lineType = CV_32FC2;
elemSize = sizeof(float)*2;
}
else
{
lineType = CV_32SC4;
elemSize = sizeof(int)*4;
}
if( CV_IS_STORAGE( lineStorage ))
{
CV_CALL( lines = cvCreateSeq( lineType, sizeof(CvSeq), elemSize, (CvMemStorage*)lineStorage ));
}
else if( CV_IS_MAT( lineStorage ))
{
mat = (CvMat*)lineStorage;
if( !CV_IS_MAT_CONT( mat->type ) || mat->rows != 1 && mat->cols != 1 )
CV_ERROR( CV_StsBadArg,
"The destination matrix should be continuous and have a single row or a single column" );
if( CV_MAT_TYPE( mat->type ) != lineType )
CV_ERROR( CV_StsBadArg,
"The destination matrix data type is inappropriate, see the manual" );
CV_CALL( lines = cvMakeSeqHeaderForArray( lineType, sizeof(CvSeq), elemSize, mat->data.ptr,
mat->rows + mat->cols - 1, &lines_header, &lines_block ));
linesMax = lines->total;
CV_CALL( cvClearSeq( lines ));
}
else
{
CV_ERROR( CV_StsBadArg, "Destination is not CvMemStorage* nor CvMat*" );
}
switch( method )
{
case CV_HOUGH_STANDARD:
IPPI_CALL( icvHoughLines_8uC1R( img->data.ptr, img->step, icvGetMatSize(img),
(float)rho, (float)theta, threshold, lines, linesMax ));
break;
case CV_HOUGH_MULTI_SCALE:
IPPI_CALL( icvHoughLinesSDiv_8uC1R( img->data.ptr, img->step, icvGetMatSize(img),
(float)rho, (float)theta, threshold,
cvRound(param1), cvRound(param2), lines, linesMax ));
break;
case CV_HOUGH_PROBABILISTIC:
IPPI_CALL( icvHoughLinesP_8uC1R( img->data.ptr, img->step, icvGetMatSize(img),
(float)rho, (float)theta, threshold,
cvRound(param1), cvRound(param2), lines, linesMax ));
break;
default:
CV_ERROR( CV_StsBadArg, "Unrecognized method id" );
}
if( mat )
{
if( mat->cols > mat->rows )
mat->cols = lines->total;
else
mat->rows = lines->total;
}
else
{
result = lines;
}
__END__;
return result;
}
/* End of file. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?