Skip to content

Commit ad765a7

Browse files
committed
Fix subpixel precision issue and compute line points in original image size
Issue 1: The subpixel precision of LSD was lost in the implicit conversion to Vec4i Solved: Line point coordinates are stored in cv::Vec4f No type conversion needed from extremes to kl float fields Issue 2: The keyline point fields for original image were not being correctly filled Solved: The points in original image are computed through scaling (using scale factor and octave index)
1 parent 67ceb42 commit ad765a7

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

modules/line_descriptor/src/LSDDetector.cpp

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -72,32 +72,32 @@ void LSDDetector::computeGaussianPyramid( const Mat& image, int numOctaves, int
7272
}
7373

7474
/* check lines' extremes */
75-
inline void checkLineExtremes( cv::Vec4i& extremes, cv::Size imageSize )
75+
inline void checkLineExtremes( cv::Vec4f& extremes, cv::Size imageSize )
7676
{
7777

7878
if( extremes[0] < 0 )
7979
extremes[0] = 0;
8080

8181
if( extremes[0] >= imageSize.width )
82-
extremes[0] = imageSize.width - 1;
82+
extremes[0] = (float)imageSize.width - 1.0f;
8383

8484
if( extremes[2] < 0 )
8585
extremes[2] = 0;
8686

8787
if( extremes[2] >= imageSize.width )
88-
extremes[2] = imageSize.width - 1;
88+
extremes[2] = (float)imageSize.width - 1.0f;
8989

9090
if( extremes[1] < 0 )
9191
extremes[1] = 0;
9292

9393
if( extremes[1] >= imageSize.height )
94-
extremes[1] = imageSize.height - 1;
94+
extremes[1] = (float)imageSize.height - 1.0f;
9595

9696
if( extremes[3] < 0 )
9797
extremes[3] = 0;
9898

9999
if( extremes[3] >= imageSize.height )
100-
extremes[3] = imageSize.height - 1;
100+
extremes[3] = (float)imageSize.height - 1.0f;
101101
}
102102

103103
/* requires line detection (only one image) */
@@ -148,48 +148,49 @@ void LSDDetector::detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keyline
148148
cv::Ptr<cv::LineSegmentDetector> ls = cv::createLineSegmentDetector( cv::LSD_REFINE_ADV );
149149

150150
/* prepare a vector to host extracted segments */
151-
std::vector<std::vector<cv::Vec4i> > lines_lsd;
151+
std::vector<std::vector<cv::Vec4f> > lines_lsd;
152152

153153
/* extract lines */
154154
for ( int i = 0; i < numOctaves; i++ )
155155
{
156-
std::vector<Vec4i> octave_lines;
156+
std::vector<Vec4f> octave_lines;
157157
ls->detect( gaussianPyrs[i], octave_lines );
158158
lines_lsd.push_back( octave_lines );
159159
}
160160

161161
/* create keylines */
162162
int class_counter = -1;
163-
for ( int j = 0; j < (int) lines_lsd.size(); j++ )
163+
for ( int octaveIdx = 0; octaveIdx < (int) lines_lsd.size(); octaveIdx++ )
164164
{
165-
for ( int k = 0; k < (int) lines_lsd[j].size(); k++ )
165+
float octaveScale = pow( (float)scale, octaveIdx );
166+
for ( int k = 0; k < (int) lines_lsd[octaveIdx].size(); k++ )
166167
{
167168
KeyLine kl;
168-
cv::Vec4i extremes = lines_lsd[j][k];
169+
cv::Vec4f extremes = lines_lsd[octaveIdx][k];
169170

170171
/* check data validity */
171-
checkLineExtremes( extremes, gaussianPyrs[j].size() );
172+
checkLineExtremes( extremes, gaussianPyrs[octaveIdx].size() );
172173

173174
/* fill KeyLine's fields */
174-
kl.startPointX = (float) extremes[0];
175-
kl.startPointY = (float) extremes[1];
176-
kl.endPointX = (float) extremes[2];
177-
kl.endPointY = (float) extremes[3];
178-
kl.sPointInOctaveX = (float) extremes[0];
179-
kl.sPointInOctaveY = (float) extremes[1];
180-
kl.ePointInOctaveX = (float) extremes[2];
181-
kl.ePointInOctaveY = (float) extremes[3];
182-
kl.lineLength = (float) sqrt( pow( (float) extremes[0] - extremes[2], 2 ) + pow( (float) extremes[1] - extremes[3], 2 ) );
175+
kl.startPointX = extremes[0] * octaveScale;
176+
kl.startPointY = extremes[1] * octaveScale;
177+
kl.endPointX = extremes[2] * octaveScale;
178+
kl.endPointY = extremes[3] * octaveScale;
179+
kl.sPointInOctaveX = extremes[0];
180+
kl.sPointInOctaveY = extremes[1];
181+
kl.ePointInOctaveX = extremes[2];
182+
kl.ePointInOctaveY = extremes[3];
183+
kl.lineLength = (float) sqrt( pow( extremes[0] - extremes[2], 2 ) + pow( extremes[1] - extremes[3], 2 ) );
183184

184185
/* compute number of pixels covered by line */
185-
LineIterator li( gaussianPyrs[j], Point( extremes[0], extremes[1] ), Point( extremes[2], extremes[3] ) );
186+
LineIterator li( gaussianPyrs[octaveIdx], Point2f( extremes[0], extremes[1] ), Point2f( extremes[2], extremes[3] ) );
186187
kl.numOfPixels = li.count;
187188

188189
kl.angle = atan2( ( kl.endPointY - kl.startPointY ), ( kl.endPointX - kl.startPointX ) );
189190
kl.class_id = ++class_counter;
190-
kl.octave = j;
191+
kl.octave = octaveIdx;
191192
kl.size = ( kl.endPointX - kl.startPointX ) * ( kl.endPointY - kl.startPointY );
192-
kl.response = kl.lineLength / max( gaussianPyrs[j].cols, gaussianPyrs[j].rows );
193+
kl.response = kl.lineLength / max( gaussianPyrs[octaveIdx].cols, gaussianPyrs[octaveIdx].rows );
193194
kl.pt = Point2f( ( kl.endPointX + kl.startPointX ) / 2, ( kl.endPointY + kl.startPointY ) / 2 );
194195

195196
keylines.push_back( kl );

0 commit comments

Comments
 (0)