mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Merge pull request #10646 from take1014:master
* Add a new interface for hough transform * Fixed warning code * Fix HoughLinesUsingSetOfPoints based on HoughLinesStandard * Delete memset * Rename HoughLinesUsingSetOfPoints and add common function * Fix test error * Change static function name * Change using CV_Assert instead of if-block and add integer test case * I solve the conflict and delete 'std :: tr1' and changed it to use 'tuple' * I deleted std::tr1::get and changed int to use 'get' * Fixed sample code * revert test_main.cpp * Delete sample code in comment and add snippets * Change file name * Delete static function * Fixed build error
This commit is contained in:
committed by
Alexander Alekhin
parent
d56b2b56fb
commit
03407a9da0
+103
-20
@@ -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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user