41 #include "opencv2/features2d/features2d.hpp"
42 #include "opencv2/imgproc/imgproc.hpp"
43 #include "opencv2/imgproc/imgproc_c.h"
64 CV_Assert(
img.type() == CV_8UC1 && blockSize*blockSize <= 2048 );
66 size_t ptidx, ptsize = pts.size();
72 float scale = (1 << 2) * blockSize * 255.0
f;
76 AutoBuffer<int> ofsbuf(blockSize*blockSize);
78 for(
int i = 0;
i < blockSize;
i++ )
79 for(
int j = 0;
j < blockSize;
j++ )
80 ofs[
i*blockSize +
j] = (
int)(
i*
step +
j);
82 for( ptidx = 0; ptidx < ptsize; ptidx++ )
84 int x0 = cvRound(pts[ptidx].pt.x - r);
85 int y0 = cvRound(pts[ptidx].pt.y - r);
88 int a = 0,
b = 0,
c = 0;
90 for(
int k = 0; k < blockSize*blockSize; k++ )
92 const uchar* ptr = ptr0 + ofs[k];
93 int Ix = (ptr[1] - ptr[-1])*2 + (ptr[-
step+1] - ptr[-
step-1]) + (ptr[
step+1] - ptr[
step-1]);
99 pts[ptidx].response = ((
float)
a *
b - (
float)
c *
c -
106 static float IC_Angle(
const Mat& image,
const int half_k, Point2f pt,
107 const std::vector<int> & u_max)
109 int m_01 = 0, m_10 = 0;
111 const uchar* center = &image.at<
uchar> (cvRound(pt.y), cvRound(pt.x));
114 for (
int u = -half_k; u <= half_k; ++u)
115 m_10 += u * center[u];
119 for (
int v = 1;
v <= half_k; ++
v)
124 for (
int u = -
d; u <=
d; ++u)
126 int val_plus = center[u +
v*
step], val_minus = center[u -
v*
step];
127 v_sum += (val_plus - val_minus);
128 m_10 += u * (val_plus + val_minus);
133 return fastAtan2((
float)m_01, (
float)m_10);
139 const Mat&
img,
const Point* pattern,
140 uchar* desc,
int dsize,
int WTA_K)
142 float angle = kpt.angle;
147 const uchar* center = &
img.at<
uchar>(cvRound(kpt.pt.y), cvRound(kpt.pt.x));
154 (
x = pattern[idx].x*
a - pattern[idx].y*
b, \
155 y = pattern[idx].x*
b + pattern[idx].y*
a, \
158 *(center + iy*
step + ix) )
160 #define GET_VALUE(idx) \
161 (x = pattern[idx].x*a - pattern[idx].y*b, \
162 y = pattern[idx].x*b + pattern[idx].y*a, \
163 ix = cvFloor(x), iy = cvFloor(y), \
165 cvRound(center[iy*step + ix]*(1-x)*(1-y) + center[(iy+1)*step + ix]*(1-x)*y + \
166 center[iy*step + ix+1]*x*(1-y) + center[(iy+1)*step + ix+1]*x*y))
171 for (
int i = 0;
i < dsize; ++
i, pattern += 16)
177 val |= (t0 < t1) << 1;
179 val |= (t0 < t1) << 2;
181 val |= (t0 < t1) << 3;
183 val |= (t0 < t1) << 4;
185 val |= (t0 < t1) << 5;
187 val |= (t0 < t1) << 6;
189 val |= (t0 < t1) << 7;
194 else if( WTA_K == 3 )
196 for (
int i = 0;
i < dsize; ++
i, pattern += 12)
200 val = t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0);
203 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 2;
206 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 4;
209 val |= (t2 > t1 ? (t2 > t0 ? 2 : 0) : (t1 > t0)) << 6;
214 else if( WTA_K == 4 )
216 for (
int i = 0;
i < dsize; ++
i, pattern += 16)
218 int t0, t1, t2, t3, u,
v, k, val;
222 if( t1 > t0 ) t0 = t1, u = 1;
223 if( t3 > t2 ) t2 = t3,
v = 3;
230 if( t1 > t0 ) t0 = t1, u = 1;
231 if( t3 > t2 ) t2 = t3,
v = 3;
238 if( t1 > t0 ) t0 = t1, u = 1;
239 if( t3 > t2 ) t2 = t3,
v = 3;
246 if( t1 > t0 ) t0 = t1, u = 1;
247 if( t3 > t2 ) t2 = t3,
v = 3;
255 CV_Error( CV_StsBadSize,
"Wrong WTA_K. It can be only 2, 3 or 4." );
261 static void initializeOrbPattern(
const Point* pattern0, std::vector<Point>& pattern,
int ntuples,
int tupleSize,
int poolSize )
265 pattern.resize(ntuples*tupleSize);
267 for(
i = 0;
i < ntuples;
i++ )
269 for( k = 0; k < tupleSize; k++ )
273 int idx = rng.uniform(0, poolSize);
274 Point pt = pattern0[idx];
275 for(
k1 = 0;
k1 < k;
k1++ )
276 if( pattern[tupleSize*
i +
k1] == pt )
280 pattern[tupleSize*
i + k] = pt;
553 for(
int i = 0;
i < npoints;
i++ )
555 pattern[
i].x = rng.uniform(-patchSize/2, patchSize/2+1);
556 pattern[
i].y = rng.uniform(-patchSize/2, patchSize/2+1);
561 static inline float getScale(
int level,
int firstLevel,
double scaleFactor)
563 return (
float)
std::pow(scaleFactor, (
double)(
level - firstLevel));
569 CV_ORB::CV_ORB(
int _nfeatures,
float _scaleFactor,
int _nlevels,
int _edgeThreshold,
570 int _firstLevel,
int _WTA_K,
int _scoreType,
int _patchSize,
const ParametersMap & _fastParameters) :
571 nfeatures(_nfeatures), scaleFactor(_scaleFactor), nlevels(_nlevels),
572 edgeThreshold(_edgeThreshold), firstLevel(_firstLevel), WTA_K(_WTA_K),
573 scoreType(_scoreType), patchSize(_patchSize), fastParameters(_fastParameters)
594 (*this)(image,
mask, keypoints, noArray(),
false);
605 int halfPatchSize,
const std::vector<int>& umax)
608 for (std::vector<KeyPoint>::iterator keypoint = keypoints.begin(),
609 keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
611 keypoint->angle =
IC_Angle(image, halfPatchSize, keypoint->pt, umax);
622 const std::vector<Mat>& maskPyramid,
623 std::vector<std::vector<KeyPoint> >& allKeypoints,
624 int nfeatures,
int firstLevel,
double scaleFactor,
625 int edgeThreshold,
int patchSize,
int scoreType,
628 int nlevels = (
int)imagePyramid.size();
629 std::vector<int> nfeaturesPerLevel(nlevels);
632 float factor = (
float)(1.0 / scaleFactor);
633 float ndesiredFeaturesPerScale = nfeatures*(1 - factor)/(1 - (
float)
pow((
double)factor, (
double)nlevels));
638 nfeaturesPerLevel[
level] = cvRound(ndesiredFeaturesPerScale);
639 sumFeatures += nfeaturesPerLevel[
level];
640 ndesiredFeaturesPerScale *= factor;
642 nfeaturesPerLevel[nlevels-1] =
std::max(nfeatures - sumFeatures, 0);
648 int halfPatchSize = patchSize / 2;
649 std::vector<int> umax(halfPatchSize + 2);
651 int v, v0, vmax = cvFloor(halfPatchSize *
sqrt(2.
f) / 2 + 1);
652 int vmin = cvCeil(halfPatchSize *
sqrt(2.
f) / 2);
653 for (
v = 0;
v <= vmax; ++
v)
654 umax[
v] = cvRound(
sqrt((
double)halfPatchSize * halfPatchSize -
v *
v));
657 for (
v = halfPatchSize, v0 = 0;
v >= vmin; --
v)
659 while (umax[v0] == umax[v0 + 1])
665 allKeypoints.resize(nlevels);
669 int featuresNum = nfeaturesPerLevel[
level];
670 allKeypoints[
level].reserve(featuresNum*2);
672 std::vector<KeyPoint> & keypoints = allKeypoints[
level];
677 keypoints =
fast.generateKeypoints(imagePyramid[
level], maskPyramid[
level]);
680 KeyPointsFilter::runByImageBorder(keypoints, imagePyramid[
level].
size(), edgeThreshold);
685 KeyPointsFilter::retainBest(keypoints, 2 * featuresNum);
692 KeyPointsFilter::retainBest(keypoints, featuresNum);
697 for (std::vector<KeyPoint>::iterator keypoint = keypoints.begin(),
698 keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
700 keypoint->octave =
level;
701 keypoint->size = patchSize*sf;
717 const std::vector<Point>& pattern,
int dsize,
int WTA_K)
720 CV_Assert(image.type() == CV_8UC1);
722 descriptors = Mat::zeros((
int)keypoints.size(), dsize, CV_8UC1);
724 for (
size_t i = 0;
i < keypoints.size();
i++)
737 void CV_ORB::operator()( InputArray _image, InputArray _mask, std::vector<KeyPoint>& _keypoints,
738 OutputArray _descriptors,
bool useProvidedKeypoints)
const
742 bool do_keypoints = !useProvidedKeypoints;
743 bool do_descriptors = _descriptors.needed();
745 if( (!do_keypoints && !do_descriptors) || _image.empty() )
749 const int HARRIS_BLOCK_SIZE = 9;
753 Mat image = _image.getMat(),
mask = _mask.getMat();
754 if( image.type() != CV_8UC1 )
755 cvtColor(_image, image, CV_BGR2GRAY);
771 for(
size_t i = 0;
i < _keypoints.size();
i++ )
777 std::vector<Mat> imagePyramid(levelsNum), maskPyramid(levelsNum);
778 for (
int level = 0;
level < levelsNum; ++
level)
781 Size sz(cvRound(image.cols*scale), cvRound(image.rows*scale));
782 Size wholeSize(sz.width + border*2, sz.height + border*2);
783 Mat temp(wholeSize, image.type()), masktemp;
784 imagePyramid[
level] = temp(Rect(border, border, sz.width, sz.height));
788 masktemp =
Mat(wholeSize,
mask.type());
789 maskPyramid[
level] = masktemp(Rect(border, border, sz.width, sz.height));
797 resize(image, imagePyramid[level], sz, 0, 0, INTER_LINEAR);
799 resize(
mask, maskPyramid[level], sz, 0, 0, INTER_LINEAR);
803 resize(imagePyramid[level-1], imagePyramid[level], sz, 0, 0, INTER_LINEAR);
806 resize(maskPyramid[level-1], maskPyramid[level], sz, 0, 0, INTER_LINEAR);
807 threshold(maskPyramid[level], maskPyramid[level], 254, 0, THRESH_TOZERO);
811 copyMakeBorder(imagePyramid[level], temp, border, border, border, border,
812 BORDER_REFLECT_101+BORDER_ISOLATED);
814 copyMakeBorder(maskPyramid[level], masktemp, border, border, border, border,
815 BORDER_CONSTANT+BORDER_ISOLATED);
819 copyMakeBorder(image, temp, border, border, border, border,
822 copyMakeBorder(
mask, masktemp, border, border, border, border,
823 BORDER_CONSTANT+BORDER_ISOLATED);
828 std::vector < std::vector<KeyPoint> > allKeypoints;
856 KeyPointsFilter::runByImageBorder(_keypoints, image.size(),
edgeThreshold);
859 allKeypoints.resize(levelsNum);
860 for (std::vector<KeyPoint>::iterator keypoint = _keypoints.begin(),
861 keypointEnd = _keypoints.end(); keypoint != keypointEnd; ++keypoint)
862 allKeypoints[keypoint->octave].push_back(*keypoint);
865 for (
int level = 0;
level < levelsNum; ++
level)
870 std::vector<KeyPoint> & keypoints = allKeypoints[
level];
872 for (std::vector<KeyPoint>::iterator keypoint = keypoints.begin(),
873 keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
874 keypoint->pt *=
scale;
879 std::vector<Point> pattern;
884 for (
int level = 0;
level < levelsNum; ++
level)
885 nkeypoints += (
int)allKeypoints[
level].size();
886 if( nkeypoints == 0 )
887 _descriptors.release();
891 descriptors = _descriptors.getMat();
894 const int npoints = 512;
895 Point patternbuf[npoints];
900 pattern0 = patternbuf;
907 std::copy(pattern0, pattern0 + npoints, std::back_inserter(pattern));
917 for (
int level = 0;
level < levelsNum; ++
level)
920 std::vector<KeyPoint>& keypoints = allKeypoints[
level];
921 int nkeypoints = (
int)keypoints.
size();
927 if (!descriptors.empty())
929 desc = descriptors.rowRange(offset, offset + nkeypoints);
934 Mat& workingMat = imagePyramid[
level];
936 GaussianBlur(workingMat, workingMat, Size(7, 7), 2, 2, BORDER_REFLECT_101);
944 for (std::vector<KeyPoint>::iterator keypoint = keypoints.begin(),
945 keypointEnd = keypoints.end(); keypoint != keypointEnd; ++keypoint)
946 keypoint->pt *=
scale;
949 _keypoints.insert(_keypoints.end(), keypoints.begin(), keypoints.end());
955 (*this)(image,
mask, keypoints, noArray(),
false);
960 (*this)(image,
Mat(), keypoints, descriptors,
true);