Commit a0237c31 authored by biagio montesano's avatar biagio montesano

computeImpl method designed, Gaussian pyramids in a separate function

parent 9b8b088b
...@@ -133,6 +133,14 @@ namespace cv ...@@ -133,6 +133,14 @@ namespace cv
std::vector<std::vector<KeyPoint> >& keypoints, std::vector<std::vector<KeyPoint> >& keypoints,
const std::vector<Mat>& masks=std::vector<Mat>() ) const; const std::vector<Mat>& masks=std::vector<Mat>() ) const;
CV_WRAP void compute( const Mat& image,
CV_OUT CV_IN_OUT std::vector<KeyPoint>& keypoints,
CV_OUT Mat& descriptors ) const;
void compute( const std::vector<Mat>& images,
std::vector<std::vector<KeyPoint> >& keypoints,
std::vector<Mat>& descriptors ) const;
/*return descriptor size */ /*return descriptor size */
int descriptorSize() const; int descriptorSize() const;
...@@ -145,12 +153,22 @@ namespace cv ...@@ -145,12 +153,22 @@ namespace cv
/* check whether Gaussian pyramids were created */ /* check whether Gaussian pyramids were created */
bool empty() const; bool empty() const;
CV_WRAP_AS(detectAndCompute) virtual void operator()( InputArray image,
InputArray mask,
CV_OUT std::vector<KeyPoint>& keypoints,
OutputArray descriptors,
bool useProvidedKeypoints=false ) const = 0;
protected: protected:
virtual void detectImpl( const Mat& image, virtual void detectImpl( const Mat& image,
std::vector<KeyPoint>& keypoints, std::vector<KeyPoint>& keypoints,
const Mat& mask=Mat() ) const = 0; const Mat& mask=Mat() ) const = 0;
virtual void computeImpl( const Mat& image,
std::vector<KeyPoint>& keypoints,
Mat& descriptors ) const = 0;
AlgorithmInfo* info() const; AlgorithmInfo* info() const;
private: private:
...@@ -158,7 +176,10 @@ namespace cv ...@@ -158,7 +176,10 @@ namespace cv
unsigned char binaryTest(float* f1, float* f2); unsigned char binaryTest(float* f1, float* f2);
/* compute LBD descriptors */ /* compute LBD descriptors */
int ComputeLBD_(ScaleLines &keyLines); int computeLBD_(ScaleLines &keyLines);
/* compute Gaussian pyramid of input image */
void computeGaussianPyramid(const Mat& image);
/* gather lines in groups. /* gather lines in groups.
Each group contains the same line, detected in different octaves */ Each group contains the same line, detected in different octaves */
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#define _USE_MATH_DEFINES #define _USE_MATH_DEFINES
#include "precomp.hpp" #include "precomp.hpp"
#include <math.h>
using namespace cv; using namespace cv;
...@@ -153,7 +152,33 @@ int BinaryDescriptor::descriptorSize() const ...@@ -153,7 +152,33 @@ int BinaryDescriptor::descriptorSize() const
/* check whether Gaussian pyramids were created */ /* check whether Gaussian pyramids were created */
bool BinaryDescriptor::empty() const bool BinaryDescriptor::empty() const
{ {
return true; return false;
}
/* power function with error management */
static inline int get2Pow(int i) {
if(i>=0 && i<=7)
return pow(2,i);
else
{
CV_Assert(false);
return -1;
}
}
/* conversion of an LBD descriptor to the decimal equivalent of its binary representation */
unsigned char BinaryDescriptor::binaryTest(float* f1, float* f2)
{
uchar result = 0;
for(int i = 0; i<8; i++)
{
if(f1[i]>f2[i])
result+=get2Pow(i);
}
return result;
} }
/* get coefficients of line passing by two points in (line_extremes) */ /* get coefficients of line passing by two points in (line_extremes) */
...@@ -213,6 +238,30 @@ float BinaryDescriptor::getLineDirection(cv::Vec3i &lineParams) ...@@ -213,6 +238,30 @@ float BinaryDescriptor::getLineDirection(cv::Vec3i &lineParams)
} }
} }
/* compute Gaussian pyramid of input image */
void BinaryDescriptor::computeGaussianPyramid(const Mat& image)
{
/* clear class fields */
images_sizes.clear();
octaveImages.clear();
/* insert input image into pyramid */
cv::Mat currentMat = image.clone();
octaveImages.push_back(currentMat);
images_sizes.push_back(currentMat.size());
/* fill Gaussian pyramid */
for(int pyrCounter = 1; pyrCounter<params.numOfOctave_; pyrCounter++)
{
/* compute and store next image in pyramid and its size */
pyrDown( currentMat, currentMat,
Size( currentMat.cols/params.reductionRatio,
currentMat.rows/params.reductionRatio ));
octaveImages.push_back(currentMat);
images_sizes.push_back(currentMat.size());
}
}
/* requires line detection (only one image) */ /* requires line detection (only one image) */
void BinaryDescriptor::detect( const Mat& image, void BinaryDescriptor::detect( const Mat& image,
CV_OUT std::vector<KeyPoint>& keypoints, CV_OUT std::vector<KeyPoint>& keypoints,
...@@ -243,24 +292,9 @@ void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keyp ...@@ -243,24 +292,9 @@ void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keyp
BinaryDescriptor *bn = const_cast<BinaryDescriptor*>(this); BinaryDescriptor *bn = const_cast<BinaryDescriptor*>(this);
bn->dxImg_vector.clear(); bn->dxImg_vector.clear();
bn->dyImg_vector.clear(); bn->dyImg_vector.clear();
bn->images_sizes.clear();
bn->octaveImages.clear();
/* insert input image into pyramid */ /* compute Gaussian pyramid */
cv::Mat currentMat = image.clone(); bn->computeGaussianPyramid(image);
bn->octaveImages.push_back(currentMat);
bn->images_sizes.push_back(currentMat.size());
/* fill Gaussian pyramid */
for(int pyrCounter = 0; pyrCounter<params.numOfOctave_; pyrCounter++)
{
/* compute and store next image in pyramid and its size */
pyrDown( currentMat, currentMat,
Size( currentMat.cols/params.reductionRatio,
currentMat.rows/params.reductionRatio ));
bn->octaveImages.push_back(currentMat);
bn->images_sizes.push_back(currentMat.size());
}
/* detect and arrange lines across octaves */ /* detect and arrange lines across octaves */
ScaleLines sl; ScaleLines sl;
...@@ -287,6 +321,7 @@ void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keyp ...@@ -287,6 +321,7 @@ void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keyp
kl.ePointInOctaveX = osl.ePointInOctaveX; kl.ePointInOctaveX = osl.ePointInOctaveX;
kl.ePointInOctaveY = osl.ePointInOctaveY; kl.ePointInOctaveY = osl.ePointInOctaveY;
kl.lineLength = osl.lineLength; kl.lineLength = osl.lineLength;
kl.numOfPixels = osl.numOfPixels;
kl.angle = osl.direction; kl.angle = osl.direction;
kl.class_id = i; kl.class_id = i;
...@@ -294,7 +329,8 @@ void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keyp ...@@ -294,7 +329,8 @@ void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keyp
kl.size = (osl.endPointX - osl.startPointX)*(osl.endPointY - osl.startPointY); kl.size = (osl.endPointX - osl.startPointX)*(osl.endPointY - osl.startPointY);
kl.response = osl.lineLength/max(images_sizes[osl.octaveCount].width, kl.response = osl.lineLength/max(images_sizes[osl.octaveCount].width,
images_sizes[osl.octaveCount].height); images_sizes[osl.octaveCount].height);
kl.pt = Point((osl.endPointX + osl.startPointX)/2, (osl.endPointY + osl.startPointY)/2); kl.pt = Point((osl.endPointX + osl.startPointX)/2,
(osl.endPointY + osl.startPointY)/2);
/* store KeyLine */ /* store KeyLine */
keypoints.push_back(kl); keypoints.push_back(kl);
...@@ -302,95 +338,98 @@ void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keyp ...@@ -302,95 +338,98 @@ void BinaryDescriptor::detectImpl( const Mat& image, std::vector<KeyPoint>& keyp
} }
} }
///* extract lines from an image and compute their descriptors */ void BinaryDescriptor::computeImpl( const Mat& image,
//inline void getLineBinaryDescriptors(cv::Mat &oct_binaryDescMat) std::vector<KeyPoint>& keypoints,
//{ Mat& descriptors ) const
// /* start function that actually implements descriptors' computation */ {
// getLineBinaryDescriptorsImpl(oct_binaryDescMat); /* keypoints list can't be empty */
if(keypoints.size() == 0)
//} {
std::cout << "Error: keypoint list is empty" << std::endl;
///* compute descriptors */ return;
//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 */ /* get number of lines */
// for(int i = 1; i<params.numOfOctave_; i++) int numLines = 0;
// { for(size_t l = 0; l<keypoints.size(); l++)
// /* compute and store next image in pyramid and its size */ {
// pyrDown( currentMat, currentMat, Size( currentMat.cols/params.reductionRatio, currentMat.rows/params.reductionRatio )); if(keypoints[l].class_id > numLines)
// matVec.push_back(currentMat); numLines = keypoints[l].class_id;
// images_sizes.push_back(currentMat.size()); }
// /* compute and store derivatives of new image */ /* create a ScaleLines object */
// cv::Sobel( currentMat, currentDx, CV_16SC1, 1, 0, 3); OctaveSingleLine fictiousOSL;
// cv::Sobel( currentMat, currentDy, CV_16SC1, 0, 1, 3); fictiousOSL.octaveCount = -1;
LinesVec lv(params.numOfOctave_, fictiousOSL);
ScaleLines sl(numLines, lv);
// dxImg_vector.push_back(currentDx); /* create a map to record association between KeyLines and their position
// dyImg_vector.push_back(currentDy); in ScaleLines vector */
// } std::map<std::pair<int, int>, int> correspondences;
// /* prepare a structure for hosting and organizing extracted lines */ /*fill ScaleLines object */
// ScaleLines keyLines; for(size_t slCounter = 0; slCounter<keypoints.size(); slCounter++)
{
KeyPoint *kp = &(keypoints[slCounter]);
KeyLine *kl = static_cast<KeyLine*>(kp);
OctaveSingleLine osl;
osl.startPointX = (*kl).startPointX;
osl.startPointY = (*kl).startPointY;
osl.endPointX = (*kl).endPointX;
osl.endPointY = (*kl).endPointY;
osl.sPointInOctaveX = (*kl).sPointInOctaveX;
osl.sPointInOctaveY = (*kl).sPointInOctaveY;
osl.ePointInOctaveX = (*kl).ePointInOctaveX;
osl.ePointInOctaveY = (*kl).ePointInOctaveY;
osl.lineLength = (*kl).lineLength;
osl.numOfPixels = (*kl).numOfPixels;
osl.direction = (*kl).angle;
osl.octaveCount = (*kl).octave;
sl[(*kl).class_id][(*kl).octave] = osl;
/* update map */
int id = (*kl).class_id;
int oct = (*kl).octave;
correspondences.insert(std::pair<std::pair<int,int>, int>(std::pair<int,int>(id, oct), slCounter));
}
// /* extract and arrange lines */ /* delete useless OctaveSingleLines */
// OctaveKeyLines(matVec, keyLines); for(size_t i = 0; i<sl.size(); i++)
{
for(size_t j = 0; j<sl[i].size(); j++)
{
if((sl[i][j]).octaveCount == -1)
(sl[i]).erase((sl[i]).begin() + j);
}
}
// /* compute LBD descriptors */ /* compute Gaussian pyramid, if image is new or pyramid was not
// ComputeLBD_(keyLines); computed before */
BinaryDescriptor *bn = const_cast<BinaryDescriptor*>(this);
if(octaveImages.size() == 0 || cv::countNonZero(image != octaveImages[0]) != 0)
bn->computeGaussianPyramid(image);
//} /* compute Sobel's derivatives */
bn->dxImg_vector.clear();
bn->dyImg_vector.clear();
/* power function with error management */ bn->dxImg_vector.resize(params.numOfOctave_);
static inline int get2Pow(int i) { bn->dyImg_vector.resize(params.numOfOctave_);
if(i>=0 && i<=7)
return pow(2,i);
else for(size_t sobelCnt = 0; sobelCnt<octaveImages.size(); sobelCnt++)
{ {
CV_Assert(false); cv::Sobel( octaveImages[sobelCnt], bn->dxImg_vector[sobelCnt], CV_16SC1, 1, 0, 3);
return -1; cv::Sobel( octaveImages[sobelCnt], bn->dyImg_vector[sobelCnt], CV_16SC1, 0, 1, 3);
} }
}
/* conversion of an LBD descriptor to the decimal equivalent of its binary representation */ /* compute LBD descriptors */
unsigned char BinaryDescriptor::binaryTest(float* f1, float* f2) bn->computeLBD_(sl);
{ }
uchar result = 0;
for(int i = 0; i<8; i++)
{
if(f1[i]>f2[i])
result+=get2Pow(i);
}
return result;
}
/* 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(ScaleLines &keyLines) int BinaryDescriptor::OctaveKeyLines(ScaleLines &keyLines)
...@@ -710,7 +749,7 @@ int BinaryDescriptor::OctaveKeyLines(ScaleLines &keyLines) ...@@ -710,7 +749,7 @@ int BinaryDescriptor::OctaveKeyLines(ScaleLines &keyLines)
} }
/* compute LBD descriptors */ /* compute LBD descriptors */
int BinaryDescriptor::ComputeLBD_(ScaleLines &keyLines) int BinaryDescriptor::computeLBD_(ScaleLines &keyLines)
{ {
//the default length of the band is the line length. //the default length of the band is the line length.
short numOfFinalLine = keyLines.size(); short numOfFinalLine = keyLines.size();
......
...@@ -43,16 +43,17 @@ ...@@ -43,16 +43,17 @@
#define __OPENCV_PRECOMP_H__ #define __OPENCV_PRECOMP_H__
#include <algorithm> #include <algorithm>
#include "opencv2/core/utility.hpp" #include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp" #include "opencv2/core/private.hpp"
#include <opencv2/imgproc.hpp> #include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp> #include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp> #include <opencv2/highgui.hpp>
#include "opencv2/line_descriptor.hpp" #include "opencv2/line_descriptor.hpp"
#include <math.h>
#include <iostream>
#include <map>
#include <utility>
#endif #endif
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