Commit ad765a75 authored by Jesus Briales's avatar Jesus Briales

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)
parent 67ceb42d
...@@ -72,32 +72,32 @@ void LSDDetector::computeGaussianPyramid( const Mat& image, int numOctaves, int ...@@ -72,32 +72,32 @@ void LSDDetector::computeGaussianPyramid( const Mat& image, int numOctaves, int
} }
/* check lines' extremes */ /* check lines' extremes */
inline void checkLineExtremes( cv::Vec4i& extremes, cv::Size imageSize ) inline void checkLineExtremes( cv::Vec4f& extremes, cv::Size imageSize )
{ {
if( extremes[0] < 0 ) if( extremes[0] < 0 )
extremes[0] = 0; extremes[0] = 0;
if( extremes[0] >= imageSize.width ) if( extremes[0] >= imageSize.width )
extremes[0] = imageSize.width - 1; extremes[0] = (float)imageSize.width - 1.0f;
if( extremes[2] < 0 ) if( extremes[2] < 0 )
extremes[2] = 0; extremes[2] = 0;
if( extremes[2] >= imageSize.width ) if( extremes[2] >= imageSize.width )
extremes[2] = imageSize.width - 1; extremes[2] = (float)imageSize.width - 1.0f;
if( extremes[1] < 0 ) if( extremes[1] < 0 )
extremes[1] = 0; extremes[1] = 0;
if( extremes[1] >= imageSize.height ) if( extremes[1] >= imageSize.height )
extremes[1] = imageSize.height - 1; extremes[1] = (float)imageSize.height - 1.0f;
if( extremes[3] < 0 ) if( extremes[3] < 0 )
extremes[3] = 0; extremes[3] = 0;
if( extremes[3] >= imageSize.height ) if( extremes[3] >= imageSize.height )
extremes[3] = imageSize.height - 1; extremes[3] = (float)imageSize.height - 1.0f;
} }
/* requires line detection (only one image) */ /* requires line detection (only one image) */
...@@ -148,48 +148,49 @@ void LSDDetector::detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keyline ...@@ -148,48 +148,49 @@ void LSDDetector::detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keyline
cv::Ptr<cv::LineSegmentDetector> ls = cv::createLineSegmentDetector( cv::LSD_REFINE_ADV ); cv::Ptr<cv::LineSegmentDetector> ls = cv::createLineSegmentDetector( cv::LSD_REFINE_ADV );
/* prepare a vector to host extracted segments */ /* prepare a vector to host extracted segments */
std::vector<std::vector<cv::Vec4i> > lines_lsd; std::vector<std::vector<cv::Vec4f> > lines_lsd;
/* extract lines */ /* extract lines */
for ( int i = 0; i < numOctaves; i++ ) for ( int i = 0; i < numOctaves; i++ )
{ {
std::vector<Vec4i> octave_lines; std::vector<Vec4f> octave_lines;
ls->detect( gaussianPyrs[i], octave_lines ); ls->detect( gaussianPyrs[i], octave_lines );
lines_lsd.push_back( octave_lines ); lines_lsd.push_back( octave_lines );
} }
/* create keylines */ /* create keylines */
int class_counter = -1; int class_counter = -1;
for ( int j = 0; j < (int) lines_lsd.size(); j++ ) for ( int octaveIdx = 0; octaveIdx < (int) lines_lsd.size(); octaveIdx++ )
{ {
for ( int k = 0; k < (int) lines_lsd[j].size(); k++ ) float octaveScale = pow( (float)scale, octaveIdx );
for ( int k = 0; k < (int) lines_lsd[octaveIdx].size(); k++ )
{ {
KeyLine kl; KeyLine kl;
cv::Vec4i extremes = lines_lsd[j][k]; cv::Vec4f extremes = lines_lsd[octaveIdx][k];
/* check data validity */ /* check data validity */
checkLineExtremes( extremes, gaussianPyrs[j].size() ); checkLineExtremes( extremes, gaussianPyrs[octaveIdx].size() );
/* fill KeyLine's fields */ /* fill KeyLine's fields */
kl.startPointX = (float) extremes[0]; kl.startPointX = extremes[0] * octaveScale;
kl.startPointY = (float) extremes[1]; kl.startPointY = extremes[1] * octaveScale;
kl.endPointX = (float) extremes[2]; kl.endPointX = extremes[2] * octaveScale;
kl.endPointY = (float) extremes[3]; kl.endPointY = extremes[3] * octaveScale;
kl.sPointInOctaveX = (float) extremes[0]; kl.sPointInOctaveX = extremes[0];
kl.sPointInOctaveY = (float) extremes[1]; kl.sPointInOctaveY = extremes[1];
kl.ePointInOctaveX = (float) extremes[2]; kl.ePointInOctaveX = extremes[2];
kl.ePointInOctaveY = (float) extremes[3]; kl.ePointInOctaveY = extremes[3];
kl.lineLength = (float) sqrt( pow( (float) extremes[0] - extremes[2], 2 ) + pow( (float) extremes[1] - extremes[3], 2 ) ); kl.lineLength = (float) sqrt( pow( extremes[0] - extremes[2], 2 ) + pow( extremes[1] - extremes[3], 2 ) );
/* compute number of pixels covered by line */ /* compute number of pixels covered by line */
LineIterator li( gaussianPyrs[j], Point( extremes[0], extremes[1] ), Point( extremes[2], extremes[3] ) ); LineIterator li( gaussianPyrs[octaveIdx], Point2f( extremes[0], extremes[1] ), Point2f( extremes[2], extremes[3] ) );
kl.numOfPixels = li.count; kl.numOfPixels = li.count;
kl.angle = atan2( ( kl.endPointY - kl.startPointY ), ( kl.endPointX - kl.startPointX ) ); kl.angle = atan2( ( kl.endPointY - kl.startPointY ), ( kl.endPointX - kl.startPointX ) );
kl.class_id = ++class_counter; kl.class_id = ++class_counter;
kl.octave = j; kl.octave = octaveIdx;
kl.size = ( kl.endPointX - kl.startPointX ) * ( kl.endPointY - kl.startPointY ); kl.size = ( kl.endPointX - kl.startPointX ) * ( kl.endPointY - kl.startPointY );
kl.response = kl.lineLength / max( gaussianPyrs[j].cols, gaussianPyrs[j].rows ); kl.response = kl.lineLength / max( gaussianPyrs[octaveIdx].cols, gaussianPyrs[octaveIdx].rows );
kl.pt = Point2f( ( kl.endPointX + kl.startPointX ) / 2, ( kl.endPointY + kl.startPointY ) / 2 ); kl.pt = Point2f( ( kl.endPointX + kl.startPointX ) / 2, ( kl.endPointY + kl.startPointY ) / 2 );
keylines.push_back( kl ); keylines.push_back( kl );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment