@ -68,6 +68,32 @@ struct hough_cmp_gt
const int * aux ;
} ;
static void
createTrigTable ( int numangle , double min_theta , double theta_step ,
float irho , float * tabSin , float * tabCos )
{
float ang = static_cast < float > ( min_theta ) ;
for ( int n = 0 ; n < numangle ; ang + = ( float ) theta_step , n + + )
{
tabSin [ n ] = ( float ) ( sin ( ( double ) ang ) * irho ) ;
tabCos [ n ] = ( float ) ( cos ( ( double ) ang ) * irho ) ;
}
}
static void
findLocalMaximums ( int numrho , int numangle , int threshold ,
const int * accum , std : : vector < int > & sort_buf )
{
for ( int r = 0 ; r < numrho ; r + + )
for ( int n = 0 ; n < numangle ; n + + )
{
int base = ( n + 1 ) * ( numrho + 2 ) + r + 1 ;
if ( accum [ base ] > threshold & &
accum [ base ] > accum [ base - 1 ] & & accum [ base ] > = accum [ base + 1 ] & &
accum [ base ] > accum [ base - numrho - 2 ] & & accum [ base ] > = accum [ base + numrho + 2 ] )
sort_buf . push_back ( base ) ;
}
}
/*
Here image is an input raster ;
@ -125,21 +151,17 @@ HoughLinesStandard( const Mat& img, float rho, float theta,
}
# endif
AutoBuffer < int > _accum ( ( numangle + 2 ) * ( numrho + 2 ) ) ;
Mat _accum = Mat : : zeros ( ( numangle + 2 ) , ( numrho + 2 ) , CV_32SC1 ) ;
std : : vector < int > _sort_buf ;
AutoBuffer < float > _tabSin ( numangle ) ;
AutoBuffer < float > _tabCos ( numangle ) ;
int * accum = _accum ;
int * accum = _accum . ptr < int > ( ) ;
float * tabSin = _tabSin , * tabCos = _tabCos ;
memset ( accum , 0 , sizeof ( accum [ 0 ] ) * ( numangle + 2 ) * ( numrho + 2 ) ) ;
float ang = static_cast < float > ( min_theta ) ;
for ( int n = 0 ; n < numangle ; ang + = theta , n + + )
{
tabSin [ n ] = ( float ) ( sin ( ( double ) ang ) * irho ) ;
tabCos [ n ] = ( float ) ( cos ( ( double ) ang ) * irho ) ;
}
// create sin and cos table
createTrigTable ( numangle , min_theta , theta ,
irho , tabSin , tabCos ) ;
// stage 1. fill accumulator
for ( i = 0 ; i < height ; i + + )
@ -155,15 +177,7 @@ HoughLinesStandard( const Mat& img, float rho, float theta,
}
// stage 2. find local maximums
for ( int r = 0 ; r < numrho ; r + + )
for ( int n = 0 ; n < numangle ; n + + )
{
int base = ( n + 1 ) * ( numrho + 2 ) + r + 1 ;
if ( accum [ base ] > threshold & &
accum [ base ] > accum [ base - 1 ] & & accum [ base ] > = accum [ base + 1 ] & &
accum [ base ] > accum [ base - numrho - 2 ] & & accum [ base ] > = accum [ base + numrho + 2 ] )
_sort_buf . push_back ( base ) ;
}
findLocalMaximums ( numrho , numangle , threshold , accum , _sort_buf ) ;
// stage 3. sort the detected lines by accumulator value
std : : sort ( _sort_buf . begin ( ) , _sort_buf . end ( ) , hough_cmp_gt ( accum ) ) ;
@ -883,6 +897,76 @@ void HoughLinesP(InputArray _image, OutputArray _lines,
Mat ( lines ) . copyTo ( _lines ) ;
}
void HoughLinesPointSet ( InputArray _point , OutputArray _lines , int lines_max , int threshold ,
double min_rho , double max_rho , double rho_step ,
double min_theta , double max_theta , double theta_step )
{
std : : vector < Vec3d > lines ;
std : : vector < Point2f > point ;
_point . copyTo ( point ) ;
CV_Assert ( _point . type ( ) = = CV_32FC2 | | _point . type ( ) = = CV_32SC2 ) ;
if ( lines_max < = 0 ) {
CV_Error ( Error : : StsBadArg , " lines_max must be greater than 0 " ) ;
}
if ( threshold < 0 ) {
CV_Error ( Error : : StsBadArg , " threshold must be greater than 0 " ) ;
}
if ( ( ( max_rho - min_rho ) < = 0 ) | | ( ( max_theta - min_theta ) < = 0 ) ) {
CV_Error ( Error : : StsBadArg , " max must be greater than min " ) ;
}
if ( ( ( rho_step < = 0 ) ) | | ( ( theta_step < = 0 ) ) ) {
CV_Error ( Error : : StsBadArg , " step must be greater than 0 " ) ;
}
int i ;
float irho = 1 / ( float ) rho_step ;
float irho_min = ( ( float ) min_rho * irho ) ;
int numangle = cvRound ( ( max_theta - min_theta ) / theta_step ) ;
int numrho = cvRound ( ( max_rho - min_rho + 1 ) / rho_step ) ;
Mat _accum = Mat : : zeros ( ( numangle + 2 ) , ( numrho + 2 ) , CV_32SC1 ) ;
std : : vector < int > _sort_buf ;
AutoBuffer < float > _tabSin ( numangle ) ;
AutoBuffer < float > _tabCos ( numangle ) ;
int * accum = _accum . ptr < int > ( ) ;
float * tabSin = _tabSin , * tabCos = _tabCos ;
// create sin and cos table
createTrigTable ( numangle , min_theta , theta_step ,
irho , tabSin , tabCos ) ;
// stage 1. fill accumlator
for ( i = 0 ; i < ( int ) point . size ( ) ; i + + )
for ( int n = 0 ; n < numangle ; n + + )
{
int r = cvRound ( point . at ( i ) . x * tabCos [ n ] + point . at ( i ) . y * tabSin [ n ] - irho_min ) ;
accum [ ( n + 1 ) * ( numrho + 2 ) + r + 1 ] + + ;
}
// stage 2. find local maximums
findLocalMaximums ( numrho , numangle , threshold , accum , _sort_buf ) ;
// stage 3. sort the detected lines by accumulator value
std : : sort ( _sort_buf . begin ( ) , _sort_buf . end ( ) , hough_cmp_gt ( accum ) ) ;
// stage 4. store the first min(total,linesMax) lines to the output buffer
lines_max = std : : min ( lines_max , ( int ) _sort_buf . size ( ) ) ;
double scale = 1. / ( numrho + 2 ) ;
for ( i = 0 ; i < lines_max ; i + + )
{
LinePolar line ;
int idx = _sort_buf [ i ] ;
int n = cvFloor ( idx * scale ) - 1 ;
int r = idx - ( n + 1 ) * ( numrho + 2 ) - 1 ;
line . rho = static_cast < float > ( min_rho ) + r * ( float ) rho_step ;
line . angle = static_cast < float > ( min_theta ) + n * ( float ) theta_step ;
lines . push_back ( Vec3d ( ( double ) accum [ idx ] , ( double ) line . rho , ( double ) line . angle ) ) ;
}
Mat ( lines ) . copyTo ( _lines ) ;
}
/****************************************************************************************\
* Circle Detection *
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@ -1611,7 +1695,6 @@ void HoughCircles( InputArray _image, OutputArray _circles,
{
HoughCircles ( _image , _circles , method , dp , minDist , param1 , param2 , minRadius , maxRadius , - 1 , 3 ) ;
}
} // \namespace cv