Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv_contrib
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
opencv_contrib
Commits
e2dfa357
Commit
e2dfa357
authored
May 16, 2015
by
GilLevi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added description of LATCH and fixed indentation
parent
292cee60
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
77 additions
and
64 deletions
+77
-64
xfeatures2d.hpp
modules/xfeatures2d/include/opencv2/xfeatures2d.hpp
+13
-0
latch.cpp
modules/xfeatures2d/src/latch.cpp
+64
-64
No files found.
modules/xfeatures2d/include/opencv2/xfeatures2d.hpp
View file @
e2dfa357
...
...
@@ -152,6 +152,19 @@ public:
/** latch Class for computing the LATCH descriptor.
If you find this code useful, please add a reference to the following paper in your work:
Gil Levi and Tal Hassner, "LATCH: Learned Arrangements of Three Patch Codes", arXiv preprint arXiv:1501.03719, 15 Jan. 2015
LATCH is a binary descriptor based on learned comparisons of triplets of image patches.
* bytes is the size of the descriptor - can be 64, 32, 16, 8, 4, 2 or 1
* rotationInvariance - whether or not the descriptor should compansate for orientation changes.
* half_ssd_size - the size of half of the mini-patches size. For example, if we would like to compare triplets of patches of size 7x7x
then the half_ssd_size should be (7-1)/2 = 3.
Note: the descriptor can be coupled with any keypoint extractor. The only demand is that if you use set rotationInvariance = True then
you will have to use an extractor which estimates the patch orientation (in degrees). Examples for such extractors are ORB and SIFT.
Note: a complete example can be found under /samples/cpp/tutorial_code/xfeatures2D/latch_match.cpp
*/
class
CV_EXPORTS
LATCHDescriptorExtractor
:
public
DescriptorExtractor
{
...
...
modules/xfeatures2d/src/latch.cpp
View file @
e2dfa357
...
...
@@ -52,15 +52,15 @@
namespace
cv
{
namespace
xfeatures2d
{
namespace
xfeatures2d
{
/*
/*
* LATCH Descriptor
*/
class
LATCHDescriptorExtractorImpl
:
public
LATCHDescriptorExtractor
{
public
:
{
public
:
enum
{
PATCH_SIZE
=
48
};
LATCHDescriptorExtractorImpl
(
int
bytes
=
32
,
bool
rotationInvariance
=
true
,
int
half_ssd_size
=
3
);
...
...
@@ -74,7 +74,7 @@ public:
virtual
void
compute
(
InputArray
image
,
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
descriptors
);
protected
:
protected
:
typedef
void
(
*
PixelTestFn
)(
const
Mat
&
input_image
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
);
int
bytes_
;
...
...
@@ -84,17 +84,17 @@ protected:
std
::
vector
<
int
>
sampling_points_
;
};
};
Ptr
<
LATCHDescriptorExtractor
>
LATCHDescriptorExtractor
::
create
(
int
bytes
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
{
return
makePtr
<
LATCHDescriptorExtractorImpl
>
(
bytes
,
rotationInvariance
,
half_ssd_size
);
}
void
Cacl
uateSums
(
int
count
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
const
Mat
&
grayImage
,
const
KeyPoint
&
pt
,
int
&
suma
,
int
&
sumc
,
float
cos_theta
,
float
sin_theta
,
int
half_ssd_size
);
}
void
Calc
uateSums
(
int
count
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
const
Mat
&
grayImage
,
const
KeyPoint
&
pt
,
int
&
suma
,
int
&
sumc
,
float
cos_theta
,
float
sin_theta
,
int
half_ssd_size
);
static
void
pixelTests1
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
static
void
pixelTests1
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
Mat
descriptors
=
_descriptors
.
getMat
();
for
(
int
i
=
0
;
i
<
(
int
)
keypoints
.
size
();
++
i
)
{
...
...
@@ -114,18 +114,18 @@ static void pixelTests1(const Mat& grayImage, const std::vector<KeyPoint>& keypo
int
suma
=
0
;
int
sumc
=
0
;
Cacl
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
Calc
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
desc
[
ix
]
+=
(
uchar
)((
suma
<
sumc
)
<<
j
);
count
+=
6
;
}
}
}
}
}
static
void
pixelTests2
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
static
void
pixelTests2
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
Mat
descriptors
=
_descriptors
.
getMat
();
for
(
int
i
=
0
;
i
<
(
int
)
keypoints
.
size
();
++
i
)
{
...
...
@@ -145,18 +145,18 @@ static void pixelTests2(const Mat& grayImage, const std::vector<KeyPoint>& keypo
int
suma
=
0
;
int
sumc
=
0
;
Cacl
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
Calc
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
desc
[
ix
]
+=
(
uchar
)((
suma
<
sumc
)
<<
j
);
count
+=
6
;
}
}
}
}
}
static
void
pixelTests4
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
static
void
pixelTests4
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
Mat
descriptors
=
_descriptors
.
getMat
();
for
(
int
i
=
0
;
i
<
(
int
)
keypoints
.
size
();
++
i
)
{
...
...
@@ -176,19 +176,19 @@ static void pixelTests4(const Mat& grayImage, const std::vector<KeyPoint>& keypo
int
suma
=
0
;
int
sumc
=
0
;
Cacl
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
Calc
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
desc
[
ix
]
+=
(
uchar
)((
suma
<
sumc
)
<<
j
);
count
+=
6
;
}
}
}
}
}
static
void
pixelTests8
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
static
void
pixelTests8
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
Mat
descriptors
=
_descriptors
.
getMat
();
for
(
int
i
=
0
;
i
<
(
int
)
keypoints
.
size
();
++
i
)
{
...
...
@@ -208,18 +208,18 @@ static void pixelTests8(const Mat& grayImage, const std::vector<KeyPoint>& keypo
int
suma
=
0
;
int
sumc
=
0
;
Cacl
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
Calc
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
desc
[
ix
]
+=
(
uchar
)((
suma
<
sumc
)
<<
j
);
count
+=
6
;
}
}
}
}
}
static
void
pixelTests16
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
static
void
pixelTests16
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
Mat
descriptors
=
_descriptors
.
getMat
();
for
(
int
i
=
0
;
i
<
(
int
)
keypoints
.
size
();
++
i
)
{
...
...
@@ -239,18 +239,18 @@ static void pixelTests16(const Mat& grayImage, const std::vector<KeyPoint>& keyp
int
suma
=
0
;
int
sumc
=
0
;
Cacl
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
Calc
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
desc
[
ix
]
+=
(
uchar
)((
suma
<
sumc
)
<<
j
);
count
+=
6
;
}
}
}
}
}
static
void
pixelTests32
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
static
void
pixelTests32
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
Mat
descriptors
=
_descriptors
.
getMat
();
for
(
int
i
=
0
;
i
<
(
int
)
keypoints
.
size
();
++
i
)
{
...
...
@@ -269,18 +269,18 @@ static void pixelTests32(const Mat& grayImage, const std::vector<KeyPoint>& keyp
int
suma
=
0
;
int
sumc
=
0
;
Cacl
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
Calc
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
desc
[
ix
]
+=
(
uchar
)((
suma
<
sumc
)
<<
j
);
count
+=
6
;
}
}
}
}
}
static
void
pixelTests64
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
static
void
pixelTests64
(
const
Mat
&
grayImage
,
const
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
int
half_ssd_size
)
{
Mat
descriptors
=
_descriptors
.
getMat
();
for
(
int
i
=
0
;
i
<
(
int
)
keypoints
.
size
();
++
i
)
{
...
...
@@ -300,18 +300,18 @@ static void pixelTests64(const Mat& grayImage, const std::vector<KeyPoint>& keyp
int
suma
=
0
;
int
sumc
=
0
;
Cacl
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
Calc
uateSums
(
count
,
points
,
rotationInvariance
,
grayImage
,
pt
,
suma
,
sumc
,
cos_theta
,
sin_theta
,
half_ssd_size
);
desc
[
ix
]
+=
(
uchar
)((
suma
<
sumc
)
<<
j
);
count
+=
6
;
}
}
}
}
}
void
Cacl
uateSums
(
int
count
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
const
Mat
&
grayImage
,
const
KeyPoint
&
pt
,
int
&
suma
,
int
&
sumc
,
float
cos_theta
,
float
sin_theta
,
int
half_ssd_size
)
void
Calc
uateSums
(
int
count
,
const
std
::
vector
<
int
>
&
points
,
bool
rotationInvariance
,
const
Mat
&
grayImage
,
const
KeyPoint
&
pt
,
int
&
suma
,
int
&
sumc
,
float
cos_theta
,
float
sin_theta
,
int
half_ssd_size
)
{
{
int
ax
=
points
[
count
];
int
ay
=
points
[
count
+
1
];
...
...
@@ -399,13 +399,13 @@ void CacluateSums(int count, const std::vector<int> &points, bool rotationInvari
}
}
}
}
LATCHDescriptorExtractorImpl
::
LATCHDescriptorExtractorImpl
(
int
bytes
,
bool
rotationInvariance
,
int
half_ssd_size
)
:
bytes_
(
bytes
),
test_fn_
(
NULL
),
rotationInvariance_
(
rotationInvariance
),
half_ssd_size_
(
half_ssd_size
)
{
LATCHDescriptorExtractorImpl
::
LATCHDescriptorExtractorImpl
(
int
bytes
,
bool
rotationInvariance
,
int
half_ssd_size
)
:
bytes_
(
bytes
),
test_fn_
(
NULL
),
rotationInvariance_
(
rotationInvariance
),
half_ssd_size_
(
half_ssd_size
)
{
switch
(
bytes
)
{
case
1
:
...
...
@@ -946,25 +946,25 @@ bytes_(bytes), test_fn_(NULL), rotationInvariance_(rotationInvariance), half_ssd
11
,
-
12
,
5
,
-
21
,
-
2
,
-
13
};
sampling_points_
.
assign
(
&
sampling_points_arr
[
0
],
&
sampling_points_arr
[
0
]
+
3072
);
}
}
int
LATCHDescriptorExtractorImpl
::
descriptorSize
()
const
{
int
LATCHDescriptorExtractorImpl
::
descriptorSize
()
const
{
return
bytes_
;
}
}
int
LATCHDescriptorExtractorImpl
::
descriptorType
()
const
{
int
LATCHDescriptorExtractorImpl
::
descriptorType
()
const
{
return
CV_8UC1
;
}
}
int
LATCHDescriptorExtractorImpl
::
defaultNorm
()
const
{
int
LATCHDescriptorExtractorImpl
::
defaultNorm
()
const
{
return
NORM_HAMMING
;
}
}
void
LATCHDescriptorExtractorImpl
::
read
(
const
FileNode
&
fn
)
{
void
LATCHDescriptorExtractorImpl
::
read
(
const
FileNode
&
fn
)
{
int
dSize
=
fn
[
"descriptorSize"
];
switch
(
dSize
)
{
...
...
@@ -993,17 +993,17 @@ void LATCHDescriptorExtractorImpl::read(const FileNode& fn)
CV_Error
(
Error
::
StsBadArg
,
"descriptorSize must be 1,2, 4, 8, 16, 32, or 64"
);
}
bytes_
=
dSize
;
}
}
void
LATCHDescriptorExtractorImpl
::
write
(
FileStorage
&
fs
)
const
{
void
LATCHDescriptorExtractorImpl
::
write
(
FileStorage
&
fs
)
const
{
fs
<<
"descriptorSize"
<<
bytes_
;
}
}
void
LATCHDescriptorExtractorImpl
::
compute
(
InputArray
image
,
void
LATCHDescriptorExtractorImpl
::
compute
(
InputArray
image
,
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
descriptors
)
{
{
Mat
grayImage
;
GaussianBlur
(
image
,
grayImage
,
cv
::
Size
(
3
,
3
),
2
,
2
);
...
...
@@ -1019,8 +1019,8 @@ void LATCHDescriptorExtractorImpl::compute(InputArray image,
descriptors
.
create
((
int
)
keypoints
.
size
(),
bytes_
,
CV_8U
);
test_fn_
(
grayImage
,
keypoints
,
descriptors
,
sampling_points_
,
rotationInvariance_
,
half_ssd_size_
);
}
}
}
}
}
// namespace cv
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment