New warnings corrected

pull/38/head
biagio montesano 10 years ago
parent b433ac58c5
commit 43f3eb9ffc
  1. 52
      modules/line_descriptor/doc/LSDDetector.rst
  2. 2
      modules/line_descriptor/doc/line_descriptor.rst
  3. BIN
      modules/line_descriptor/doc/pics/lines_cameraman_edl.png
  4. 1
      modules/line_descriptor/include/opencv2/line_descriptor.hpp
  5. 113
      modules/line_descriptor/include/opencv2/line_descriptor/descriptor.hpp
  6. 27
      modules/line_descriptor/samples/compute_descriptors.cpp
  7. 9
      modules/line_descriptor/samples/lines_extraction.cpp
  8. 9
      modules/line_descriptor/samples/radius_matching.cpp
  9. 215
      modules/line_descriptor/src/LSDDetector.cpp
  10. 914
      modules/line_descriptor/src/binary_descriptor.cpp
  11. 4
      modules/line_descriptor/src/binary_descriptor_matcher.cpp
  12. 2579
      modules/line_descriptor/src/ed_line_detector.cpp
  13. 2
      modules/line_descriptor/src/line_descriptor_init.cpp
  14. 2
      modules/line_descriptor/src/precomp.hpp

@ -0,0 +1,52 @@
.. _LSDDetector:
Line Segments Detector
======================
Lines extraction methodology
----------------------------
The lines extraction methodology described in the following is mainly based on [EDL]_.
The extraction starts with a Gaussian pyramid generated from an original image, downsampled N-1 times, blurred N times, to obtain N layers (one for each octave), with layer 0 corresponding to input image. Then, from each layer (octave) in the pyramid, lines are extracted using LSD algorithm.
Differently from EDLine lines extractor used in original article, LSD furnishes information only about lines extremes; thus, additional information regarding slope and equation of line are computed via analytic methods. The number of pixels is obtained using `LineIterator <http://docs.opencv.org/modules/core/doc/drawing_functions.html#lineiterator>`_. Extracted lines are returned in the form of KeyLine objects, but since extraction is based on a method different from the one used in `BinaryDescriptor <binary_descriptor.html>`_ class, data associated to a line's extremes in original image and in octave it was extracted from, coincide. KeyLine's field *class_id* is used as an index to indicate the order of extraction of a line inside a single octave.
LSDDetector::createLSDDetector
------------------------------
Creates ad LSDDetector object, using smart pointers.
.. ocv:function:: Ptr<LSDDetector> LSDDetector::createLSDDetector()
LSDDetector::detect
-------------------
Detect lines inside an image.
.. ocv:function:: void LSDDetector::detect( const Mat& image, std::vector<KeyLine>& keylines, int scale, int numOctaves, const Mat& mask=Mat())
.. ocv:function:: void LSDDetector::detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, int scale, int numOctaves, const std::vector<Mat>& masks=std::vector<Mat>() ) const
:param image: input image
:param images: input images
:param keylines: vector or set of vectors that will store extracted lines for one or more images
:param mask: mask matrix to detect only KeyLines of interest
:param masks: vector of mask matrices to detect only KeyLines of interest from each input image
:param scale: scale factor used in pyramids generation
:param numOctaves: number of octaves inside pyramid
References
----------
.. [EDL] Von Gioi, R. Grompone, et al. *LSD: A fast line segment detector with a false detection control*, IEEE Transactions on Pattern Analysis and Machine Intelligence 32.4 (2010): 722-732.

@ -125,6 +125,8 @@ References
.. [LBD] Zhang, Lilian, and Reinhard Koch. *An efficient and robust line segment matching approach based on LBD descriptor and pairwise geometric consistency*, Journal of Visual Communication and Image Representation 24.7 (2013): 794-805.
.. [EDL] Von Gioi, R. Grompone, et al. *LSD: A fast line segment detector with a false detection control*, IEEE Transactions on Pattern Analysis and Machine Intelligence 32.4 (2010): 722-732.
Summary
-------

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

@ -43,7 +43,6 @@
#define __OPENCV_LINE_DESCRIPTOR_HPP__
#include "opencv2/line_descriptor/descriptor.hpp"
//#include "opencv2/core.hpp"
namespace cv
{

@ -134,15 +134,6 @@ class CV_EXPORTS_W BinaryDescriptor : public Algorithm
};
struct CV_EXPORTS LineDetectionMode
{
enum
{
LSD_DETECTOR = 0, // detect lines using LSD
EDL_DETECTOR = 1 // detect lines using EDLines
};
};
/* constructor */
CV_WRAP
BinaryDescriptor( const BinaryDescriptor::Params &parameters = BinaryDescriptor::Params() );
@ -162,53 +153,48 @@ class CV_EXPORTS_W BinaryDescriptor : public Algorithm
int getReductionRatio();
void setReductionRatio( int rRatio );
/* read parameters from a FileNode object and store them (class function ) */
/* reads parameters from a FileNode object and store them (class function ) */
virtual void read( const cv::FileNode& fn );
/* store parameters to a FileStorage object (class function) */
/* stores parameters to a FileStorage object (class function) */
virtual void write( cv::FileStorage& fs ) const;
/* requires line detection (only one image) */
CV_WRAP
void detect( const Mat& image, CV_OUT std::vector<KeyLine>& keypoints, const Mat& mask = Mat(), int flags = LineDetectionMode::LSD_DETECTOR );
void detect( const Mat& image, CV_OUT std::vector<KeyLine>& keypoints, const Mat& mask = Mat() );
/* requires line detection (more than one image) */
void detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, const std::vector<Mat>& masks = std::vector<Mat>(),
int flags = LineDetectionMode::LSD_DETECTOR ) const;
void detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, const std::vector<Mat>& masks =
std::vector<Mat>() ) const;
/* requires descriptors computation (only one image) */
CV_WRAP
void compute( const Mat& image, CV_OUT CV_IN_OUT std::vector<KeyLine>& keylines, CV_OUT Mat& descriptors, bool returnFloatDescr = false, int flags =
LineDetectionMode::LSD_DETECTOR ) const;
void compute( const Mat& image, CV_OUT CV_IN_OUT std::vector<KeyLine>& keylines, CV_OUT Mat& descriptors, bool returnFloatDescr = false ) const;
/* requires descriptors computation (more than one image) */
void compute( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, std::vector<Mat>& descriptors, bool returnFloatDescr =
false,
int flags = LineDetectionMode::LSD_DETECTOR ) const;
false ) const;
/*return descriptor size */
/* returns descriptor size */
int descriptorSize() const;
/* return data type */
/* returns data type */
int descriptorType() const;
/* return norm mode */
/* returns norm mode */
int defaultNorm() const;
/* check whether Gaussian pyramids were created */
bool empty() const;
/* definition of operator () */
CV_WRAP_AS(detectAndCompute)
virtual void operator()( InputArray image, InputArray mask, CV_OUT std::vector<KeyLine>& keylines, OutputArray descriptors,
bool useProvidedKeyLines = false, bool returnFloatDescr = false, int flags = LineDetectionMode::LSD_DETECTOR ) const;
bool useProvidedKeyLines = false, bool returnFloatDescr = false ) const;
protected:
/* implementation of line detection */
virtual void detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, int flags, const Mat& mask = Mat() ) const;
virtual void detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, const Mat& mask = Mat() ) const;
/* implementation of descriptors' computation */
virtual void computeImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, Mat& descriptors, bool returnFloatDescr, int flags ) const;
virtual void computeImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, Mat& descriptors, bool returnFloatDescr ) const;
/* function inherited from Algorithm */
AlgorithmInfo* info() const;
@ -217,49 +203,24 @@ class CV_EXPORTS_W BinaryDescriptor : public Algorithm
/* conversion of an LBD descriptor to its binary representation */
unsigned char binaryConversion( float* f1, float* f2 );
/* compute LBD descriptors */
int computeLBD( ScaleLines &keyLines, int flags );
/* compute LBD descriptors using EDLine extractor */
int computeLBD_EDL( ScaleLines &keyLines );
int computeLBD( ScaleLines &keyLines );
/* compute Gaussian pyramid of input image */
void computeGaussianPyramid( const Mat& image );
/* gather lines in groups.
Each group contains the same line, detected in different octaves */
int OctaveKeyLines( ScaleLines &keyLines );
/* gather lines in groups using EDLine extractor.
/* gathers lines in groups using EDLine extractor.
Each group contains the same line, detected in different octaves */
int OctaveKeyLines_EDL( cv::Mat& image, ScaleLines &keyLines );
/* get coefficients of line passing by two points (in line_extremes) */
void getLineParameters( cv::Vec4i &line_extremes, cv::Vec3i &lineParams );
/* compute the angle between line and X axis */
float getLineDirection( cv::Vec3i &lineParams );
int OctaveKeyLines( cv::Mat& image, ScaleLines &keyLines );
/* the local gaussian coefficient applied to the orthogonal line direction within each band */
std::vector<float> gaussCoefL_;
/* the global gaussian coefficient applied to each Row within line support region */
/* the global gaussian coefficient applied to each row within line support region */
std::vector<float> gaussCoefG_;
/* vector to store horizontal and vertical derivatives of octave images */
std::vector<cv::Mat> dxImg_vector, dyImg_vector;
/* vectot to store sizes of octave images */
std::vector<cv::Size> images_sizes;
/* structure to store lines extracted from each octave image */
std::vector<std::vector<cv::Vec4i> > extractedLines;
/* descriptor parameters */
Params params;
/* vector to store the Gaussian pyramid od an input image */
std::vector<cv::Mat> octaveImages;
/* vector of sizes of downsampled and blurred images */
std::vector<cv::Size> images_sizes;
/*For each octave of image, we define an EDLineDetector, because we can get gradient images (dxImg, dyImg, gImg)
*from the EDLineDetector class without extra computation cost. Another reason is that, if we use
@ -269,6 +230,42 @@ class CV_EXPORTS_W BinaryDescriptor : public Algorithm
};
class CV_EXPORTS_W LSDDetector : public Algorithm
{
public:
/* constructor */
LSDDetector()
{
}
;
/* constructor with smart pointer */
static Ptr<LSDDetector> createLSDDetector();
/* requires line detection (only one image) */
CV_WRAP
void detect( const Mat& image, CV_OUT std::vector<KeyLine>& keypoints, int scale, int numOctaves, const Mat& mask = Mat() );
/* requires line detection (more than one image) */
void detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, int scale, int numOctaves,
const std::vector<Mat>& masks = std::vector<Mat>() ) const;
private:
/* compute Gaussian pyramid of input image */
void computeGaussianPyramid( const Mat& image, int numOctaves, int scale );
/* implementation of line detection */
void detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, int numOctaves, int scale, const Mat& mask ) const;
/* matrices for Gaussian pyramids */
std::vector<cv::Mat> gaussianPyrs;
protected:
/* function inherited from Algorithm */
AlgorithmInfo* info() const;
};
class CV_EXPORTS_W BinaryDescriptorMatcher : public Algorithm
{

@ -61,20 +61,19 @@ static void help()
<< std::endl;
}
inline void writeMat(cv::Mat m, std::string name, int n)
inline void writeMat( cv::Mat m, std::string name, int n )
{
std::stringstream ss;
std::string s;
ss << n;
ss >> s;
std::string fileNameConf = name + s;
cv::FileStorage fsConf(fileNameConf, cv::FileStorage::WRITE);
fsConf << "m" << m;
fsConf.release();
std::stringstream ss;
std::string s;
ss << n;
ss >> s;
std::string fileNameConf = name + s;
cv::FileStorage fsConf( fileNameConf, cv::FileStorage::WRITE );
fsConf << "m" << m;
fsConf.release();
}
int main( int argc, char** argv )
{
/* get parameters from command line */
@ -102,7 +101,7 @@ int main( int argc, char** argv )
/* compute lines */
std::vector<KeyLine> keylines;
bd->detect( imageMat, keylines, mask, 1 );
bd->detect( imageMat, keylines, mask );
/* select only lines from first octave */
std::vector<KeyLine> octave0;
@ -115,7 +114,7 @@ int main( int argc, char** argv )
/* compute descriptors */
cv::Mat descriptors;
bd->compute( imageMat, octave0, descriptors, false, 1 );
writeMat(descriptors, "bd_descriptors", 0);
bd->compute( imageMat, octave0, descriptors, 1);
writeMat( descriptors, "bd_descriptors", 0 );
}

@ -80,7 +80,7 @@ int main( int argc, char** argv )
std::cout << "Error, image could not be loaded. Please, check its path" << std::endl;
}
/* create a ramdom binary mask */
/* create a random binary mask */
cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );
/* create a pointer to a BinaryDescriptor object with deafult parameters */
@ -91,16 +91,15 @@ int main( int argc, char** argv )
/* extract lines */
cv::Mat output = imageMat.clone();
bd->detect( imageMat, lines, mask, 1 );
bd->detect( imageMat, lines, mask );
/* draw lines extracted from octave 0 */
if( output.channels() == 1 )
cvtColor( output, output, COLOR_GRAY2BGR );
for ( size_t i = 0; i < lines.size(); i++ )
{
KeyLine kl = lines[i];
if( kl.octave == 0 /*&& kl.response >0.08*/)
if( kl.octave == 0)
{
/* get a random color */
int R = ( rand() % (int) ( 255 + 1 ) );
@ -112,7 +111,7 @@ int main( int argc, char** argv )
Point pt2 = Point( kl.endPointX, kl.endPointY );
/* draw line */
line( output, pt1, pt2, Scalar( B, G, R ), 5 );
line( output, pt1, pt2, Scalar( B, G, R ), 3 );
}
}

@ -128,13 +128,4 @@ int main( int argc, char** argv )
std::vector<std::vector<DMatch> > matches;
bdm->radiusMatch( queries, matches, 30 );
/* print matches */
for ( size_t q = 0; q < matches.size(); q++ )
{
for ( size_t m = 0; m < matches[q].size(); m++ )
{
DMatch dm = matches[q][m];
std::cout << "Descriptor: " << q << " Image: " << dm.imgIdx << " Distance: " << dm.distance << std::endl;
}
}
}

@ -0,0 +1,215 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2014, Biagio Montesano, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
using namespace cv;
Ptr<LSDDetector> LSDDetector::createLSDDetector()
{
return Ptr<LSDDetector>( new LSDDetector() );
}
/* compute Gaussian pyramid of input image */
void LSDDetector::computeGaussianPyramid( const Mat& image, int numOctaves, int scale )
{
/* clear class fields */
gaussianPyrs.clear();
/* insert input image into pyramid */
cv::Mat currentMat = image.clone();
cv::GaussianBlur( currentMat, currentMat, cv::Size( 5, 5 ), 1 );
gaussianPyrs.push_back( currentMat );
/* fill Gaussian pyramid */
for ( int pyrCounter = 1; pyrCounter < numOctaves; pyrCounter++ )
{
/* compute and store next image in pyramid and its size */
pyrDown( currentMat, currentMat, Size( currentMat.cols / scale, currentMat.rows / scale ) );
gaussianPyrs.push_back( currentMat );
}
}
/* check lines' extremes */
inline void checkLineExtremes( cv::Vec4i& extremes, cv::Size imageSize )
{
if( extremes[0] < 0 )
extremes[0] = 0;
if( extremes[0] >= imageSize.width )
extremes[0] = imageSize.width - 1;
if( extremes[2] < 0 )
extremes[2] = 0;
if( extremes[2] >= imageSize.width )
extremes[2] = imageSize.width - 1;
if( extremes[1] < 0 )
extremes[1] = 0;
if( extremes[1] >= imageSize.height )
extremes[1] = imageSize.height - 1;
if( extremes[3] < 0 )
extremes[3] = 0;
if( extremes[3] >= imageSize.height )
extremes[3] = imageSize.height - 1;
}
/* requires line detection (only one image) */
void LSDDetector::detect( const Mat& image, CV_OUT std::vector<KeyLine>& keylines, int scale, int numOctaves, const Mat& mask )
{
if( mask.data != NULL && ( mask.size() != image.size() || mask.type() != CV_8UC1 ) )
{
std::cout << "Mask error while detecting lines: " << "please check its dimensions and that data type is CV_8UC1" << std::endl;
CV_Assert( false );
}
else
detectImpl( image, keylines, numOctaves, scale, mask );
}
/* requires line detection (more than one image) */
void LSDDetector::detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, int scale, int numOctaves,
const std::vector<Mat>& masks ) const
{
/* detect lines from each image */
for ( size_t counter = 0; counter < images.size(); counter++ )
{
if( masks[counter].data != NULL && ( masks[counter].size() != images[counter].size() || masks[counter].type() != CV_8UC1 ) )
{
std::cout << "Masks error while detecting lines: " << "please check their dimensions and that data types are CV_8UC1" << std::endl;
CV_Assert( false );
}
detectImpl( images[counter], keylines[counter], numOctaves, scale, masks[counter] );
}
}
/* implementation of line detection */
void LSDDetector::detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, int numOctaves, int scale, const Mat& mask ) const
{
cv::Mat image;
if( imageSrc.channels() != 1 )
cvtColor( imageSrc, image, COLOR_BGR2GRAY );
else
image = imageSrc.clone();
/*check whether image depth is different from 0 */
if( image.depth() != 0 )
{
std::cout << "Warning, depth image!= 0" << std::endl;
CV_Assert( false );
}
/* create a pointer to self */
LSDDetector *lsd = const_cast<LSDDetector*>( this );
/* compute Gaussian pyramids */
lsd->computeGaussianPyramid( image, numOctaves, scale );
/* create an LSD extractor */
cv::Ptr<cv::LineSegmentDetector> ls = cv::createLineSegmentDetector( cv::LSD_REFINE_ADV );
/* prepare a vector to host extracted segments */
std::vector<std::vector<cv::Vec4i> > lines_lsd;
/* extract lines */
for ( int i = 0; i < numOctaves; i++ )
{
std::vector<Vec4i> octave_lines;
ls->detect( gaussianPyrs[i], octave_lines );
lines_lsd.push_back( octave_lines );
}
/* create keylines */
for ( int j = 0; j < (int) lines_lsd.size(); j++ )
{
for ( int k = 0; k < (int) lines_lsd[j].size(); k++ )
{
KeyLine kl;
cv::Vec4i extremes = lines_lsd[j][k];
/* check data validity */
checkLineExtremes( extremes, gaussianPyrs[j].size() );
/* fill KeyLine's fields */
kl.startPointX = extremes[0];
kl.startPointY = extremes[1];
kl.endPointX = extremes[2];
kl.endPointY = extremes[3];
kl.sPointInOctaveX = extremes[0];
kl.sPointInOctaveY = extremes[1];
kl.ePointInOctaveX = extremes[2];
kl.ePointInOctaveY = extremes[3];
kl.lineLength = sqrt( pow( extremes[0] - extremes[2], 2 ) + pow( extremes[1] - extremes[3], 2 ) );
/* compute number of pixels covered by line */
LineIterator li( gaussianPyrs[j], Point( extremes[0], extremes[1] ), Point( extremes[2], extremes[3] ) );
kl.numOfPixels = li.count;
kl.angle = atan2( ( kl.endPointY - kl.startPointY ), ( kl.endPointX - kl.startPointX ) );
kl.class_id = k;
kl.octave = j;
kl.size = ( kl.endPointX - kl.startPointX ) * ( kl.endPointY - kl.startPointY );
kl.response = kl.lineLength / max( gaussianPyrs[j].cols, gaussianPyrs[j].rows );
kl.pt = Point( ( kl.endPointX + kl.startPointX ) / 2, ( kl.endPointY + kl.startPointY ) / 2 );
keylines.push_back( kl );
}
}
/* delete undesired KeyLines, according to input mask */
if( !mask.empty() )
{
for ( size_t keyCounter = 0; keyCounter < keylines.size(); keyCounter++ )
{
KeyLine kl = keylines[keyCounter];
if( mask.at<uchar>( kl.startPointY, kl.startPointX ) == 0 && mask.at<uchar>( kl.endPointY, kl.endPointX ) == 0 )
keylines.erase( keylines.begin() + keyCounter );
}
}
}

File diff suppressed because it is too large Load Diff

@ -159,7 +159,7 @@ void BinaryDescriptorMatcher::match( const Mat& queryDescriptors, std::vector<DM
CV_Assert( false );
}
/* create a DMatch object if required by mask of if there is
/* create a DMatch object if required by mask or if there is
no mask at all */
else if( masks.empty() || masks[itup->second].at<uchar>( counter ) != 0 )
{
@ -212,7 +212,7 @@ void BinaryDescriptorMatcher::match( const Mat& queryDescriptors, const Mat& tra
/* compose matches */
for ( int counter = 0; counter < queryDescriptors.rows; counter++ )
{
/* create a DMatch object if required by mask of if there is
/* create a DMatch object if required by mask or if there is
no mask at all */
if( mask.empty() || ( !mask.empty() && mask.at<uchar>( counter ) != 0 ) )
{

File diff suppressed because it is too large Load Diff

@ -46,12 +46,14 @@ namespace cv
CV_INIT_ALGORITHM( BinaryDescriptor, "BINARY.DESCRIPTOR", );
CV_INIT_ALGORITHM( BinaryDescriptorMatcher, "BINARY.DESCRIPTOR.MATCHER", );
CV_INIT_ALGORITHM( LSDDetector, "LSDDETECTOR", );
bool initModule_line_descriptor( void )
{
bool all = true;
all &= !BinaryDescriptor_info_auto.name().empty();
all &= !BinaryDescriptorMatcher_info_auto.name().empty();
all &= !LSDDetector_info_auto.name().empty();
return all;
}

@ -58,8 +58,6 @@
#include <algorithm>
#include <bitset>
#include "opencv2/line_descriptor.hpp"
#endif

Loading…
Cancel
Save