Skip to content

Commit d945e79

Browse files
authored
Add files via upload
1 parent e483448 commit d945e79

File tree

6 files changed

+1698
-0
lines changed

6 files changed

+1698
-0
lines changed

BRIEF/BRIEF.cpp

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
Copyright 2010 Computer Vision Lab,
3+
Ecole Polytechnique Federale de Lausanne (EPFL), Switzerland.
4+
All rights reserved.
5+
6+
Authors: Eray Molla, Michael Calonder, and Vincent Lepetit
7+
8+
This file is part of the BRIEF_demo software.
9+
10+
BRIEF_demo is free software; you can redistribute it and/or modify
11+
it under the terms of the GNU General Public License as published by
12+
the Free Software Foundation; either version 2 of the License, or
13+
(at your option) any later version.
14+
15+
BRIEF_demo is distributed in the hope that it will be useful, but
16+
WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18+
General Public License for more details.
19+
20+
You should have received a copy of the GNU General Public License
21+
along with BRIEF_demo; if not, write to the Free Software
22+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23+
02110-1301, USA
24+
*/
25+
26+
#include "BRIEF.h"
27+
28+
#include <cv.h>
29+
#include <highgui.h>
30+
#include <cvaux.h>
31+
#include <ctime>
32+
#include <iostream>
33+
34+
using namespace std;
35+
using namespace CVLAB;
36+
37+
BRIEF::BRIEF(void)
38+
{
39+
// Allocates memory for 'testLocations' and 'intensityPairs':
40+
testLocations = vector< pair<cv::Point2i, cv::Point2i> >(DESC_LEN);
41+
integralImage = cvCreateMat(1, 1, CV_32SC1);
42+
43+
// Picks the pixel pairs for intensity comparison tests:
44+
pickTestLocations();
45+
}
46+
47+
BRIEF::~BRIEF(void)
48+
{
49+
// Free allocated memory segments:
50+
testLocations.clear();
51+
cvReleaseMat(&integralImage);
52+
}
53+
54+
void BRIEF::getBriefDescriptor(bitset<DESC_LEN>& desc, cv::KeyPoint kpt, IplImage* img)
55+
{
56+
// Calculate the width step of the integral image
57+
int inWS = integralImage->step / CV_ELEM_SIZE(integralImage->type);
58+
59+
// Hold the pointer of the data part of integral image matrix with 'iD'
60+
int* iD = integralImage->data.i;
61+
62+
// Iterate over test location pairs
63+
for (int i = 0; i < DESC_LEN; ++i) {
64+
// tL holds the current test location pairs
65+
const pair<cv::Point2i, cv::Point2i>& tL = testLocations[i];
66+
67+
// Transform the testpoints from patch coordinates to the image coordinate
68+
const cv::Point2i p1 = CV_POINT_PLUS(kpt.pt, tL.first);
69+
const cv::Point2i p2 = CV_POINT_PLUS(kpt.pt, tL.second);
70+
71+
// Use the integral image to compare the average intensities around the 2 test locations:
72+
const int intensity1 =
73+
GET_PIXEL_NW(iD, p1, inWS) - GET_PIXEL_NE(iD, p1, inWS) -
74+
GET_PIXEL_SW(iD, p1, inWS) + GET_PIXEL_SE(iD, p1, inWS);
75+
76+
const int intensity2 =
77+
GET_PIXEL_NW(iD, p2, inWS) - GET_PIXEL_NE(iD, p2, inWS) -
78+
GET_PIXEL_SW(iD, p2, inWS) + GET_PIXEL_SE(iD, p2, inWS);
79+
80+
desc[i] = intensity1 < intensity2;
81+
}
82+
}
83+
84+
void BRIEF::getBriefDescriptors(vector< bitset<DESC_LEN> >& descriptors, const vector<cv::KeyPoint>& kpts,
85+
IplImage* img)
86+
{
87+
// Make sure that input image contains only one color channel:
88+
assert(img->nChannels == 1);
89+
90+
// Check whether all the keypoints are inside the subimage:
91+
assert(validateKeypoints(kpts, img->width, img->height));
92+
93+
// If memory allocated in 'descriptors' is not enough, then resize it:
94+
descriptors.resize(kpts.size());
95+
96+
// Allocate space for the integral image:
97+
allocateIntegralImage(img);
98+
99+
// Calculate the integral image:
100+
cvIntegral(img, integralImage);
101+
102+
// Iterate over keypoints:
103+
for (unsigned int i = 0; i < kpts.size(); ++i)
104+
getBriefDescriptor(descriptors[i], kpts[i], img);
105+
}
106+
107+
void BRIEF::pickTestLocations(void)
108+
{
109+
// Pick test locations totally randomly in a way that the locations are inside the patch. Note that
110+
// number of the tests is equal to the length of the descriptor.
111+
for (int i = 0; i < DESC_LEN; ++i) {
112+
pair<cv::Point2i, cv::Point2i>& tL = testLocations[i];
113+
114+
tL.first.x = int(rand() % PATCH_SIZE) - HALF_PATCH_SIZE - 1;
115+
tL.first.y = int(rand() % PATCH_SIZE) - HALF_PATCH_SIZE - 1;
116+
tL.second.x = int(rand() % PATCH_SIZE) - HALF_PATCH_SIZE - 1;
117+
tL.second.y = int(rand() % PATCH_SIZE) - HALF_PATCH_SIZE - 1;
118+
}
119+
}
120+
121+
bool BRIEF::isKeypointInsideSubImage(const cv::KeyPoint& kpt, const int width, const int height)
122+
{
123+
return
124+
SUBIMAGE_LEFT <= kpt.pt.x && kpt.pt.x < SUBIMAGE_RIGHT(width) &&
125+
SUBIMAGE_TOP <= kpt.pt.y && kpt.pt.y < SUBIMAGE_BOTTOM(height);
126+
}
127+
128+
bool BRIEF::validateKeypoints(const vector<cv::KeyPoint>& kpts, int im_w, int im_h)
129+
{
130+
for (unsigned int i = 0; i < kpts.size(); ++i)
131+
if ( !isKeypointInsideSubImage(kpts[i], im_w, im_h) )
132+
return false;
133+
134+
return true;
135+
}
136+
137+
void BRIEF::allocateIntegralImage(const IplImage* img)
138+
{
139+
const int im_w_1 = img->width + 1, im_h_1 = img->height + 1;
140+
141+
if (im_w_1 != integralImage->width && im_h_1 != integralImage->height) {
142+
cvReleaseMat(&integralImage);
143+
integralImage = cvCreateMat(im_h_1, im_w_1, CV_32SC1);
144+
}
145+
}

BRIEF/BRIEF.h

+188
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
Copyright 2010 Computer Vision Lab,
3+
Ecole Polytechnique Federale de Lausanne (EPFL), Switzerland.
4+
All rights reserved.
5+
6+
Authors: Eray Molla, Michael Calonder, and Vincent Lepetit
7+
8+
This file is part of the BRIEF_demo software.
9+
10+
BRIEF_demo is free software; you can redistribute it and/or modify
11+
it under the terms of the GNU General Public License as published by
12+
the Free Software Foundation; either version 2 of the License, or
13+
(at your option) any later version.
14+
15+
BRIEF_demo is distributed in the hope that it will be useful, but
16+
WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18+
General Public License for more details.
19+
20+
You should have received a copy of the GNU General Public License
21+
along with BRIEF_demo; if not, write to the Free Software
22+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23+
02110-1301, USA
24+
*/
25+
26+
#ifndef __BRIEF_H__
27+
#define __BRIEF_H__
28+
29+
#include <vector>
30+
#include <bitset>
31+
#include <cv.h>
32+
#include <highgui.h>
33+
34+
using namespace std;
35+
36+
namespace CVLAB {
37+
38+
// Length of the BRIEF descriptor:
39+
static const int DESC_LEN = 256;
40+
41+
// Size of the area in which the tests are computed:
42+
static const int PATCH_SIZE = 37;
43+
44+
// Box kernel size used for smoothing. Must be an odd positive integer:
45+
static const int KERNEL_SIZE = 9;
46+
47+
48+
// Size of the area surrounding feature point
49+
static const int PATCH_SIZE_2 = PATCH_SIZE * PATCH_SIZE;
50+
// Half of the patch size
51+
static const int HALF_PATCH_SIZE = PATCH_SIZE >> 1;
52+
// Area of the smoothing kernel
53+
static const int KERNEL_AREA = KERNEL_SIZE * KERNEL_SIZE;
54+
// Half of the kernel size
55+
static const int HALF_KERNEL_SIZE = KERNEL_SIZE >> 1;
56+
57+
/***************************************************************************************************
58+
*
59+
* +++++++++++++++++++
60+
* +-a- | +
61+
* + b + a = IMAGE_PADDING_LEFT
62+
* + | + b = IMAGE_PADDING_TOP
63+
* + +++++++++++ + The area inside is the subimage we look for the keypoints such that
64+
* + + + + all the test locations we pick and the corners of the smoothing kernels
65+
* + + + + we apply to these test locations are guaranteed to be inside the image.
66+
* + + + + Note that in our implementation a = b
67+
* + + + +
68+
* + +++++++++++ +
69+
* + | -a-+
70+
* + b +
71+
* + | +
72+
* +++++++++++++++++++
73+
* Figure 1
74+
*
75+
**************************************************************************************************/
76+
77+
// See figure above:
78+
static const int IMAGE_PADDING_TOP = HALF_KERNEL_SIZE + HALF_PATCH_SIZE;
79+
static const int IMAGE_PADDING_LEFT = IMAGE_PADDING_TOP;
80+
static const int IMAGE_PADDING_TOTAL = IMAGE_PADDING_TOP << 1;
81+
static const int IMAGE_PADDING_RIGHT = IMAGE_PADDING_LEFT;
82+
static const int IMAGE_PADDING_BOTTOM = IMAGE_PADDING_TOP;
83+
static const int SUBIMAGE_LEFT = IMAGE_PADDING_LEFT;
84+
static const int SUBIMAGE_TOP = IMAGE_PADDING_TOP;
85+
86+
// Returns the Hamming Distance between two BRIEF descriptors
87+
inline int HAMMING_DISTANCE(const bitset<DESC_LEN>& d1, const bitset<DESC_LEN>& d2)
88+
{
89+
return (d1 ^ d2).count();
90+
}
91+
92+
// Returns the width of the subimage shown in the figure above given the original image width:
93+
inline int SUBIMAGE_WIDTH(const int width)
94+
{
95+
return width - IMAGE_PADDING_TOTAL;
96+
}
97+
98+
// Returns the width of the subimage shown in the figure above given the original image width:
99+
inline int SUBIMAGE_HEIGHT(const int height)
100+
{
101+
return height - IMAGE_PADDING_TOTAL;
102+
}
103+
104+
// Returns the x-coordinate of the right edge of the subimage
105+
inline int SUBIMAGE_RIGHT(const int width)
106+
{
107+
return width - IMAGE_PADDING_RIGHT;
108+
}
109+
110+
// Returns the y-coordinate of the bottom edge of the subimage
111+
inline int SUBIMAGE_BOTTOM(const int height)
112+
{
113+
return height - IMAGE_PADDING_BOTTOM;
114+
}
115+
116+
// Returns pd[row][column]
117+
inline int GET_MATRIX_DATA(const int* pD, const int row, int column, const int wS)
118+
{
119+
return *(pD + (row * wS) + column);
120+
}
121+
122+
// Returns the value of north-west corner of the kernel
123+
inline int GET_PIXEL_NW(const int* pD, const cv::Point2i& point, const int wS)
124+
{
125+
return GET_MATRIX_DATA(pD, point.y - HALF_KERNEL_SIZE, point.x - HALF_KERNEL_SIZE, wS);
126+
}
127+
128+
// Returns the value of north-east corner of the kernel
129+
inline int GET_PIXEL_NE(const int* pD, const cv::Point2i& point, const int wS)
130+
{
131+
return GET_MATRIX_DATA(pD, point.y - HALF_KERNEL_SIZE, point.x + HALF_KERNEL_SIZE, wS);
132+
}
133+
134+
// Returns the value of south-west corner of the kernel
135+
inline int GET_PIXEL_SW(const int* pD, const cv::Point2i& point, const int wS)
136+
{
137+
return GET_MATRIX_DATA(pD, point.y + HALF_KERNEL_SIZE, point.x - HALF_KERNEL_SIZE, wS);
138+
}
139+
140+
// Returns the value of south-east corner of the kernel
141+
inline int GET_PIXEL_SE(const int* pD, const cv::Point2i& point, const int wS)
142+
{
143+
return GET_MATRIX_DATA(pD, point.y + HALF_KERNEL_SIZE, point.x + HALF_KERNEL_SIZE, wS);
144+
}
145+
146+
// Returns a cv::Point2i which is the sum of two cv::Point2i
147+
inline cv::Point2i CV_POINT_PLUS(const cv::Point2i& p, const cv::Point2i& delta)
148+
{
149+
return cv::Point2i(p.x + delta.x, p.y + delta.y);
150+
}
151+
152+
// A class which represents the operations of BRIEF keypoint descriptor
153+
class BRIEF {
154+
public:
155+
// The constructor only pre-computes the tests locations:
156+
BRIEF(void);
157+
158+
// Destructor method:
159+
virtual ~BRIEF();
160+
161+
// Given keypoint kpt and image img, returns the BRIEF descriptor desc
162+
void getBriefDescriptor(bitset<DESC_LEN>& desc, cv::KeyPoint kpt, IplImage* img);
163+
164+
// Given keypoints kpts and image img, returns BRIEF descriptors descs
165+
void getBriefDescriptors(vector< bitset<DESC_LEN> >& descriptors, const vector<cv::KeyPoint>& kpts, IplImage* img);
166+
167+
private:
168+
// Choose the test locations arbitrarily
169+
void pickTestLocations(void);
170+
171+
// Allocate space for storing integral image
172+
void allocateIntegralImage(const IplImage* img);
173+
174+
// Checks if the tests locations for the keypoints in kpts lie inside an im_w x im_h image:
175+
bool validateKeypoints(const vector< cv::KeyPoint >& kpts, int im_w, int im_h);
176+
177+
// Returns true if kpt is inside the subimage
178+
bool isKeypointInsideSubImage(const cv::KeyPoint& kpt, const int width, const int height);
179+
180+
// Test locations used for intensity comparison tests
181+
vector< pair<cv::Point2i, cv::Point2i> > testLocations;
182+
183+
CvMat* integralImage;
184+
};
185+
186+
};
187+
188+
#endif

0 commit comments

Comments
 (0)