Commit fba71a8e authored by biagio montesano's avatar biagio montesano

Added methods for derivation from FeatureDetector

parent 0863960c
...@@ -53,18 +53,32 @@ ...@@ -53,18 +53,32 @@
namespace cv namespace cv
{ {
class CV_EXPORTS_W LineDescriptor : public virtual Algorithm class CV_EXPORTS_W KeyLine: public KeyPoint
{ {
public: public:
virtual ~LineDescriptor(); /* lines's extremes in original image */
void getLineBinaryDescriptors(cv::Mat &oct_binaryDescMat); float startPointX;
float startPointY;
float endPointX;
float endPointY;
/* line's extremes in image it was extracted from */
float sPointInOctaveX;
float sPointInOctaveY;
float ePointInOctaveX;
float ePointInOctaveY;
/* the length of line */
float lineLength;
/* number of pixels covered by the line */
unsigned int numOfPixels;
protected:
virtual void getLineBinaryDescriptorsImpl(cv::Mat &oct_binaryDescMat);
}; };
class CV_EXPORTS_W BinaryDescriptor : public LineDescriptor class CV_EXPORTS_W BinaryDescriptor : public DescriptorExtractor
{ {
public: public:
...@@ -92,7 +106,10 @@ namespace cv ...@@ -92,7 +106,10 @@ namespace cv
/* image's reduction ratio in construction of Gaussian pyramids */ /* image's reduction ratio in construction of Gaussian pyramids */
CV_PROP_RW int reductionRatio; CV_PROP_RW int reductionRatio;
/* read parameters from a FileNode object and store them (struct function) */
void read( const FileNode& fn ); void read( const FileNode& fn );
/* store parameters to a FileStorage object (struct function) */
void write( FileStorage& fs ) const; void write( FileStorage& fs ) const;
}; };
...@@ -100,29 +117,63 @@ namespace cv ...@@ -100,29 +117,63 @@ namespace cv
CV_WRAP BinaryDescriptor(const BinaryDescriptor::Params &parameters = CV_WRAP BinaryDescriptor(const BinaryDescriptor::Params &parameters =
BinaryDescriptor::Params()); BinaryDescriptor::Params());
/* read parameters from a FileNode object and store them (class function ) */
virtual void read( const cv::FileNode& fn ); virtual void read( const cv::FileNode& fn );
/* store parameters to a FileStorage object (class function) */
virtual void write( cv::FileStorage& fs ) const; virtual void write( cv::FileStorage& fs ) const;
void getLineBinaryDescriptors(cv::Mat &oct_binaryDescMat);
/* requires line detection (only one image) */
CV_WRAP void detect( const Mat& image,
CV_OUT std::vector<KeyPoint>& keypoints,
const Mat& mask=Mat() );
protected: /* requires line detection (more than one image) */
virtual void getLineBinaryDescriptorsImpl(cv::Mat &oct_binaryDescMat); void detect( const std::vector<Mat>& images,
AlgorithmInfo* info() const; std::vector<std::vector<KeyPoint> >& keypoints,
const std::vector<Mat>& masks=std::vector<Mat>() ) const;
Params params; /*return descriptor size */
int descriptorSize() const = 0;
/* return data type */
int descriptorType() const = 0;
/* return norm mode */
int defaultNorm() const = 0;
/* check whether Gaussian pyramids were created */
bool empty() const;
protected:
virtual void detectImpl( const Mat& image,
std::vector<KeyPoint>& keypoints,
const Mat& mask=Mat() ) const = 0;
AlgorithmInfo* info() const;
private: private:
/* conversion of an LBD descriptor to the decimal equivalent of its binary representation */
unsigned char binaryTest(float* f1, float* f2); unsigned char binaryTest(float* f1, float* f2);
/* compute LBD descriptors */
int ComputeLBD_(ScaleLines &keyLines); int ComputeLBD_(ScaleLines &keyLines);
int OctaveKeyLines(std::vector<cv::Mat> & octaveImages, ScaleLines &keyLines);
/* gather lines in groups.
Each group contains the same line, detected in different octaves */
int OctaveKeyLines(ScaleLines &keyLines);
/* get coefficients of line passing by two points (in line_extremes) */
void getLineParameters(cv::Vec4i &line_extremes, cv::Vec3i &lineParams); void getLineParameters(cv::Vec4i &line_extremes, cv::Vec3i &lineParams);
/* compute the angle between line and X axis */
float getLineDirection(cv::Vec3i &lineParams); float getLineDirection(cv::Vec3i &lineParams);
/* the local gaussian coefficient apply to the orthogonal line direction within each band */ /* the local gaussian coefficient applied to the orthogonal line direction within each band */
std::vector<float> gaussCoefL_; std::vector<float> gaussCoefL_;
/* the global gaussian coefficient apply to each Row within line support region */ /* the global gaussian coefficient applied to each Row within line support region */
std::vector<float> gaussCoefG_; std::vector<float> gaussCoefG_;
/* vector to store horizontal and vertical derivatives of octave images */ /* vector to store horizontal and vertical derivatives of octave images */
...@@ -134,6 +185,12 @@ namespace cv ...@@ -134,6 +185,12 @@ namespace cv
/* structure to store lines extracted from each octave image */ /* structure to store lines extracted from each octave image */
std::vector<std::vector<cv::Vec4i> > extractedLines; 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;
}; };
} }
......
...@@ -132,7 +132,31 @@ void BinaryDescriptor::write( cv::FileStorage& fs ) const ...@@ -132,7 +132,31 @@ void BinaryDescriptor::write( cv::FileStorage& fs ) const
params.write(fs); params.write(fs);
} }
/* get coefficients of line passing by two points in line_extremes */ /* return norm mode */
int BinaryDescriptor::defaultNorm() const
{
return NORM_HAMMING;
}
/* return data type */
int BinaryDescriptor::descriptorType() const
{
return CV_8U;
}
/*return descriptor size */
int BinaryDescriptor::descriptorSize() const
{
return 1;
}
/* check whether Gaussian pyramids were created */
bool BinaryDescriptor::empty() const
{
return true;
}
/* get coefficients of line passing by two points in (line_extremes) */
void BinaryDescriptor::getLineParameters(cv::Vec4i &line_extremes, cv::Vec3i &lineParams) void BinaryDescriptor::getLineParameters(cv::Vec4i &line_extremes, cv::Vec3i &lineParams)
{ {
int x1 = line_extremes[0]; int x1 = line_extremes[0];
...@@ -185,73 +209,162 @@ float BinaryDescriptor::getLineDirection(cv::Vec3i &lineParams) ...@@ -185,73 +209,162 @@ float BinaryDescriptor::getLineDirection(cv::Vec3i &lineParams)
return atan(m); return atan(m);
else else
return M_PI - atan(m); return -atan(m);
} }
} }
/* extract lines from an image and compute their descriptors */ /* requires line detection (only one image) */
void BinaryDescriptor::getLineBinaryDescriptors(cv::Mat &oct_binaryDescMat) void BinaryDescriptor::detect( const Mat& image,
CV_OUT std::vector<KeyPoint>& keypoints,
const Mat& mask)
{ {
/* start function that actually implements descriptors' computation */ /* invoke KeyLines detection */
getLineBinaryDescriptorsImpl(oct_binaryDescMat); detectImpl(image, keypoints, mask);
} }
/* compute descriptors */ /* requires line detection (more than one image) */
void BinaryDescriptor::getLineBinaryDescriptorsImpl(cv::Mat &oct_binaryDescMat) void BinaryDescriptor::detect( const std::vector<Mat>& images,
std::vector<std::vector<KeyPoint> >& keypoints,
const std::vector<Mat>& masks ) const
{ {
/* prepare a matrix to store Gaussian pyramid of input matrix */ /* detect lines from each image */
std::vector<cv::Mat> matVec(params.numOfOctave_); for(size_t counter = 0; counter<images.size(); counter++)
{
detectImpl(images[counter],keypoints[counter], masks[counter]);
}
}
/* reinitialize structures for hosting images' derivatives and sizes void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keypoints,
const Mat& mask) const
{
/* reinitialize structures for hosting images, images' derivatives and sizes
(they may have been used in the past) */ (they may have been used in the past) */
dxImg_vector.clear(); BinaryDescriptor *bn = const_cast<BinaryDescriptor*>(this);
dyImg_vector.clear(); bn->dxImg_vector.clear();
images_sizes.clear(); bn->dyImg_vector.clear();
bn->images_sizes.clear();
dxImg_vector.resize(params.numOfOctave_); bn->octaveImages.clear();
dyImg_vector.resize(params.numOfOctave_);
images_sizes.resize(params.numOfOctave_);
/* insert input image into pyramid */ /* insert input image into pyramid */
cv::Mat currentMat = oct_binaryDescMat.clone(); cv::Mat currentMat = image.clone();
matVec.push_back(currentMat); bn->octaveImages.push_back(currentMat);
images_sizes.push_back(currentMat.size()); bn->images_sizes.push_back(currentMat.size());
/* compute and store derivatives of input image */
cv:Mat currentDx, currentDy;
cv::Sobel( currentMat, currentDx, CV_16SC1, 1, 0, 3);
cv::Sobel( currentMat, currentDy, CV_16SC1, 0, 1, 3);
dxImg_vector.push_back(currentDx);
dyImg_vector.push_back(currentDy);
/* fill Gaussian pyramid */ /* fill Gaussian pyramid */
for(int i = 1; i<params.numOfOctave_; i++) for(int pyrCounter = 0; pyrCounter<params.numOfOctave_; pyrCounter++)
{ {
/* compute and store next image in pyramid and its size */ /* compute and store next image in pyramid and its size */
pyrDown( currentMat, currentMat, Size( currentMat.cols/params.reductionRatio, currentMat.rows/params.reductionRatio )); pyrDown( currentMat, currentMat,
matVec.push_back(currentMat); Size( currentMat.cols/params.reductionRatio,
images_sizes.push_back(currentMat.size()); currentMat.rows/params.reductionRatio ));
bn->octaveImages.push_back(currentMat);
bn->images_sizes.push_back(currentMat.size());
}
/* compute and store derivatives of new image */ /* detect and arrange lines across octaves */
cv::Sobel( currentMat, currentDx, CV_16SC1, 1, 0, 3); ScaleLines sl;
cv::Sobel( currentMat, currentDy, CV_16SC1, 0, 1, 3); bn->OctaveKeyLines(sl);
dxImg_vector.push_back(currentDx); /* fill KeyLines vector */
dyImg_vector.push_back(currentDy); for(int i = 0; i<(int)sl.size(); i++)
{
for(size_t j = 0; j<sl[i].size(); j++)
{
/* get current line */
OctaveSingleLine osl = sl[i][j];
/* create a KeyLine object */
KeyLine kl;
/* fill KeyLine's fields */
kl.startPointX = osl.startPointX;
kl.startPointY = osl.startPointY;
kl.endPointX = osl.endPointX;
kl.endPointY = osl.endPointY;
kl.sPointInOctaveX = osl.sPointInOctaveX;
kl.sPointInOctaveY = osl.sPointInOctaveY;
kl.ePointInOctaveX = osl.ePointInOctaveX;
kl.ePointInOctaveY = osl.ePointInOctaveY;
kl.lineLength = osl.lineLength;
kl.angle = osl.direction;
kl.class_id = i;
kl.octave = osl.octaveCount;
kl.size = (osl.endPointX - osl.startPointX)*(osl.endPointY - osl.startPointY);
kl.response = osl.lineLength/max(images_sizes[osl.octaveCount].width,
images_sizes[osl.octaveCount].height);
kl.pt = Point((osl.endPointX + osl.startPointX)/2, (osl.endPointY + osl.startPointY)/2);
/* store KeyLine */
keypoints.push_back(kl);
}
} }
}
/* prepare a structure for hosting and organizing extracted lines */ ///* extract lines from an image and compute their descriptors */
ScaleLines keyLines; //inline void getLineBinaryDescriptors(cv::Mat &oct_binaryDescMat)
//{
// /* start function that actually implements descriptors' computation */
// getLineBinaryDescriptorsImpl(oct_binaryDescMat);
/* extract and arrange lines */ //}
OctaveKeyLines(matVec, keyLines);
/* compute LBD descriptors */ ///* compute descriptors */
ComputeLBD_(keyLines); //inline void getLineBinaryDescriptorsImpl(cv::Mat &oct_binaryDescMat)
//{
// /* prepare a matrix to store Gaussian pyramid of input matrix */
// std::vector<cv::Mat> matVec(params.numOfOctave_);
} // /* reinitialize structures for hosting images' derivatives and sizes
// (they may have been used in the past) */
// dxImg_vector.clear();
// dyImg_vector.clear();
// images_sizes.clear();
// dxImg_vector.resize(params.numOfOctave_);
// dyImg_vector.resize(params.numOfOctave_);
// images_sizes.resize(params.numOfOctave_);
// /* insert input image into pyramid */
// cv::Mat currentMat = oct_binaryDescMat.clone();
// matVec.push_back(currentMat);
// images_sizes.push_back(currentMat.size());
// /* compute and store derivatives of input image */
// cv:Mat currentDx, currentDy;
// cv::Sobel( currentMat, currentDx, CV_16SC1, 1, 0, 3);
// cv::Sobel( currentMat, currentDy, CV_16SC1, 0, 1, 3);
// dxImg_vector.push_back(currentDx);
// dyImg_vector.push_back(currentDy);
// /* fill Gaussian pyramid */
// for(int i = 1; i<params.numOfOctave_; i++)
// {
// /* compute and store next image in pyramid and its size */
// pyrDown( currentMat, currentMat, Size( currentMat.cols/params.reductionRatio, currentMat.rows/params.reductionRatio ));
// matVec.push_back(currentMat);
// images_sizes.push_back(currentMat.size());
// /* compute and store derivatives of new image */
// cv::Sobel( currentMat, currentDx, CV_16SC1, 1, 0, 3);
// cv::Sobel( currentMat, currentDy, CV_16SC1, 0, 1, 3);
// dxImg_vector.push_back(currentDx);
// dyImg_vector.push_back(currentDy);
// }
// /* prepare a structure for hosting and organizing extracted lines */
// ScaleLines keyLines;
// /* extract and arrange lines */
// OctaveKeyLines(matVec, keyLines);
// /* compute LBD descriptors */
// ComputeLBD_(keyLines);
//}
/* power function with error management */ /* power function with error management */
static inline int get2Pow(int i) { static inline int get2Pow(int i) {
...@@ -280,7 +393,7 @@ unsigned char BinaryDescriptor::binaryTest(float* f1, float* f2) ...@@ -280,7 +393,7 @@ unsigned char BinaryDescriptor::binaryTest(float* f1, float* f2)
} }
/* gather lines in groups. Each group contains the same line, detected in different octaves */ /* gather lines in groups. Each group contains the same line, detected in different octaves */
int BinaryDescriptor::OctaveKeyLines(std::vector<cv::Mat> & octaveImages, ScaleLines &keyLines) int BinaryDescriptor::OctaveKeyLines(ScaleLines &keyLines)
{ {
/* final number of extracted lines */ /* final number of extracted lines */
...@@ -345,7 +458,7 @@ int BinaryDescriptor::OctaveKeyLines(std::vector<cv::Mat> & octaveImages, ScaleL ...@@ -345,7 +458,7 @@ int BinaryDescriptor::OctaveKeyLines(std::vector<cv::Mat> & octaveImages, ScaleL
/* create and fill an array to store scale factors */ /* create and fill an array to store scale factors */
float *scale = new float[params.numOfOctave_]; float *scale = new float[params.numOfOctave_];
scale[0] = 1; scale[0] = 1;
for(unsigned int octaveCount = 1; octaveCount<params.numOfOctave_; octaveCount++ ) for(unsigned int octaveCount = 1; octaveCount<(unsigned int)params.numOfOctave_; octaveCount++ )
{ {
scale[octaveCount] = params.reductionRatio * scale[octaveCount-1]; scale[octaveCount] = params.reductionRatio * scale[octaveCount-1];
} }
...@@ -366,7 +479,7 @@ int BinaryDescriptor::OctaveKeyLines(std::vector<cv::Mat> & octaveImages, ScaleL ...@@ -366,7 +479,7 @@ int BinaryDescriptor::OctaveKeyLines(std::vector<cv::Mat> & octaveImages, ScaleL
float lp0,lp1, lp2, lp3, np0,np1, np2, np3; float lp0,lp1, lp2, lp3, np0,np1, np2, np3;
/* loop over list of octaves */ /* loop over list of octaves */
for(unsigned int octaveCount = 1; octaveCount<params.numOfOctave_; octaveCount++) for(unsigned int octaveCount = 1; octaveCount<(unsigned int)params.numOfOctave_; octaveCount++)
{ {
/*for each line in current octave image, find their corresponding lines /*for each line in current octave image, find their corresponding lines
in the octaveLines, in the octaveLines,
...@@ -483,7 +596,7 @@ int BinaryDescriptor::OctaveKeyLines(std::vector<cv::Mat> & octaveImages, ScaleL ...@@ -483,7 +596,7 @@ int BinaryDescriptor::OctaveKeyLines(std::vector<cv::Mat> & octaveImages, ScaleL
maxLocalDis = (endPointDis>maxLocalDis)?endPointDis:maxLocalDis; maxLocalDis = (endPointDis>maxLocalDis)?endPointDis:maxLocalDis;
/* check whether conditions for considering line to be compared /* check whether conditions for considering line to be compared
worth to be inserted in the same LineVec are satisfied */ wremoveInvalidPointsorth to be inserted in the same LineVec are satisfied */
if((maxLocalDis<0.8*(length+octaveLines[lineNextId].lineLength)) if((maxLocalDis<0.8*(length+octaveLines[lineNextId].lineLength))
&&(minLocalDis<minEndPointDis)) &&(minLocalDis<minEndPointDis))
{ {
......
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