1
0
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:
take1014
2018-02-09 04:54:43 +09:00
committed by Alexander Alekhin
parent d56b2b56fb
commit 03407a9da0
4 changed files with 235 additions and 20 deletions
+103 -20
View File
@@ -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