added improved ORB implementation, convex-convex polygon intersection, eigen2x2 low-level function ...
This commit is contained in:
parent
5a702d7d9d
commit
2e9f5c434b
@ -260,7 +260,7 @@ public:
|
||||
* @param sensitivity: strenght of the sigmoide
|
||||
* @param maxOutputValue: the maximum output value
|
||||
*/
|
||||
inline void normalizeGrayOutputCentredSigmoide(const type meanValue=(type)0.0, const type sensitivity=(type)2.0, const type maxOutputValue=(type)255.0){normalizeGrayOutputCentredSigmoide(meanValue, sensitivity, 255.0, this->Buffer(), this->Buffer(), this->getNBpixels()), maxOutputValue;};
|
||||
inline void normalizeGrayOutputCentredSigmoide(const type meanValue=(type)0.0, const type sensitivity=(type)2.0, const type maxOutputValue=(type)255.0){normalizeGrayOutputCentredSigmoide(meanValue, sensitivity, 255.0, this->Buffer(), this->Buffer(), this->getNBpixels());};
|
||||
|
||||
/**
|
||||
* sigmoide image normalization function (saturates min and max values), in this function, the sigmoide is centered on low values (high saturation of the medium and high values
|
||||
|
@ -729,6 +729,8 @@ public:
|
||||
_Tp dot(const Point_& pt) const;
|
||||
//! dot product computed in double-precision arithmetics
|
||||
double ddot(const Point_& pt) const;
|
||||
//! cross-product
|
||||
double cross(const Point_& pt) const;
|
||||
//! checks whether the point is inside the specified rectangle
|
||||
bool inside(const Rect_<_Tp>& r) const;
|
||||
|
||||
@ -1274,6 +1276,7 @@ public:
|
||||
_InputArray();
|
||||
_InputArray(const Mat& m);
|
||||
_InputArray(const MatExpr& expr);
|
||||
template<typename _Tp> _InputArray(const _Tp* vec, int n);
|
||||
template<typename _Tp> _InputArray(const vector<_Tp>& vec);
|
||||
template<typename _Tp> _InputArray(const vector<vector<_Tp> >& vec);
|
||||
_InputArray(const vector<Mat>& vec);
|
||||
@ -1323,6 +1326,7 @@ public:
|
||||
template<typename _Tp> _OutputArray(vector<vector<_Tp> >& vec);
|
||||
_OutputArray(vector<Mat>& vec);
|
||||
template<typename _Tp, int m, int n> _OutputArray(Matx<_Tp, m, n>& matx);
|
||||
template<typename _Tp> _OutputArray(_Tp* vec, int n);
|
||||
virtual bool fixedSize() const;
|
||||
virtual bool fixedType() const;
|
||||
virtual bool needed() const;
|
||||
|
@ -1112,6 +1112,9 @@ template<typename _Tp> inline _InputArray::_InputArray(const vector<vector<_Tp>
|
||||
|
||||
template<typename _Tp, int m, int n> inline _InputArray::_InputArray(const Matx<_Tp, m, n>& mtx)
|
||||
: flags(MATX + DataType<_Tp>::type), obj((void*)&mtx), sz(n, m) {}
|
||||
|
||||
template<typename _Tp> inline _InputArray::_InputArray(const _Tp* vec, int n)
|
||||
: flags(MATX + DataType<_Tp>::type), obj((void*)vec), sz(n, 1) {}
|
||||
|
||||
inline _InputArray::_InputArray(const Scalar& s)
|
||||
: flags(MATX + CV_64F), obj((void*)&s), sz(1, 4) {}
|
||||
@ -1119,6 +1122,7 @@ inline _InputArray::_InputArray(const Scalar& s)
|
||||
template<typename _Tp> inline _OutputArray::_OutputArray(vector<_Tp>& vec) : _InputArray(vec) {}
|
||||
template<typename _Tp> inline _OutputArray::_OutputArray(vector<vector<_Tp> >& vec) : _InputArray(vec) {}
|
||||
template<typename _Tp, int m, int n> inline _OutputArray::_OutputArray(Matx<_Tp, m, n>& mtx) : _InputArray(mtx) {}
|
||||
template<typename _Tp> inline _OutputArray::_OutputArray(_Tp* vec, int n) : _InputArray(vec, n) {}
|
||||
|
||||
//////////////////////////////////// Matrix Expressions /////////////////////////////////////////
|
||||
|
||||
|
@ -1599,6 +1599,9 @@ template<typename _Tp> inline _Tp Point_<_Tp>::dot(const Point_& pt) const
|
||||
template<typename _Tp> inline double Point_<_Tp>::ddot(const Point_& pt) const
|
||||
{ return (double)x*pt.x + (double)y*pt.y; }
|
||||
|
||||
template<typename _Tp> inline double Point_<_Tp>::cross(const Point_& pt) const
|
||||
{ return (double)x*pt.y - (double)y*pt.x; }
|
||||
|
||||
template<typename _Tp> static inline Point_<_Tp>&
|
||||
operator += (Point_<_Tp>& a, const Point_<_Tp>& b)
|
||||
{
|
||||
|
@ -2050,7 +2050,9 @@ void cv::polylines(InputOutputArray _img, InputArrayOfArrays pts,
|
||||
int thickness, int lineType, int shift )
|
||||
{
|
||||
Mat img = _img.getMat();
|
||||
int i, ncontours = (int)pts.total();
|
||||
bool manyContours = pts.kind() == _InputArray::STD_VECTOR_VECTOR ||
|
||||
pts.kind() == _InputArray::STD_VECTOR_MAT;
|
||||
int i, ncontours = manyContours ? (int)pts.total() : 1;
|
||||
if( ncontours == 0 )
|
||||
return;
|
||||
AutoBuffer<Point*> _ptsptr(ncontours);
|
||||
@ -2060,7 +2062,9 @@ void cv::polylines(InputOutputArray _img, InputArrayOfArrays pts,
|
||||
|
||||
for( i = 0; i < ncontours; i++ )
|
||||
{
|
||||
Mat p = pts.getMat(i);
|
||||
Mat p = pts.getMat(manyContours ? i : -1);
|
||||
if( p.total() == 0 )
|
||||
continue;
|
||||
CV_Assert(p.checkVector(2, CV_32S) >= 0);
|
||||
ptsptr[i] = (Point*)p.data;
|
||||
npts[i] = p.rows*p.cols*p.channels()/2;
|
||||
|
@ -422,16 +422,15 @@ public:
|
||||
|
||||
struct CV_EXPORTS CommonParams
|
||||
{
|
||||
enum { DEFAULT_N_LEVELS = 3, DEFAULT_FIRST_LEVEL = 0};
|
||||
enum { DEFAULT_N_LEVELS = 3, DEFAULT_FIRST_LEVEL = 0, HARRIS_SCORE=0, FAST_SCORE=1 };
|
||||
|
||||
/** default constructor */
|
||||
CommonParams(float scale_factor = 1.2f, unsigned n_levels = DEFAULT_N_LEVELS, int edge_threshold = 31,
|
||||
unsigned first_level = DEFAULT_FIRST_LEVEL) :
|
||||
unsigned first_level = DEFAULT_FIRST_LEVEL, int WTA_K=2, int score_type=HARRIS_SCORE) :
|
||||
scale_factor_(scale_factor), n_levels_(n_levels), first_level_(first_level >= n_levels ? 0 : first_level),
|
||||
edge_threshold_(edge_threshold)
|
||||
edge_threshold_(edge_threshold), WTA_K_(WTA_K), score_type_(score_type)
|
||||
{
|
||||
// No other patch size is supported right now
|
||||
patch_size_ = 31;
|
||||
patch_size_ = 31;
|
||||
}
|
||||
void read(const FileNode& fn);
|
||||
void write(FileStorage& fs) const;
|
||||
@ -444,12 +443,16 @@ public:
|
||||
* if 1, that means we will also look at the image scale_factor_ times bigger
|
||||
*/
|
||||
unsigned first_level_;
|
||||
/** How far from the boundary the points should be */
|
||||
/** How far from the boundary the points should be. */
|
||||
int edge_threshold_;
|
||||
|
||||
/** How many random points are used to produce each cell of the descriptor (2, 3, 4 ...) */
|
||||
int WTA_K_;
|
||||
|
||||
/** Type of the score to use (FAST, HARRIS, ...) */
|
||||
int score_type_;
|
||||
|
||||
friend class ORB;
|
||||
protected:
|
||||
/** The size of the patch that will be used for orientation and comparisons */
|
||||
/** The size of the patch that will be used for orientation and comparisons (only 31 is supported)*/
|
||||
int patch_size_;
|
||||
};
|
||||
|
||||
@ -483,8 +486,12 @@ public:
|
||||
void
|
||||
operator()(const cv::Mat &image, const cv::Mat &mask, std::vector<cv::KeyPoint> & keypoints, cv::Mat & descriptors,
|
||||
bool useProvidedKeypoints = false);
|
||||
|
||||
|
||||
void read(const FileNode& fn);
|
||||
void write(FileStorage& fs) const;
|
||||
|
||||
private:
|
||||
|
||||
/** The size of the patch used when comparing regions in the patterns */
|
||||
static const int kKernelWidth = 5;
|
||||
|
||||
@ -539,28 +546,20 @@ private:
|
||||
/** Parameters tuning ORB */
|
||||
CommonParams params_;
|
||||
|
||||
/** size of the half patch used for orientation computation, see Rosin - 1999 - Measuring Corner Properties */
|
||||
int half_patch_size_;
|
||||
|
||||
/** pre-computed offsets used for the Harris verification, one vector per scale */
|
||||
std::vector<std::vector<int> > orientation_horizontal_offsets_;
|
||||
std::vector<std::vector<int> > orientation_vertical_offsets_;
|
||||
|
||||
/** The steps of the integral images for each scale */
|
||||
std::vector<size_t> integral_image_steps_;
|
||||
vector<size_t> integral_image_steps_;
|
||||
|
||||
/** The number of desired features per scale */
|
||||
std::vector<size_t> n_features_per_level_;
|
||||
vector<size_t> n_features_per_level_;
|
||||
|
||||
/** The overall number of desired features */
|
||||
size_t n_features_;
|
||||
|
||||
/** the end of a row in a circular patch */
|
||||
std::vector<int> u_max_;
|
||||
|
||||
/** The patterns for each level (the patterns are the same, but not their offset */
|
||||
class OrbPatterns;
|
||||
std::vector<OrbPatterns*> patterns_;
|
||||
|
||||
/** The circular region to compute a feature orientation */
|
||||
vector<int> u_max_;
|
||||
|
||||
/** Points to compute BRIEF descriptors from */
|
||||
vector<Point> pattern;
|
||||
};
|
||||
|
||||
/*!
|
||||
@ -1551,10 +1550,6 @@ protected:
|
||||
private:
|
||||
/** the ORB object we use for the computations */
|
||||
mutable ORB orb_;
|
||||
/** The parameters used */
|
||||
ORB::CommonParams params_;
|
||||
/** the number of features that need to be retrieved */
|
||||
unsigned n_features_;
|
||||
};
|
||||
|
||||
class CV_EXPORTS SimpleBlobDetector : public cv::FeatureDetector
|
||||
@ -1953,8 +1948,6 @@ protected:
|
||||
private:
|
||||
/** the ORB object we use for the computations */
|
||||
mutable ORB orb_;
|
||||
/** The parameters used */
|
||||
ORB::CommonParams params_;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -2157,6 +2150,17 @@ struct CV_EXPORTS Hamming
|
||||
|
||||
typedef Hamming HammingLUT;
|
||||
|
||||
template<int cellsize> struct CV_EXPORTS HammingMultilevel
|
||||
{
|
||||
typedef unsigned char ValueType;
|
||||
typedef int ResultType;
|
||||
|
||||
ResultType operator()( const unsigned char* a, const unsigned char* b, int size ) const
|
||||
{
|
||||
return normHamming(a, b, size, cellsize);
|
||||
}
|
||||
};
|
||||
|
||||
/****************************************************************************************\
|
||||
* DMatch *
|
||||
\****************************************************************************************/
|
||||
|
@ -63,7 +63,6 @@ void DescriptorExtractor::compute( const Mat& image, vector<KeyPoint>& keypoints
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
KeyPointsFilter::runByImageBorder( keypoints, image.size(), 0 );
|
||||
KeyPointsFilter::runByKeypointSize( keypoints, std::numeric_limits<float>::epsilon() );
|
||||
|
||||
@ -247,8 +246,7 @@ int SurfDescriptorExtractor::descriptorType() const
|
||||
|
||||
|
||||
/** Default constructor */
|
||||
OrbDescriptorExtractor::OrbDescriptorExtractor(ORB::CommonParams params) :
|
||||
params_(params)
|
||||
OrbDescriptorExtractor::OrbDescriptorExtractor(ORB::CommonParams params)
|
||||
{
|
||||
orb_ = ORB(0, params);
|
||||
}
|
||||
@ -260,16 +258,15 @@ void OrbDescriptorExtractor::computeImpl(const cv::Mat& image, std::vector<cv::K
|
||||
}
|
||||
void OrbDescriptorExtractor::read(const cv::FileNode& fn)
|
||||
{
|
||||
params_.read(fn);
|
||||
orb_ = ORB(0, params_);
|
||||
orb_.read(fn);
|
||||
}
|
||||
void OrbDescriptorExtractor::write(cv::FileStorage& fs) const
|
||||
{
|
||||
params_.write(fs);
|
||||
orb_.write(fs);
|
||||
}
|
||||
int OrbDescriptorExtractor::descriptorSize() const
|
||||
{
|
||||
return ORB::kBytes;
|
||||
return orb_.descriptorSize();
|
||||
}
|
||||
int OrbDescriptorExtractor::descriptorType() const
|
||||
{
|
||||
|
@ -449,43 +449,22 @@ void SurfFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoi
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ORB::CommonParams::read(const FileNode& fn)
|
||||
{
|
||||
scale_factor_ = fn["scaleFactor"];
|
||||
n_levels_ = int(fn["nLevels"]);
|
||||
first_level_ = int(fn["firstLevel"]);
|
||||
edge_threshold_ = fn["edgeThreshold"];
|
||||
patch_size_ = fn["patchSize"];
|
||||
}
|
||||
|
||||
void ORB::CommonParams::write(FileStorage& fs) const
|
||||
{
|
||||
fs << "scaleFactor" << scale_factor_;
|
||||
fs << "nLevels" << int(n_levels_);
|
||||
fs << "firstLevel" << int(first_level_);
|
||||
fs << "edgeThreshold" << int(edge_threshold_);
|
||||
fs << "patchSize" << int(patch_size_);
|
||||
}
|
||||
|
||||
/** Default constructor
|
||||
* @param n_features the number of desired features
|
||||
*/
|
||||
OrbFeatureDetector::OrbFeatureDetector(size_t n_features, ORB::CommonParams params) :
|
||||
params_(params)
|
||||
OrbFeatureDetector::OrbFeatureDetector(size_t n_features, ORB::CommonParams params)
|
||||
{
|
||||
orb_ = ORB(n_features, params);
|
||||
}
|
||||
|
||||
void OrbFeatureDetector::read(const FileNode& fn)
|
||||
{
|
||||
params_.read(fn);
|
||||
n_features_ = int(fn["nFeatures"]);
|
||||
orb_.read(fn);
|
||||
}
|
||||
|
||||
void OrbFeatureDetector::write(FileStorage& fs) const
|
||||
{
|
||||
params_.write(fs);
|
||||
fs << "nFeatures" << int(n_features_);
|
||||
orb_.write(fs);
|
||||
}
|
||||
|
||||
void OrbFeatureDetector::detectImpl(const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask) const
|
||||
|
@ -138,6 +138,7 @@ static void _prepareImgAndDrawKeypoints( const Mat& img1, const vector<KeyPoint>
|
||||
else
|
||||
{
|
||||
outImg.create( size, CV_MAKETYPE(img1.depth(), 3) );
|
||||
outImg = Scalar::all(0);
|
||||
outImg1 = outImg( Rect(0, 0, img1.cols, img1.rows) );
|
||||
outImg2 = outImg( Rect(img1.cols, 0, img2.cols, img2.rows) );
|
||||
|
||||
|
@ -46,6 +46,39 @@
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
template<typename _Tp> static int solveQuadratic(_Tp a, _Tp b, _Tp c, _Tp& x1, _Tp& x2)
|
||||
{
|
||||
if( a == 0 )
|
||||
{
|
||||
if( b == 0 )
|
||||
{
|
||||
x1 = x2 = 0;
|
||||
return c == 0;
|
||||
}
|
||||
x1 = x2 = -c/b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
_Tp d = b*b - 4*a*c;
|
||||
if( d < 0 )
|
||||
{
|
||||
x1 = x2 = 0;
|
||||
return 0;
|
||||
}
|
||||
if( d > 0 )
|
||||
{
|
||||
d = std::sqrt(d);
|
||||
double s = 1/(2*a);
|
||||
x1 = (-b - d)*s;
|
||||
x2 = (-b + d)*s;
|
||||
if( x1 > x2 )
|
||||
std::swap(x1, x2);
|
||||
return 2;
|
||||
}
|
||||
x1 = x2 = -b/(2*a);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//for android ndk
|
||||
#undef _S
|
||||
static inline Point2f applyHomography( const Mat_<double>& H, const Point2f& pt )
|
||||
@ -109,13 +142,13 @@ EllipticKeyPoint::EllipticKeyPoint( const Point2f& _center, const Scalar& _ellip
|
||||
center = _center;
|
||||
ellipse = _ellipse;
|
||||
|
||||
Mat_<double> M = getSecondMomentsMatrix(_ellipse), eval;
|
||||
eigen( M, eval );
|
||||
assert( eval.rows == 2 && eval.cols == 1 );
|
||||
axes.width = 1.f / (float)sqrt(eval(0,0));
|
||||
axes.height = 1.f / (float)sqrt(eval(1,0));
|
||||
|
||||
double ac_b2 = ellipse[0]*ellipse[2] - ellipse[1]*ellipse[1];
|
||||
double a = ellipse[0], b = ellipse[1], c = ellipse[2];
|
||||
double ac_b2 = a*c - b*b;
|
||||
double x1, x2;
|
||||
solveQuadratic(1., -(a+c), ac_b2, x1, x2);
|
||||
axes.width = (float)(1/sqrt(x1));
|
||||
axes.height = (float)(1/sqrt(x2));
|
||||
|
||||
boundingBox.width = (float)sqrt(ellipse[2]/ac_b2);
|
||||
boundingBox.height = (float)sqrt(ellipse[0]/ac_b2);
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ void cv::FAST(const Mat& img, std::vector<KeyPoint>& keypoints, int threshold, b
|
||||
score > pprev[j-1] && score > pprev[j] && score > pprev[j+1] &&
|
||||
score > curr[j-1] && score > curr[j] && score > curr[j+1]) )
|
||||
{
|
||||
keypoints.push_back(KeyPoint((float)j, (float)(i-1), 6.f, -1, (float)score));
|
||||
keypoints.push_back(KeyPoint((float)j, (float)(i-1), 7.f, -1, (float)score));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -340,10 +340,20 @@ Ptr<DescriptorMatcher> DescriptorMatcher::create( const string& descriptorMatche
|
||||
{
|
||||
dm = new BruteForceMatcher<Hamming>();
|
||||
}
|
||||
else if( !descriptorMatcherType.compare( "BruteForce-HammingLUT") )
|
||||
else if( !descriptorMatcherType.compare("BruteForce-HammingLUT") )
|
||||
{
|
||||
dm = new BruteForceMatcher<Hamming>();
|
||||
}
|
||||
else if( !descriptorMatcherType.compare("BruteForce-Hamming(2)") )
|
||||
{
|
||||
dm = new BruteForceMatcher<HammingMultilevel<2> >();
|
||||
}
|
||||
else if( !descriptorMatcherType.compare("BruteForce-Hamming(4)") )
|
||||
{
|
||||
dm = new BruteForceMatcher<HammingMultilevel<4> >();
|
||||
}
|
||||
else
|
||||
CV_Error( CV_StsBadArg, "Unknown matcher name" );
|
||||
|
||||
return dm;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,259 +0,0 @@
|
||||
//x1,y1,x2,y2
|
||||
int ORB::OrbPatterns::bit_pattern_31_[256*4] ={
|
||||
8,-3, 9,5/*mean (0), correlation (0)*/,
|
||||
4,2, 7,-12/*mean (1.12461e-05), correlation (0.0437584)*/,
|
||||
-11,9, -8,2/*mean (3.37382e-05), correlation (0.0617409)*/,
|
||||
7,-12, 12,-13/*mean (5.62303e-05), correlation (0.0636977)*/,
|
||||
2,-13, 2,12/*mean (0.000134953), correlation (0.085099)*/,
|
||||
1,-7, 1,6/*mean (0.000528565), correlation (0.0857175)*/,
|
||||
-2,-10, -2,-4/*mean (0.0188821), correlation (0.0985774)*/,
|
||||
-13,-13, -11,-8/*mean (0.0363135), correlation (0.0899616)*/,
|
||||
-13,-3, -12,-9/*mean (0.121806), correlation (0.099849)*/,
|
||||
10,4, 11,9/*mean (0.122065), correlation (0.093285)*/,
|
||||
-13,-8, -8,-9/*mean (0.162787), correlation (0.0942748)*/,
|
||||
-11,7, -9,12/*mean (0.21561), correlation (0.0974438)*/,
|
||||
7,7, 12,6/*mean (0.160583), correlation (0.130064)*/,
|
||||
-4,-5, -3,0/*mean (0.228171), correlation (0.132998)*/,
|
||||
-13,2, -12,-3/*mean (0.00997526), correlation (0.145926)*/,
|
||||
-9,0, -7,5/*mean (0.198234), correlation (0.143636)*/,
|
||||
12,-6, 12,-1/*mean (0.0676226), correlation (0.16689)*/,
|
||||
-3,6, -2,12/*mean (0.166847), correlation (0.171682)*/,
|
||||
-6,-13, -4,-8/*mean (0.101215), correlation (0.179716)*/,
|
||||
11,-13, 12,-8/*mean (0.200641), correlation (0.192279)*/,
|
||||
4,7, 5,1/*mean (0.205106), correlation (0.186848)*/,
|
||||
5,-3, 10,-3/*mean (0.234908), correlation (0.192319)*/,
|
||||
3,-7, 6,12/*mean (0.0709964), correlation (0.210872)*/,
|
||||
-8,-7, -6,-2/*mean (0.0939834), correlation (0.212589)*/,
|
||||
-2,11, -1,-10/*mean (0.127778), correlation (0.20866)*/,
|
||||
-13,12, -8,10/*mean (0.14783), correlation (0.206356)*/,
|
||||
-7,3, -5,-3/*mean (0.182141), correlation (0.198942)*/,
|
||||
-4,2, -3,7/*mean (0.188237), correlation (0.21384)*/,
|
||||
-10,-12, -6,11/*mean (0.14865), correlation (0.23571)*/,
|
||||
5,-12, 6,-7/*mean (0.222312), correlation (0.23324)*/,
|
||||
5,-6, 7,-1/*mean (0.229082), correlation (0.23389)*/,
|
||||
1,0, 4,-5/*mean (0.241577), correlation (0.215286)*/,
|
||||
9,11, 11,-13/*mean (0.00338507), correlation (0.251373)*/,
|
||||
4,7, 4,12/*mean (0.131005), correlation (0.257622)*/,
|
||||
2,-1, 4,4/*mean (0.152755), correlation (0.255205)*/,
|
||||
-4,-12, -2,7/*mean (0.182771), correlation (0.244867)*/,
|
||||
-8,-5, -7,-10/*mean (0.186898), correlation (0.23901)*/,
|
||||
4,11, 9,12/*mean (0.226226), correlation (0.258255)*/,
|
||||
0,-8, 1,-13/*mean (0.0897886), correlation (0.274827)*/,
|
||||
-13,-2, -8,2/*mean (0.148774), correlation (0.28065)*/,
|
||||
-3,-2, -2,3/*mean (0.153048), correlation (0.283063)*/,
|
||||
-6,9, -4,-9/*mean (0.169523), correlation (0.278248)*/,
|
||||
8,12, 10,7/*mean (0.225337), correlation (0.282851)*/,
|
||||
0,9, 1,3/*mean (0.226687), correlation (0.278734)*/,
|
||||
7,-5, 11,-10/*mean (0.00693882), correlation (0.305161)*/,
|
||||
-13,-6, -11,0/*mean (0.0227283), correlation (0.300181)*/,
|
||||
10,7, 12,1/*mean (0.125517), correlation (0.31089)*/,
|
||||
-6,-3, -6,12/*mean (0.131748), correlation (0.312779)*/,
|
||||
10,-9, 12,-4/*mean (0.144827), correlation (0.292797)*/,
|
||||
-13,8, -8,-12/*mean (0.149202), correlation (0.308918)*/,
|
||||
-13,0, -8,-4/*mean (0.160909), correlation (0.310013)*/,
|
||||
3,3, 7,8/*mean (0.177755), correlation (0.309394)*/,
|
||||
5,7, 10,-7/*mean (0.212337), correlation (0.310315)*/,
|
||||
-1,7, 1,-12/*mean (0.214429), correlation (0.311933)*/,
|
||||
3,-10, 5,6/*mean (0.235807), correlation (0.313104)*/,
|
||||
2,-4, 3,-10/*mean (0.00494827), correlation (0.344948)*/,
|
||||
-13,0, -13,5/*mean (0.0549145), correlation (0.344675)*/,
|
||||
-13,-7, -12,12/*mean (0.103385), correlation (0.342715)*/,
|
||||
-13,3, -11,8/*mean (0.134222), correlation (0.322922)*/,
|
||||
-7,12, -4,7/*mean (0.153284), correlation (0.337061)*/,
|
||||
6,-10, 12,8/*mean (0.154881), correlation (0.329257)*/,
|
||||
-9,-1, -7,-6/*mean (0.200967), correlation (0.33312)*/,
|
||||
-2,-5, 0,12/*mean (0.201518), correlation (0.340635)*/,
|
||||
-12,5, -7,5/*mean (0.207805), correlation (0.335631)*/,
|
||||
3,-10, 8,-13/*mean (0.224438), correlation (0.34504)*/,
|
||||
-7,-7, -4,5/*mean (0.239361), correlation (0.338053)*/,
|
||||
-3,-2, -1,-7/*mean (0.240744), correlation (0.344322)*/,
|
||||
2,9, 5,-11/*mean (0.242949), correlation (0.34145)*/,
|
||||
-11,-13, -5,-13/*mean (0.244028), correlation (0.336861)*/,
|
||||
-1,6, 0,-1/*mean (0.247571), correlation (0.343684)*/,
|
||||
5,-3, 5,2/*mean (0.000697256), correlation (0.357265)*/,
|
||||
-4,-13, -4,12/*mean (0.00213675), correlation (0.373827)*/,
|
||||
-9,-6, -9,6/*mean (0.0126856), correlation (0.373938)*/,
|
||||
-12,-10, -8,-4/*mean (0.0152497), correlation (0.364237)*/,
|
||||
10,2, 12,-3/*mean (0.0299933), correlation (0.345292)*/,
|
||||
7,12, 12,12/*mean (0.0307242), correlation (0.366299)*/,
|
||||
-7,-13, -6,5/*mean (0.0534975), correlation (0.368357)*/,
|
||||
-4,9, -3,4/*mean (0.099865), correlation (0.372276)*/,
|
||||
7,-1, 12,2/*mean (0.117083), correlation (0.364529)*/,
|
||||
-7,6, -5,1/*mean (0.126125), correlation (0.369606)*/,
|
||||
-13,11, -12,5/*mean (0.130364), correlation (0.358502)*/,
|
||||
-3,7, -2,-6/*mean (0.131691), correlation (0.375531)*/,
|
||||
7,-8, 12,-7/*mean (0.160166), correlation (0.379508)*/,
|
||||
-13,-7, -11,-12/*mean (0.167848), correlation (0.353343)*/,
|
||||
1,-3, 12,12/*mean (0.183378), correlation (0.371916)*/,
|
||||
2,-6, 3,0/*mean (0.228711), correlation (0.371761)*/,
|
||||
-4,3, -2,-13/*mean (0.247211), correlation (0.364063)*/,
|
||||
-1,-13, 1,9/*mean (0.249325), correlation (0.378139)*/,
|
||||
7,1, 8,-6/*mean (0.000652272), correlation (0.411682)*/,
|
||||
1,-1, 3,12/*mean (0.00248538), correlation (0.392988)*/,
|
||||
9,1, 12,6/*mean (0.0206815), correlation (0.386106)*/,
|
||||
-1,-9, -1,3/*mean (0.0364485), correlation (0.410752)*/,
|
||||
-13,-13, -10,5/*mean (0.0376068), correlation (0.398374)*/,
|
||||
7,7, 10,12/*mean (0.0424202), correlation (0.405663)*/,
|
||||
12,-5, 12,9/*mean (0.0942645), correlation (0.410422)*/,
|
||||
6,3, 7,11/*mean (0.1074), correlation (0.413224)*/,
|
||||
5,-13, 6,10/*mean (0.109256), correlation (0.408646)*/,
|
||||
2,-12, 2,3/*mean (0.131691), correlation (0.416076)*/,
|
||||
3,8, 4,-6/*mean (0.165081), correlation (0.417569)*/,
|
||||
2,6, 12,-13/*mean (0.171874), correlation (0.408471)*/,
|
||||
9,-12, 10,3/*mean (0.175146), correlation (0.41296)*/,
|
||||
-8,4, -7,9/*mean (0.183682), correlation (0.402956)*/,
|
||||
-11,12, -4,-6/*mean (0.184672), correlation (0.416125)*/,
|
||||
1,12, 2,-8/*mean (0.191487), correlation (0.386696)*/,
|
||||
6,-9, 7,-4/*mean (0.192668), correlation (0.394771)*/,
|
||||
2,3, 3,-2/*mean (0.200157), correlation (0.408303)*/,
|
||||
6,3, 11,0/*mean (0.204588), correlation (0.411762)*/,
|
||||
3,-3, 8,-8/*mean (0.205904), correlation (0.416294)*/,
|
||||
7,8, 9,3/*mean (0.213237), correlation (0.409306)*/,
|
||||
-11,-5, -6,-4/*mean (0.243444), correlation (0.395069)*/,
|
||||
-10,11, -5,10/*mean (0.247672), correlation (0.413392)*/,
|
||||
-5,-8, -3,12/*mean (0.24774), correlation (0.411416)*/,
|
||||
-10,5, -9,0/*mean (0.00213675), correlation (0.454003)*/,
|
||||
8,-1, 12,-6/*mean (0.0293635), correlation (0.455368)*/,
|
||||
4,-6, 6,-11/*mean (0.0404971), correlation (0.457393)*/,
|
||||
-10,12, -8,7/*mean (0.0481107), correlation (0.448364)*/,
|
||||
4,-2, 6,7/*mean (0.050641), correlation (0.455019)*/,
|
||||
-2,0, -2,12/*mean (0.0525978), correlation (0.44338)*/,
|
||||
-5,-8, -5,2/*mean (0.0629667), correlation (0.457096)*/,
|
||||
7,-6, 10,12/*mean (0.0653846), correlation (0.445623)*/,
|
||||
-9,-13, -8,-8/*mean (0.0858749), correlation (0.449789)*/,
|
||||
-5,-13, -5,-2/*mean (0.122402), correlation (0.450201)*/,
|
||||
8,-8, 9,-13/*mean (0.125416), correlation (0.453224)*/,
|
||||
-9,-11, -9,0/*mean (0.130128), correlation (0.458724)*/,
|
||||
1,-8, 1,-2/*mean (0.132467), correlation (0.440133)*/,
|
||||
7,-4, 9,1/*mean (0.132692), correlation (0.454)*/,
|
||||
-2,1, -1,-4/*mean (0.135695), correlation (0.455739)*/,
|
||||
11,-6, 12,-11/*mean (0.142904), correlation (0.446114)*/,
|
||||
-12,-9, -6,4/*mean (0.146165), correlation (0.451473)*/,
|
||||
3,7, 7,12/*mean (0.147627), correlation (0.456643)*/,
|
||||
5,5, 10,8/*mean (0.152901), correlation (0.455036)*/,
|
||||
0,-4, 2,8/*mean (0.167083), correlation (0.459315)*/,
|
||||
-9,12, -5,-13/*mean (0.173234), correlation (0.454706)*/,
|
||||
0,7, 2,12/*mean (0.18312), correlation (0.433855)*/,
|
||||
-1,2, 1,7/*mean (0.185504), correlation (0.443838)*/,
|
||||
5,11, 7,-9/*mean (0.185706), correlation (0.451123)*/,
|
||||
3,5, 6,-8/*mean (0.188968), correlation (0.455808)*/,
|
||||
-13,-4, -8,9/*mean (0.191667), correlation (0.459128)*/,
|
||||
-5,9, -3,-3/*mean (0.193196), correlation (0.458364)*/,
|
||||
-4,-7, -3,-12/*mean (0.196536), correlation (0.455782)*/,
|
||||
6,5, 8,0/*mean (0.1972), correlation (0.450481)*/,
|
||||
-7,6, -6,12/*mean (0.199438), correlation (0.458156)*/,
|
||||
-13,6, -5,-2/*mean (0.211224), correlation (0.449548)*/,
|
||||
1,-10, 3,10/*mean (0.211718), correlation (0.440606)*/,
|
||||
4,1, 8,-4/*mean (0.213034), correlation (0.443177)*/,
|
||||
-2,-2, 2,-13/*mean (0.234334), correlation (0.455304)*/,
|
||||
2,-12, 12,12/*mean (0.235684), correlation (0.443436)*/,
|
||||
-2,-13, 0,-6/*mean (0.237674), correlation (0.452525)*/,
|
||||
4,1, 9,3/*mean (0.23962), correlation (0.444824)*/,
|
||||
-6,-10, -3,-5/*mean (0.248459), correlation (0.439621)*/,
|
||||
-3,-13, -1,1/*mean (0.249505), correlation (0.456666)*/,
|
||||
7,5, 12,-11/*mean (0.00119208), correlation (0.495466)*/,
|
||||
4,-2, 5,-7/*mean (0.00372245), correlation (0.484214)*/,
|
||||
-13,9, -9,-5/*mean (0.00741116), correlation (0.499854)*/,
|
||||
7,1, 8,6/*mean (0.0208952), correlation (0.499773)*/,
|
||||
7,-8, 7,6/*mean (0.0220085), correlation (0.501609)*/,
|
||||
-7,-4, -7,1/*mean (0.0233806), correlation (0.496568)*/,
|
||||
-8,11, -7,-8/*mean (0.0236505), correlation (0.489719)*/,
|
||||
-13,6, -12,-8/*mean (0.0268781), correlation (0.503487)*/,
|
||||
2,4, 3,9/*mean (0.0323324), correlation (0.501938)*/,
|
||||
10,-5, 12,3/*mean (0.0399235), correlation (0.494029)*/,
|
||||
-6,-5, -6,7/*mean (0.0420153), correlation (0.486579)*/,
|
||||
8,-3, 9,-8/*mean (0.0548021), correlation (0.484237)*/,
|
||||
2,-12, 2,8/*mean (0.0616622), correlation (0.496642)*/,
|
||||
-11,-2, -10,3/*mean (0.0627755), correlation (0.498563)*/,
|
||||
-12,-13, -7,-9/*mean (0.0829622), correlation (0.495491)*/,
|
||||
-11,0, -10,-5/*mean (0.0843342), correlation (0.487146)*/,
|
||||
5,-3, 11,8/*mean (0.0929937), correlation (0.502315)*/,
|
||||
-2,-13, -1,12/*mean (0.113327), correlation (0.48941)*/,
|
||||
-1,-8, 0,9/*mean (0.132119), correlation (0.467268)*/,
|
||||
-13,-11, -12,-5/*mean (0.136269), correlation (0.498771)*/,
|
||||
-10,-2, -10,11/*mean (0.142173), correlation (0.498714)*/,
|
||||
-3,9, -2,-13/*mean (0.144141), correlation (0.491973)*/,
|
||||
2,-3, 3,2/*mean (0.14892), correlation (0.500782)*/,
|
||||
-9,-13, -4,0/*mean (0.150371), correlation (0.498211)*/,
|
||||
-4,6, -3,-10/*mean (0.152159), correlation (0.495547)*/,
|
||||
-4,12, -2,-7/*mean (0.156152), correlation (0.496925)*/,
|
||||
-6,-11, -4,9/*mean (0.15749), correlation (0.499222)*/,
|
||||
6,-3, 6,11/*mean (0.159211), correlation (0.503821)*/,
|
||||
-13,11, -5,5/*mean (0.162427), correlation (0.501907)*/,
|
||||
11,11, 12,6/*mean (0.16652), correlation (0.497632)*/,
|
||||
7,-5, 12,-2/*mean (0.169141), correlation (0.484474)*/,
|
||||
-1,12, 0,7/*mean (0.169456), correlation (0.495339)*/,
|
||||
-4,-8, -3,-2/*mean (0.171457), correlation (0.487251)*/,
|
||||
-7,1, -6,7/*mean (0.175), correlation (0.500024)*/,
|
||||
-13,-12, -8,-13/*mean (0.175866), correlation (0.497523)*/,
|
||||
-7,-2, -6,-8/*mean (0.178273), correlation (0.501854)*/,
|
||||
-8,5, -6,-9/*mean (0.181107), correlation (0.494888)*/,
|
||||
-5,-1, -4,5/*mean (0.190227), correlation (0.482557)*/,
|
||||
-13,7, -8,10/*mean (0.196739), correlation (0.496503)*/,
|
||||
1,5, 5,-13/*mean (0.19973), correlation (0.499759)*/,
|
||||
1,0, 10,-13/*mean (0.204465), correlation (0.49873)*/,
|
||||
9,12, 10,-1/*mean (0.209334), correlation (0.49063)*/,
|
||||
5,-8, 10,-9/*mean (0.211134), correlation (0.503011)*/,
|
||||
-1,11, 1,-13/*mean (0.212), correlation (0.499414)*/,
|
||||
-9,-3, -6,2/*mean (0.212168), correlation (0.480739)*/,
|
||||
-1,-10, 1,12/*mean (0.212731), correlation (0.502523)*/,
|
||||
-13,1, -8,-10/*mean (0.21327), correlation (0.489786)*/,
|
||||
8,-11, 10,-6/*mean (0.214159), correlation (0.488246)*/,
|
||||
2,-13, 3,-6/*mean (0.216993), correlation (0.50287)*/,
|
||||
7,-13, 12,-9/*mean (0.223639), correlation (0.470502)*/,
|
||||
-10,-10, -5,-7/*mean (0.224089), correlation (0.500852)*/,
|
||||
-10,-8, -8,-13/*mean (0.228666), correlation (0.502629)*/,
|
||||
4,-6, 8,5/*mean (0.22906), correlation (0.498305)*/,
|
||||
3,12, 8,-13/*mean (0.233378), correlation (0.503825)*/,
|
||||
-4,2, -3,-3/*mean (0.234323), correlation (0.476692)*/,
|
||||
5,-13, 10,-12/*mean (0.236392), correlation (0.475462)*/,
|
||||
4,-13, 5,-1/*mean (0.236842), correlation (0.504132)*/,
|
||||
-9,9, -4,3/*mean (0.236977), correlation (0.497739)*/,
|
||||
0,3, 3,-9/*mean (0.24314), correlation (0.499398)*/,
|
||||
-12,1, -6,1/*mean (0.243297), correlation (0.489447)*/,
|
||||
3,2, 4,-8/*mean (0.00155196), correlation (0.553496)*/,
|
||||
-10,-10, -10,9/*mean (0.00239541), correlation (0.54297)*/,
|
||||
8,-13, 12,12/*mean (0.0034413), correlation (0.544361)*/,
|
||||
-8,-12, -6,-5/*mean (0.003565), correlation (0.551225)*/,
|
||||
2,2, 3,7/*mean (0.00835583), correlation (0.55285)*/,
|
||||
10,6, 11,-8/*mean (0.00885065), correlation (0.540913)*/,
|
||||
6,8, 8,-12/*mean (0.0101552), correlation (0.551085)*/,
|
||||
-7,10, -6,5/*mean (0.0102227), correlation (0.533635)*/,
|
||||
-3,-9, -3,9/*mean (0.0110211), correlation (0.543121)*/,
|
||||
-1,-13, -1,5/*mean (0.0113473), correlation (0.550173)*/,
|
||||
-3,-7, -3,4/*mean (0.0140913), correlation (0.554774)*/,
|
||||
-8,-2, -8,3/*mean (0.017049), correlation (0.55461)*/,
|
||||
4,2, 12,12/*mean (0.01778), correlation (0.546921)*/,
|
||||
2,-5, 3,11/*mean (0.0224022), correlation (0.549667)*/,
|
||||
6,-9, 11,-13/*mean (0.029161), correlation (0.546295)*/,
|
||||
3,-1, 7,12/*mean (0.0303081), correlation (0.548599)*/,
|
||||
11,-1, 12,4/*mean (0.0355151), correlation (0.523943)*/,
|
||||
-3,0, -3,6/*mean (0.0417904), correlation (0.543395)*/,
|
||||
4,-11, 4,12/*mean (0.0487292), correlation (0.542818)*/,
|
||||
2,-4, 2,1/*mean (0.0575124), correlation (0.554888)*/,
|
||||
-10,-6, -8,1/*mean (0.0594242), correlation (0.544026)*/,
|
||||
-13,7, -11,1/*mean (0.0597391), correlation (0.550524)*/,
|
||||
-13,12, -11,-13/*mean (0.0608974), correlation (0.55383)*/,
|
||||
6,0, 11,-13/*mean (0.065126), correlation (0.552006)*/,
|
||||
0,-1, 1,4/*mean (0.074224), correlation (0.546372)*/,
|
||||
-13,3, -9,-2/*mean (0.0808592), correlation (0.554875)*/,
|
||||
-9,8, -6,-3/*mean (0.0883378), correlation (0.551178)*/,
|
||||
-13,-6, -8,-2/*mean (0.0901035), correlation (0.548446)*/,
|
||||
5,-9, 8,10/*mean (0.0949843), correlation (0.554694)*/,
|
||||
2,7, 3,-9/*mean (0.0994152), correlation (0.550979)*/,
|
||||
-1,-6, -1,-1/*mean (0.10045), correlation (0.552714)*/,
|
||||
9,5, 11,-2/*mean (0.100686), correlation (0.552594)*/,
|
||||
11,-3, 12,-8/*mean (0.101091), correlation (0.532394)*/,
|
||||
3,0, 3,5/*mean (0.101147), correlation (0.525576)*/,
|
||||
-1,4, 0,10/*mean (0.105263), correlation (0.531498)*/,
|
||||
3,-6, 4,5/*mean (0.110785), correlation (0.540491)*/,
|
||||
-13,0, -10,5/*mean (0.112798), correlation (0.536582)*/,
|
||||
5,8, 12,11/*mean (0.114181), correlation (0.555793)*/,
|
||||
8,9, 9,-6/*mean (0.117431), correlation (0.553763)*/,
|
||||
7,-4, 8,-12/*mean (0.118522), correlation (0.553452)*/,
|
||||
-10,4, -10,9/*mean (0.12094), correlation (0.554785)*/,
|
||||
7,3, 12,4/*mean (0.122582), correlation (0.555825)*/,
|
||||
9,-7, 10,-2/*mean (0.124978), correlation (0.549846)*/,
|
||||
7,0, 12,-2/*mean (0.127002), correlation (0.537452)*/,
|
||||
-1,-6, 0,-11/*mean (0.127148), correlation (0.547401)*/
|
||||
};
|
@ -445,6 +445,9 @@ CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize,
|
||||
int ksize, double k,
|
||||
int borderType=BORDER_DEFAULT );
|
||||
|
||||
// low-level function for computing eigenvalues and eigenvectors of 2x2 matrices
|
||||
CV_EXPORTS void eigen2x2( const float* a, float* e, int n );
|
||||
|
||||
//! computes both eigenvalues and the eigenvectors of 2x2 derivative covariation matrix at each pixel. The output is stored as 6-channel matrix.
|
||||
CV_EXPORTS_W void cornerEigenValsAndVecs( InputArray src, OutputArray dst,
|
||||
int blockSize, int ksize,
|
||||
@ -1016,6 +1019,10 @@ CV_EXPORTS_W void convexHull( InputArray points, OutputArray hull,
|
||||
//! returns true iff the contour is convex. Does not support contours with self-intersection
|
||||
CV_EXPORTS_W bool isContourConvex( InputArray contour );
|
||||
|
||||
//! finds intersection of two convex polygons
|
||||
CV_EXPORTS_W float intersectConvexConvex( InputArray _p1, InputArray _p2,
|
||||
OutputArray _p12, bool handleNested=true );
|
||||
|
||||
//! fits ellipse to the set of 2D points
|
||||
CV_EXPORTS_W RotatedRect fitEllipse( InputArray points );
|
||||
|
||||
|
@ -161,11 +161,67 @@ calcHarris( const Mat& _cov, Mat& _dst, double k )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void eigen2x2( const float* cov, float* dst, int n )
|
||||
{
|
||||
for( int j = 0; j < n; j++ )
|
||||
{
|
||||
double a = cov[j*3];
|
||||
double b = cov[j*3+1];
|
||||
double c = cov[j*3+2];
|
||||
|
||||
double u = (a + c)*0.5;
|
||||
double v = std::sqrt((a - c)*(a - c)*0.25 + b*b);
|
||||
double l1 = u + v;
|
||||
double l2 = u - v;
|
||||
|
||||
double x = b;
|
||||
double y = l1 - a;
|
||||
double e = fabs(x);
|
||||
|
||||
if( e + fabs(y) < 1e-4 )
|
||||
{
|
||||
y = b;
|
||||
x = l1 - c;
|
||||
e = fabs(x);
|
||||
if( e + fabs(y) < 1e-4 )
|
||||
{
|
||||
e = 1./(e + fabs(y) + FLT_EPSILON);
|
||||
x *= e, y *= e;
|
||||
}
|
||||
}
|
||||
|
||||
double d = 1./std::sqrt(x*x + y*y + DBL_EPSILON);
|
||||
dst[6*j] = (float)l1;
|
||||
dst[6*j + 2] = (float)(x*d);
|
||||
dst[6*j + 3] = (float)(y*d);
|
||||
|
||||
x = b;
|
||||
y = l2 - a;
|
||||
e = fabs(x);
|
||||
|
||||
if( e + fabs(y) < 1e-4 )
|
||||
{
|
||||
y = b;
|
||||
x = l2 - c;
|
||||
e = fabs(x);
|
||||
if( e + fabs(y) < 1e-4 )
|
||||
{
|
||||
e = 1./(e + fabs(y) + FLT_EPSILON);
|
||||
x *= e, y *= e;
|
||||
}
|
||||
}
|
||||
|
||||
d = 1./std::sqrt(x*x + y*y + DBL_EPSILON);
|
||||
dst[6*j + 1] = (float)l2;
|
||||
dst[6*j + 4] = (float)(x*d);
|
||||
dst[6*j + 5] = (float)(y*d);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
calcEigenValsVecs( const Mat& _cov, Mat& _dst )
|
||||
{
|
||||
int i, j;
|
||||
Size size = _cov.size();
|
||||
if( _cov.isContinuous() && _dst.isContinuous() )
|
||||
{
|
||||
@ -173,64 +229,12 @@ calcEigenValsVecs( const Mat& _cov, Mat& _dst )
|
||||
size.height = 1;
|
||||
}
|
||||
|
||||
for( i = 0; i < size.height; i++ )
|
||||
for( int i = 0; i < size.height; i++ )
|
||||
{
|
||||
const float* cov = (const float*)(_cov.data + _cov.step*i);
|
||||
float* dst = (float*)(_dst.data + _dst.step*i);
|
||||
|
||||
for( j = 0; j < size.width; j++ )
|
||||
{
|
||||
double a = cov[j*3];
|
||||
double b = cov[j*3+1];
|
||||
double c = cov[j*3+2];
|
||||
|
||||
double u = (a + c)*0.5;
|
||||
double v = std::sqrt((a - c)*(a - c)*0.25 + b*b);
|
||||
double l1 = u + v;
|
||||
double l2 = u - v;
|
||||
|
||||
double x = b;
|
||||
double y = l1 - a;
|
||||
double e = fabs(x);
|
||||
|
||||
if( e + fabs(y) < 1e-4 )
|
||||
{
|
||||
y = b;
|
||||
x = l1 - c;
|
||||
e = fabs(x);
|
||||
if( e + fabs(y) < 1e-4 )
|
||||
{
|
||||
e = 1./(e + fabs(y) + FLT_EPSILON);
|
||||
x *= e, y *= e;
|
||||
}
|
||||
}
|
||||
|
||||
double d = 1./std::sqrt(x*x + y*y + DBL_EPSILON);
|
||||
dst[6*j] = (float)l1;
|
||||
dst[6*j + 2] = (float)(x*d);
|
||||
dst[6*j + 3] = (float)(y*d);
|
||||
|
||||
x = b;
|
||||
y = l2 - a;
|
||||
e = fabs(x);
|
||||
|
||||
if( e + fabs(y) < 1e-4 )
|
||||
{
|
||||
y = b;
|
||||
x = l2 - c;
|
||||
e = fabs(x);
|
||||
if( e + fabs(y) < 1e-4 )
|
||||
{
|
||||
e = 1./(e + fabs(y) + FLT_EPSILON);
|
||||
x *= e, y *= e;
|
||||
}
|
||||
}
|
||||
|
||||
d = 1./std::sqrt(x*x + y*y + DBL_EPSILON);
|
||||
dst[6*j + 1] = (float)l2;
|
||||
dst[6*j + 4] = (float)(x*d);
|
||||
dst[6*j + 5] = (float)(y*d);
|
||||
}
|
||||
eigen2x2(cov, dst, size.width);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,4 +328,463 @@ cvPointPolygonTest( const CvArr* _contour, CvPoint2D32f pt, int measure_dist )
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This code is described in "Computational Geometry in C" (Second Edition),
|
||||
Chapter 7. It is not written to be comprehensible without the
|
||||
explanation in that book.
|
||||
|
||||
Written by Joseph O'Rourke.
|
||||
Last modified: December 1997
|
||||
Questions to orourke@cs.smith.edu.
|
||||
--------------------------------------------------------------------
|
||||
This code is Copyright 1997 by Joseph O'Rourke. It may be freely
|
||||
redistributed in its entirety provided that this copyright notice is
|
||||
not removed.
|
||||
--------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace cv
|
||||
{
|
||||
typedef enum { Pin, Qin, Unknown } tInFlag;
|
||||
|
||||
static int areaSign( Point2f a, Point2f b, Point2f c )
|
||||
{
|
||||
static const double eps = 1e-5;
|
||||
double area2 = (b.x - a.x) * (double)(c.y - a.y) - (c.x - a.x ) * (double)(b.y - a.y);
|
||||
return area2 > eps ? 1 : area2 < -eps ? -1 : 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Returns true iff point c lies on the closed segement ab.
|
||||
// Assumes it is already known that abc are collinear.
|
||||
//---------------------------------------------------------------------
|
||||
static bool between( Point2f a, Point2f b, Point2f c )
|
||||
{
|
||||
Point2f ba, ca;
|
||||
|
||||
// If ab not vertical, check betweenness on x; else on y.
|
||||
if ( a.x != b.x )
|
||||
return ((a.x <= c.x) && (c.x <= b.x)) ||
|
||||
((a.x >= c.x) && (c.x >= b.x));
|
||||
else
|
||||
return ((a.y <= c.y) && (c.y <= b.y)) ||
|
||||
((a.y >= c.y) && (c.y >= b.y));
|
||||
}
|
||||
|
||||
static char parallelInt( Point2f a, Point2f b, Point2f c, Point2f d, Point2f& p, Point2f& q )
|
||||
{
|
||||
char code = 'e';
|
||||
if( areaSign(a, b, c) != 0 )
|
||||
code = '0';
|
||||
else if( between(a, b, c) && between(a, b, d))
|
||||
p = c, q = d;
|
||||
else if( between(c, d, a) && between(c, d, b))
|
||||
p = a, q = b;
|
||||
else if( between(a, b, c) && between(c, d, b))
|
||||
p = c, q = b;
|
||||
else if( between(a, b, c) && between(c, d, a))
|
||||
p = c, q = a;
|
||||
else if( between(a, b, d) && between(c, d, b))
|
||||
p = d, q = b;
|
||||
else if( between(a, b, d) && between(c, d, a))
|
||||
p = d, q = a;
|
||||
else
|
||||
code = '0';
|
||||
return code;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// segSegInt: Finds the point of intersection p between two closed
|
||||
// segments ab and cd. Returns p and a char with the following meaning:
|
||||
// 'e': The segments collinearly overlap, sharing a point.
|
||||
// 'v': An endpoint (vertex) of one segment is on the other segment,
|
||||
// but 'e' doesn't hold.
|
||||
// '1': The segments intersect properly (i.e., they share a point and
|
||||
// neither 'v' nor 'e' holds).
|
||||
// '0': The segments do not intersect (i.e., they share no points).
|
||||
// Note that two collinear segments that share just one point, an endpoint
|
||||
// of each, returns 'e' rather than 'v' as one might expect.
|
||||
//---------------------------------------------------------------------
|
||||
static char segSegInt( Point2f a, Point2f b, Point2f c, Point2f d, Point2f& p, Point2f& q )
|
||||
{
|
||||
double s, t; // The two parameters of the parametric eqns.
|
||||
double num, denom; // Numerator and denoninator of equations.
|
||||
char code = '?'; // Return char characterizing intersection.
|
||||
|
||||
denom = a.x * (double)( d.y - c.y ) +
|
||||
b.x * (double)( c.y - d.y ) +
|
||||
d.x * (double)( b.y - a.y ) +
|
||||
c.x * (double)( a.y - b.y );
|
||||
|
||||
// If denom is zero, then segments are parallel: handle separately.
|
||||
if (denom == 0.0)
|
||||
return parallelInt(a, b, c, d, p, q);
|
||||
|
||||
num = a.x * (double)( d.y - c.y ) +
|
||||
c.x * (double)( a.y - d.y ) +
|
||||
d.x * (double)( c.y - a.y );
|
||||
if ( (num == 0.0) || (num == denom) ) code = 'v';
|
||||
s = num / denom;
|
||||
|
||||
num = -( a.x * (double)( c.y - b.y ) +
|
||||
b.x * (double)( a.y - c.y ) +
|
||||
c.x * (double)( b.y - a.y ) );
|
||||
if ( (num == 0.0) || (num == denom) ) code = 'v';
|
||||
t = num / denom;
|
||||
|
||||
if ( (0.0 < s) && (s < 1.0) &&
|
||||
(0.0 < t) && (t < 1.0) )
|
||||
code = '1';
|
||||
else if ( (0.0 > s) || (s > 1.0) ||
|
||||
(0.0 > t) || (t > 1.0) )
|
||||
code = '0';
|
||||
|
||||
p.x = a.x + s * ( b.x - a.x );
|
||||
p.y = a.y + s * ( b.y - a.y );
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static tInFlag inOut( Point2f p, tInFlag inflag, int aHB, int bHA, Point2f*& result )
|
||||
{
|
||||
if( p != result[-1] )
|
||||
*result++ = p;
|
||||
// Update inflag.
|
||||
return aHB > 0 ? Pin : bHA > 0 ? Qin : inflag;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Advances and prints out an inside vertex if appropriate.
|
||||
//---------------------------------------------------------------------
|
||||
static int advance( int a, int *aa, int n, bool inside, Point2f v, Point2f*& result )
|
||||
{
|
||||
if( inside && v != result[-1] )
|
||||
*result++ = v;
|
||||
(*aa)++;
|
||||
return (a+1) % n;
|
||||
}
|
||||
|
||||
static void addSharedSeg( Point2f p, Point2f q, Point2f*& result )
|
||||
{
|
||||
if( p != result[-1] )
|
||||
*result++ = p;
|
||||
if( q != result[-1] )
|
||||
*result++ = q;
|
||||
}
|
||||
|
||||
|
||||
static int intersectConvexConvex_( const Point2f* P, int n, const Point2f* Q, int m,
|
||||
Point2f* result, float* _area )
|
||||
{
|
||||
Point2f* result0 = result;
|
||||
// P has n vertices, Q has m vertices.
|
||||
int a=0, b=0; // indices on P and Q (resp.)
|
||||
Point2f Origin(0,0);
|
||||
tInFlag inflag=Unknown; // {Pin, Qin, Unknown}: which inside
|
||||
int aa=0, ba=0; // # advances on a & b indices (after 1st inter.)
|
||||
bool FirstPoint=true;// Is this the first point? (used to initialize).
|
||||
Point2f p0; // The first point.
|
||||
*result++ = Point2f(FLT_MAX, FLT_MAX);
|
||||
|
||||
do
|
||||
{
|
||||
// Computations of key variables.
|
||||
int a1 = (a + n - 1) % n; // a-1, b-1 (resp.)
|
||||
int b1 = (b + m - 1) % m;
|
||||
|
||||
Point2f A = P[a] - P[a1], B = Q[b] - Q[b1]; // directed edges on P and Q (resp.)
|
||||
|
||||
int cross = areaSign( Origin, A, B ); // sign of z-component of A x B
|
||||
int aHB = areaSign( Q[b1], Q[b], P[a] ); // a in H(b).
|
||||
int bHA = areaSign( P[a1], P[a], Q[b] ); // b in H(A);
|
||||
|
||||
// If A & B intersect, update inflag.
|
||||
Point2f p, q;
|
||||
int code = segSegInt( P[a1], P[a], Q[b1], Q[b], p, q );
|
||||
if( code == '1' || code == 'v' )
|
||||
{
|
||||
if( inflag == Unknown && FirstPoint )
|
||||
{
|
||||
aa = ba = 0;
|
||||
FirstPoint = false;
|
||||
p0 = p;
|
||||
*result++ = p;
|
||||
}
|
||||
inflag = inOut( p, inflag, aHB, bHA, result );
|
||||
}
|
||||
|
||||
//-----Advance rules-----
|
||||
|
||||
// Special case: A & B overlap and oppositely oriented.
|
||||
if( code == 'e' && A.ddot(B) < 0 )
|
||||
{
|
||||
addSharedSeg( p, q, result );
|
||||
return (int)(result - result0);
|
||||
}
|
||||
|
||||
// Special case: A & B parallel and separated.
|
||||
if( cross == 0 && aHB < 0 && bHA < 0 )
|
||||
return (int)(result - result0);
|
||||
|
||||
// Special case: A & B collinear.
|
||||
else if ( cross == 0 && aHB == 0 && bHA == 0 ) {
|
||||
// Advance but do not output point.
|
||||
if ( inflag == Pin )
|
||||
b = advance( b, &ba, m, inflag == Qin, Q[b], result );
|
||||
else
|
||||
a = advance( a, &aa, n, inflag == Pin, P[a], result );
|
||||
}
|
||||
|
||||
// Generic cases.
|
||||
else if( cross >= 0 )
|
||||
{
|
||||
if( bHA > 0)
|
||||
a = advance( a, &aa, n, inflag == Pin, P[a], result );
|
||||
else
|
||||
b = advance( b, &ba, m, inflag == Qin, Q[b], result );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( aHB > 0)
|
||||
b = advance( b, &ba, m, inflag == Qin, Q[b], result );
|
||||
else
|
||||
a = advance( a, &aa, n, inflag == Pin, P[a], result );
|
||||
}
|
||||
// Quit when both adv. indices have cycled, or one has cycled twice.
|
||||
}
|
||||
while ( ((aa < n) || (ba < m)) && (aa < 2*n) && (ba < 2*m) );
|
||||
|
||||
// Deal with special cases: not implemented.
|
||||
if( inflag == Unknown )
|
||||
{
|
||||
// The boundaries of P and Q do not cross.
|
||||
// ...
|
||||
}
|
||||
|
||||
int i, nr = (int)(result - result0);
|
||||
double area = 0;
|
||||
Point2f prev = result0[nr-1];
|
||||
for( i = 1; i < nr; i++ )
|
||||
{
|
||||
result0[i-1] = result0[i];
|
||||
area += (double)prev.x*result0[i].y - (double)prev.y*result0[i].x;
|
||||
prev = result0[i];
|
||||
}
|
||||
|
||||
*_area = (float)(area*0.5);
|
||||
|
||||
if( result0[nr-2] == result0[0] && nr > 1 )
|
||||
nr--;
|
||||
return nr-1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float cv::intersectConvexConvex( InputArray _p1, InputArray _p2, OutputArray _p12, bool handleNested )
|
||||
{
|
||||
Mat p1 = _p1.getMat(), p2 = _p2.getMat();
|
||||
CV_Assert( p1.depth() == CV_32S || p1.depth() == CV_32F );
|
||||
CV_Assert( p2.depth() == CV_32S || p2.depth() == CV_32F );
|
||||
|
||||
int n = p1.checkVector(2, p1.depth(), true);
|
||||
int m = p2.checkVector(2, p2.depth(), true);
|
||||
|
||||
CV_Assert( n >= 0 && m >= 0 );
|
||||
|
||||
if( n < 2 || m < 2 )
|
||||
{
|
||||
_p12.release();
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
AutoBuffer<Point2f> _result(n*2 + m*2 + 1);
|
||||
Point2f *fp1 = _result, *fp2 = fp1 + n;
|
||||
Point2f* result = fp2 + m;
|
||||
int orientation = 0;
|
||||
|
||||
for( int k = 1; k <= 2; k++ )
|
||||
{
|
||||
Mat& p = k == 1 ? p1 : p2;
|
||||
int len = k == 1 ? n : m;
|
||||
Point2f* dst = k == 1 ? fp1 : fp2;
|
||||
|
||||
Mat temp(p.size(), CV_MAKETYPE(CV_32F, p.channels()), dst);
|
||||
p.convertTo(temp, CV_32F);
|
||||
CV_Assert( temp.ptr<Point2f>() == dst );
|
||||
Point2f diff0 = dst[0] - dst[len-1];
|
||||
for( int i = 1; i < len; i++ )
|
||||
{
|
||||
double s = diff0.cross(dst[i] - dst[i-1]);
|
||||
if( s != 0 )
|
||||
{
|
||||
if( s < 0 )
|
||||
{
|
||||
orientation++;
|
||||
flip( temp, temp, temp.rows > 1 ? 0 : 1 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float area = 0.f;
|
||||
int nr = intersectConvexConvex_(fp1, n, fp2, m, result, &area);
|
||||
if( nr == 0 )
|
||||
{
|
||||
if( !handleNested )
|
||||
{
|
||||
_p12.release();
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
if( pointPolygonTest(_InputArray(fp1, n), fp2[0], false) >= 0 )
|
||||
{
|
||||
result = fp2;
|
||||
nr = m;
|
||||
}
|
||||
else if( pointPolygonTest(_InputArray(fp2, n), fp1[0], false) >= 0 )
|
||||
{
|
||||
result = fp1;
|
||||
nr = n;
|
||||
}
|
||||
else
|
||||
{
|
||||
_p12.release();
|
||||
return 0.f;
|
||||
}
|
||||
area = contourArea(_InputArray(result, nr), false);
|
||||
}
|
||||
|
||||
if( _p12.needed() )
|
||||
{
|
||||
Mat temp(nr, 1, CV_32FC2, result);
|
||||
// if both input contours were reflected,
|
||||
// let's orient the result as the input vectors
|
||||
if( orientation == 2 )
|
||||
flip(temp, temp, 0);
|
||||
|
||||
temp.copyTo(_p12);
|
||||
}
|
||||
return (float)fabs(area);
|
||||
}
|
||||
|
||||
/*
|
||||
static void testConvConv()
|
||||
{
|
||||
static const int P1[] =
|
||||
{
|
||||
0, 0,
|
||||
100, 0,
|
||||
100, 100,
|
||||
0, 100,
|
||||
};
|
||||
|
||||
static const int Q1[] =
|
||||
{
|
||||
100, 80,
|
||||
50, 80,
|
||||
50, 50,
|
||||
100, 50
|
||||
};
|
||||
|
||||
static const int P2[] =
|
||||
{
|
||||
0, 0,
|
||||
200, 0,
|
||||
200, 100,
|
||||
100, 200,
|
||||
0, 100
|
||||
};
|
||||
|
||||
static const int Q2[] =
|
||||
{
|
||||
100, 100,
|
||||
300, 100,
|
||||
300, 200,
|
||||
100, 200
|
||||
};
|
||||
|
||||
static const int P3[] =
|
||||
{
|
||||
0, 0,
|
||||
100, 0,
|
||||
100, 100,
|
||||
0, 100
|
||||
};
|
||||
|
||||
static const int Q3[] =
|
||||
{
|
||||
50, 50,
|
||||
150, 50,
|
||||
150, 150,
|
||||
50, 150
|
||||
};
|
||||
|
||||
static const int P4[] =
|
||||
{
|
||||
0, 160,
|
||||
50, 80,
|
||||
130, 0,
|
||||
190, 20,
|
||||
240, 100,
|
||||
240, 260,
|
||||
190, 290,
|
||||
130, 320,
|
||||
70, 320,
|
||||
30, 290
|
||||
};
|
||||
|
||||
static const int Q4[] =
|
||||
{
|
||||
160, -30,
|
||||
280, 160,
|
||||
160, 320,
|
||||
0, 220,
|
||||
30, 100
|
||||
};
|
||||
|
||||
static const void* PQs[] =
|
||||
{
|
||||
P1, Q1, P2, Q2, P3, Q3, P4, Q4
|
||||
};
|
||||
|
||||
static const int lens[] =
|
||||
{
|
||||
CV_DIM(P1), CV_DIM(Q1),
|
||||
CV_DIM(P2), CV_DIM(Q2),
|
||||
CV_DIM(P3), CV_DIM(Q3),
|
||||
CV_DIM(P4), CV_DIM(Q4)
|
||||
};
|
||||
|
||||
Mat img(800, 800, CV_8UC3);
|
||||
|
||||
for( int i = 0; i < CV_DIM(PQs)/2; i++ )
|
||||
{
|
||||
Mat Pm = Mat(lens[i*2]/2, 1, CV_32SC2, (void*)PQs[i*2]) + Scalar(100, 100);
|
||||
Mat Qm = Mat(lens[i*2+1]/2, 1, CV_32SC2, (void*)PQs[i*2+1]) + Scalar(100, 100);
|
||||
Point* P = Pm.ptr<Point>();
|
||||
Point* Q = Qm.ptr<Point>();
|
||||
|
||||
flip(Pm, Pm, 0);
|
||||
flip(Qm, Qm, 0);
|
||||
|
||||
Mat Rm;
|
||||
intersectConvexConvex(Pm, Qm, Rm);
|
||||
std::cout << Rm << std::endl << std::endl;
|
||||
|
||||
img = Scalar::all(0);
|
||||
|
||||
polylines(img, Pm, true, Scalar(0,255,0), 1, CV_AA, 0);
|
||||
polylines(img, Qm, true, Scalar(0,0,255), 1, CV_AA, 0);
|
||||
Mat temp;
|
||||
Rm.convertTo(temp, CV_32S, 256);
|
||||
polylines(img, temp, true, Scalar(128, 255, 255), 3, CV_AA, 8);
|
||||
|
||||
namedWindow("test", 1);
|
||||
imshow("test", img);
|
||||
waitKey();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* End of file. */
|
||||
|
@ -206,6 +206,22 @@ void cv::copyMakeBorder( InputArray _src, OutputArray _dst, int top, int bottom,
|
||||
_dst.create( src.rows + top + bottom, src.cols + left + right, src.type() );
|
||||
Mat dst = _dst.getMat();
|
||||
|
||||
if( src.isSubmatrix() && (borderType & BORDER_ISOLATED) == 0 )
|
||||
{
|
||||
Size wholeSize;
|
||||
Point ofs;
|
||||
src.locateROI(wholeSize, ofs);
|
||||
int dtop = std::min(ofs.y, top);
|
||||
int dbottom = std::min(wholeSize.height - src.rows - ofs.y, bottom);
|
||||
int dleft = std::min(ofs.x, left);
|
||||
int dright = std::min(wholeSize.width - src.cols - ofs.x, right);
|
||||
src.adjustROI(dtop, dbottom, dleft, dright);
|
||||
top -= dtop;
|
||||
left -= dleft;
|
||||
}
|
||||
|
||||
borderType &= ~BORDER_ISOLATED;
|
||||
|
||||
if( borderType != BORDER_CONSTANT )
|
||||
copyMakeBorder_8u( src.data, src.step, src.size(),
|
||||
dst.data, dst.step, dst.size(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user