@@ -68,6 +68,32 @@ struct hough_cmp_gt
68
68
const int * aux;
69
69
};
70
70
71
+ static void
72
+ createTrigTable ( int numangle, double min_theta, double theta_step,
73
+ float irho, float *tabSin, float *tabCos )
74
+ {
75
+ float ang = static_cast <float >(min_theta);
76
+ for (int n = 0 ; n < numangle; ang += (float )theta_step, n++ )
77
+ {
78
+ tabSin[n] = (float )(sin ((double )ang) * irho);
79
+ tabCos[n] = (float )(cos ((double )ang) * irho);
80
+ }
81
+ }
82
+
83
+ static void
84
+ findLocalMaximums ( int numrho, int numangle, int threshold,
85
+ const int *accum, std::vector<int >& sort_buf )
86
+ {
87
+ for (int r = 0 ; r < numrho; r++ )
88
+ for (int n = 0 ; n < numangle; n++ )
89
+ {
90
+ int base = (n+1 ) * (numrho+2 ) + r+1 ;
91
+ if ( accum[base] > threshold &&
92
+ accum[base] > accum[base - 1 ] && accum[base] >= accum[base + 1 ] &&
93
+ accum[base] > accum[base - numrho - 2 ] && accum[base] >= accum[base + numrho + 2 ] )
94
+ sort_buf.push_back (base);
95
+ }
96
+ }
71
97
72
98
/*
73
99
Here image is an input raster;
@@ -125,21 +151,17 @@ HoughLinesStandard( const Mat& img, float rho, float theta,
125
151
}
126
152
#endif
127
153
128
- AutoBuffer<int > _accum ((numangle+2 ) * (numrho+2 ));
154
+
155
+ Mat _accum = Mat::zeros ( (numangle+2 ), (numrho+2 ), CV_32SC1 );
129
156
std::vector<int > _sort_buf;
130
157
AutoBuffer<float > _tabSin (numangle);
131
158
AutoBuffer<float > _tabCos (numangle);
132
- int *accum = _accum;
159
+ int *accum = _accum. ptr < int >() ;
133
160
float *tabSin = _tabSin, *tabCos = _tabCos;
134
161
135
- memset ( accum, 0 , sizeof (accum[0 ]) * (numangle+2 ) * (numrho+2 ) );
136
-
137
- float ang = static_cast <float >(min_theta);
138
- for (int n = 0 ; n < numangle; ang += theta, n++ )
139
- {
140
- tabSin[n] = (float )(sin ((double )ang) * irho);
141
- tabCos[n] = (float )(cos ((double )ang) * irho);
142
- }
162
+ // create sin and cos table
163
+ createTrigTable ( numangle, min_theta, theta,
164
+ irho, tabSin, tabCos );
143
165
144
166
// stage 1. fill accumulator
145
167
for ( i = 0 ; i < height; i++ )
@@ -155,15 +177,7 @@ HoughLinesStandard( const Mat& img, float rho, float theta,
155
177
}
156
178
157
179
// stage 2. find local maximums
158
- for (int r = 0 ; r < numrho; r++ )
159
- for (int n = 0 ; n < numangle; n++ )
160
- {
161
- int base = (n+1 ) * (numrho+2 ) + r+1 ;
162
- if ( accum[base] > threshold &&
163
- accum[base] > accum[base - 1 ] && accum[base] >= accum[base + 1 ] &&
164
- accum[base] > accum[base - numrho - 2 ] && accum[base] >= accum[base + numrho + 2 ] )
165
- _sort_buf.push_back (base);
166
- }
180
+ findLocalMaximums ( numrho, numangle, threshold, accum, _sort_buf );
167
181
168
182
// stage 3. sort the detected lines by accumulator value
169
183
std::sort (_sort_buf.begin (), _sort_buf.end (), hough_cmp_gt (accum));
@@ -883,6 +897,76 @@ void HoughLinesP(InputArray _image, OutputArray _lines,
883
897
Mat (lines).copyTo (_lines);
884
898
}
885
899
900
+ void HoughLinesPointSet ( InputArray _point, OutputArray _lines, int lines_max, int threshold,
901
+ double min_rho, double max_rho, double rho_step,
902
+ double min_theta, double max_theta, double theta_step )
903
+ {
904
+ std::vector<Vec3d> lines;
905
+ std::vector<Point2f> point;
906
+ _point.copyTo (point);
907
+
908
+ CV_Assert ( _point.type () == CV_32FC2 || _point.type () == CV_32SC2 );
909
+ if ( lines_max <= 0 ) {
910
+ CV_Error ( Error::StsBadArg, " lines_max must be greater than 0" );
911
+ }
912
+ if ( threshold < 0 ) {
913
+ CV_Error ( Error::StsBadArg, " threshold must be greater than 0" );
914
+ }
915
+ if ( ((max_rho - min_rho) <= 0 ) || ((max_theta - min_theta) <= 0 ) ) {
916
+ CV_Error ( Error::StsBadArg, " max must be greater than min" );
917
+ }
918
+ if ( ((rho_step <= 0 )) || ((theta_step <= 0 )) ) {
919
+ CV_Error ( Error::StsBadArg, " step must be greater than 0" );
920
+ }
921
+
922
+ int i;
923
+ float irho = 1 / (float )rho_step;
924
+ float irho_min = ((float )min_rho * irho);
925
+ int numangle = cvRound ((max_theta - min_theta) / theta_step);
926
+ int numrho = cvRound ((max_rho - min_rho + 1 ) / rho_step);
927
+
928
+ Mat _accum = Mat::zeros ( (numangle+2 ), (numrho+2 ), CV_32SC1 );
929
+ std::vector<int > _sort_buf;
930
+ AutoBuffer<float > _tabSin (numangle);
931
+ AutoBuffer<float > _tabCos (numangle);
932
+ int *accum = _accum.ptr <int >();
933
+ float *tabSin = _tabSin, *tabCos = _tabCos;
934
+
935
+ // create sin and cos table
936
+ createTrigTable ( numangle, min_theta, theta_step,
937
+ irho, tabSin, tabCos );
938
+
939
+ // stage 1. fill accumlator
940
+ for ( i = 0 ; i < (int )point.size (); i++ )
941
+ for (int n = 0 ; n < numangle; n++ )
942
+ {
943
+ int r = cvRound ( point.at (i).x * tabCos[n] + point.at (i).y * tabSin[n] - irho_min);
944
+ accum[(n+1 ) * (numrho+2 ) + r+1 ]++;
945
+ }
946
+
947
+ // stage 2. find local maximums
948
+ findLocalMaximums ( numrho, numangle, threshold, accum, _sort_buf );
949
+
950
+ // stage 3. sort the detected lines by accumulator value
951
+ std::sort (_sort_buf.begin (), _sort_buf.end (), hough_cmp_gt (accum));
952
+
953
+ // stage 4. store the first min(total,linesMax) lines to the output buffer
954
+ lines_max = std::min (lines_max, (int )_sort_buf.size ());
955
+ double scale = 1 ./(numrho+2 );
956
+ for ( i = 0 ; i < lines_max; i++ )
957
+ {
958
+ LinePolar line;
959
+ int idx = _sort_buf[i];
960
+ int n = cvFloor (idx*scale) - 1 ;
961
+ int r = idx - (n+1 )*(numrho+2 ) - 1 ;
962
+ line.rho = static_cast <float >(min_rho) + r * (float )rho_step;
963
+ line.angle = static_cast <float >(min_theta) + n * (float )theta_step;
964
+ lines.push_back (Vec3d ((double )accum[idx], (double )line.rho , (double )line.angle ));
965
+ }
966
+
967
+ Mat (lines).copyTo (_lines);
968
+ }
969
+
886
970
/* ***************************************************************************************\
887
971
* Circle Detection *
888
972
\****************************************************************************************/
@@ -1611,7 +1695,6 @@ void HoughCircles( InputArray _image, OutputArray _circles,
1611
1695
{
1612
1696
HoughCircles (_image, _circles, method, dp, minDist, param1, param2, minRadius, maxRadius, -1 , 3 );
1613
1697
}
1614
-
1615
1698
} // \namespace cv
1616
1699
1617
1700
0 commit comments