mirror of
https://github.com/opencv/opencv_contrib.git
synced 2025-10-20 12:55:15 +08:00
Added methods for derivation from FeatureDetector
This commit is contained in:
@@ -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
|
|||||||
/* 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
|
|||||||
CV_WRAP BinaryDescriptor(const BinaryDescriptor::Params ¶meters =
|
CV_WRAP BinaryDescriptor(const BinaryDescriptor::Params ¶meters =
|
||||||
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() );
|
||||||
|
|
||||||
|
/* requires line detection (more than one image) */
|
||||||
|
void detect( const std::vector<Mat>& images,
|
||||||
|
std::vector<std::vector<KeyPoint> >& keypoints,
|
||||||
|
const std::vector<Mat>& masks=std::vector<Mat>() ) const;
|
||||||
|
|
||||||
|
/*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:
|
protected:
|
||||||
virtual void getLineBinaryDescriptorsImpl(cv::Mat &oct_binaryDescMat);
|
virtual void detectImpl( const Mat& image,
|
||||||
|
std::vector<KeyPoint>& keypoints,
|
||||||
|
const Mat& mask=Mat() ) const = 0;
|
||||||
|
|
||||||
AlgorithmInfo* info() const;
|
AlgorithmInfo* info() const;
|
||||||
|
|
||||||
Params params;
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|||||||
/* 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
|
|||||||
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,74 +209,163 @@ 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);
|
||||||
/* compute and store derivatives of new image */
|
bn->images_sizes.push_back(currentMat.size());
|
||||||
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 */
|
/* detect and arrange lines across octaves */
|
||||||
ScaleLines keyLines;
|
ScaleLines sl;
|
||||||
|
bn->OctaveKeyLines(sl);
|
||||||
|
|
||||||
/* extract and arrange lines */
|
/* fill KeyLines vector */
|
||||||
OctaveKeyLines(matVec, keyLines);
|
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];
|
||||||
|
|
||||||
/* compute LBD descriptors */
|
/* create a KeyLine object */
|
||||||
ComputeLBD_(keyLines);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///* extract lines from an image and compute their descriptors */
|
||||||
|
//inline void getLineBinaryDescriptors(cv::Mat &oct_binaryDescMat)
|
||||||
|
//{
|
||||||
|
// /* start function that actually implements descriptors' computation */
|
||||||
|
// getLineBinaryDescriptorsImpl(oct_binaryDescMat);
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
///* compute descriptors */
|
||||||
|
//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) {
|
||||||
if(i>=0 && i<=7)
|
if(i>=0 && i<=7)
|
||||||
@@ -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
|
|||||||
/* 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
|
|||||||
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
|
|||||||
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))
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user