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
9c1d01e2
Commit
9c1d01e2
authored
Oct 27, 2016
by
Balint Cristian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add BoostDesc Descriptor.
parent
2a637461
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1297 additions
and
6 deletions
+1297
-6
CMakeLists.txt
modules/xfeatures2d/CMakeLists.txt
+2
-2
download_boostdesc.cmake
modules/xfeatures2d/cmake/download_boostdesc.cmake
+30
-0
download_vgg.cmake
modules/xfeatures2d/cmake/download_vgg.cmake
+1
-1
xfeatures2d.bib
modules/xfeatures2d/doc/xfeatures2d.bib
+14
-0
xfeatures2d.hpp
modules/xfeatures2d/include/opencv2/xfeatures2d.hpp
+41
-0
export-boostdesc.py
modules/xfeatures2d/samples/export-boostdesc.py
+293
-0
boostdesc.cpp
modules/xfeatures2d/src/boostdesc.cpp
+731
-0
vgg.cpp
modules/xfeatures2d/src/vgg.cpp
+3
-3
test_features2d.cpp
modules/xfeatures2d/test/test_features2d.cpp
+56
-0
test_rotation_and_scale_invariance.cpp
...s/xfeatures2d/test/test_rotation_and_scale_invariance.cpp
+126
-0
No files found.
modules/xfeatures2d/CMakeLists.txt
View file @
9c1d01e2
set
(
the_description
"Contributed/Experimental Algorithms for Salient 2D Features Detection"
)
ocv_define_module
(
xfeatures2d opencv_core opencv_imgproc opencv_features2d opencv_calib3d opencv_shape opencv_highgui opencv_videoio opencv_ml
OPTIONAL opencv_cudaarithm WRAP python java
)
include
(
cmake/download_vgg.cmake
)
\ No newline at end of file
include
(
cmake/download_vgg.cmake
)
include
(
cmake/download_boostdesc.cmake
)
modules/xfeatures2d/cmake/download_boostdesc.cmake
0 → 100644
View file @
9c1d01e2
set
(
OPENCV_3RDPARTY_COMMIT
"34e4206aef44d50e6bbcd0ab06354b52e7466d26"
)
set
(
FILE_HASH_BOOSTDESC_BGM
"0ea90e7a8f3f7876d450e4149c97c74f"
)
set
(
FILE_HASH_BOOSTDESC_BGM_BI
"232c966b13651bd0e46a1497b0852191"
)
set
(
FILE_HASH_BOOSTDESC_BGM_HD
"324426a24fa56ad9c5b8e3e0b3e5303e"
)
set
(
FILE_HASH_BOOSTDESC_BINBOOST_064
"202e1b3e9fec871b04da31f7f016679f"
)
set
(
FILE_HASH_BOOSTDESC_BINBOOST_128
"98ea99d399965c03d555cef3ea502a0b"
)
set
(
FILE_HASH_BOOSTDESC_BINBOOST_256
"e6dcfa9f647779eb1ce446a8d759b6ea"
)
set
(
FILE_HASH_BOOSTDESC_LBGM
"0ae0675534aa318d9668f2a179c2a052"
)
set
(
BOOSTDESC_DOWNLOAD_URL
${
OPENCV_CONTRIB_BOOSTDESC_URL
}
;$ENV{OPENCV_CONTRIB_BOOSTDESC_URL};https://raw.githubusercontent.com/opencv/opencv_3rdparty/
${
OPENCV_3RDPARTY_COMMIT
}
/
)
function
(
boostdesc_download file id
)
message
(
STATUS
"Check contents of
${
file
}
..."
)
ocv_download
(
PACKAGE
${
file
}
HASH
${
FILE_HASH_
${
id
}}
URL
${
BOOSTDESC_DOWNLOAD_URL
}
DESTINATION_DIR
${
CMAKE_CURRENT_LIST_DIR
}
/../src
DOWNLOAD_DIR
${
CMAKE_CURRENT_LIST_DIR
}
/.download
)
endfunction
()
boostdesc_download
(
boostdesc_bgm.i BOOSTDESC_BGM
)
boostdesc_download
(
boostdesc_bgm_bi.i BOOSTDESC_BGM_BI
)
boostdesc_download
(
boostdesc_bgm_hd.i BOOSTDESC_BGM_HD
)
boostdesc_download
(
boostdesc_binboost_064.i BOOSTDESC_BINBOOST_064
)
boostdesc_download
(
boostdesc_binboost_128.i BOOSTDESC_BINBOOST_128
)
boostdesc_download
(
boostdesc_binboost_256.i BOOSTDESC_BINBOOST_256
)
boostdesc_download
(
boostdesc_lbgm.i BOOSTDESC_LBGM
)
modules/xfeatures2d/cmake/download_vgg.cmake
View file @
9c1d01e2
...
...
@@ -6,7 +6,7 @@ set(FILE_HASH_VGG_80 "7cd47228edec52b6d82f46511af325c5")
set
(
FILE_HASH_VGG_120
"151805e03568c9f490a5e3a872777b75"
)
set
(
VGG_DOWNLOAD_URL
${
OPENCV_CONTRIB_VGG_URL
}
;$ENV{OPENCV_CONTRIB_VGG_URL};https://raw.githubusercontent.com/
Itseez
/opencv_3rdparty/
${
OPENCV_3RDPARTY_COMMIT
}
/
)
set
(
VGG_DOWNLOAD_URL
${
OPENCV_CONTRIB_VGG_URL
}
;$ENV{OPENCV_CONTRIB_VGG_URL};https://raw.githubusercontent.com/
opencv
/opencv_3rdparty/
${
OPENCV_3RDPARTY_COMMIT
}
/
)
function
(
vgg_download file id
)
message
(
STATUS
"Check contents of
${
file
}
..."
)
...
...
modules/xfeatures2d/doc/xfeatures2d.bib
View file @
9c1d01e2
...
...
@@ -78,3 +78,17 @@
journal = "IEEE Transactions on Pattern Analysis and Machine Intelligence",
year = "2014"
}
@article{Trzcinski13b,
author = {T. Trzcinski, M. Christoudias and V. Lepetit},
title = {{Learning Image Descriptors with Boosting}},
journal = "submitted to IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI)",
year = {2013}
}
@inproceedings{Trzcinski13a,
author = {T. Trzcinski, M. Christoudias, V. Lepetit and P. Fua},
title = {{Boosting Binary Keypoint Descriptors}},
booktitle = "Computer Vision and Pattern Recognition",
year = {2013}
}
modules/xfeatures2d/include/opencv2/xfeatures2d.hpp
View file @
9c1d01e2
...
...
@@ -318,6 +318,47 @@ public:
};
/** @brief Class implementing BoostDesc (Learning Image Descriptors with Boosting), described in
@cite Trzcinski13a and @cite Trzcinski13b.
@param desc type of descriptor to use, BoostDesc::BINBOOST_256 is default (256 bit long dimension)
Available types are: BoostDesc::BGM, BoostDesc::BGM_HARD, BoostDesc::BGM_BILINEAR, BoostDesc::LBGM,
BoostDesc::BINBOOST_64, BoostDesc::BINBOOST_128, BoostDesc::BINBOOST_256
@param use_orientation sample patterns using keypoints orientation, enabled by default
@param scale_factor adjust the sampling window of detected keypoints
6.25f is default and fits for KAZE, SURF detected keypoints window ratio
6.75f should be the scale for SIFT detected keypoints window ratio
5.00f should be the scale for AKAZE, MSD, AGAST, FAST, BRISK keypoints window ratio
0.75f should be the scale for ORB keypoints ratio
1.50f was the default in original implementation
@note BGM is the base descriptor where each binary dimension is computed as the output of a single weak learner.
BGM_HARD and BGM_BILINEAR refers to same BGM but use different type of gradient binning. In the BGM_HARD that
use ASSIGN_HARD binning type the gradient is assigned to the nearest orientation bin. In the BGM_BILINEAR that use
ASSIGN_BILINEAR binning type the gradient is assigned to the two neighbouring bins. In the BGM and all other modes that use
ASSIGN_SOFT binning type the gradient is assigned to 8 nearest bins according to the cosine value between the gradient
angle and the bin center. LBGM (alias FP-Boost) is the floating point extension where each dimension is computed
as a linear combination of the weak learner responses. BINBOOST and subvariants are the binary extensions of LBGM
where each bit is computed as a thresholded linear combination of a set of weak learners.
BoostDesc header files (boostdesc_*.i) was exported from original binaries with export-boostdesc.py script from
samples subfolder.
*/
class
CV_EXPORTS_W
BoostDesc
:
public
Feature2D
{
public
:
CV_WRAP
enum
{
BGM
=
100
,
BGM_HARD
=
101
,
BGM_BILINEAR
=
102
,
LBGM
=
200
,
BINBOOST_64
=
300
,
BINBOOST_128
=
301
,
BINBOOST_256
=
302
};
CV_WRAP
static
Ptr
<
BoostDesc
>
create
(
int
desc
=
BoostDesc
::
BINBOOST_256
,
bool
use_scale_orientation
=
true
,
float
scale_factor
=
6.25
f
);
};
//! @}
}
...
...
modules/xfeatures2d/samples/export-boostdesc.py
0 → 100644
View file @
9c1d01e2
#!/usr/bin/python
"""
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2016
*
* Balint Cristian <cristian dot balint at gmail dot com>
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/
/* export-boostdesc.py */
/* Export C headers from binary data */
// [http://infoscience.epfl.ch/record/186246/files/boostDesc_1.0.tar.gz]
"""
import
sys
import
struct
def
float_to_hex
(
f
):
return
struct
.
unpack
(
'<I'
,
struct
.
pack
(
'<f'
,
f
)
)[
0
]
def
main
():
# usage
if
(
len
(
sys
.
argv
)
<
3
):
print
(
"Usage:
%
s <binary-type (BGM, LBGM, BINBOOST)> <boostdesc-binary-filename>"
%
sys
.
argv
[
0
]
)
sys
.
exit
(
0
)
if
(
(
sys
.
argv
[
1
]
!=
"BGM"
)
and
(
sys
.
argv
[
1
]
!=
"LBGM"
)
and
(
sys
.
argv
[
1
]
!=
"BINBOOST"
)
):
print
(
"Invalid type [
%
s]"
%
sys
.
argv
[
1
]
)
sys
.
exit
(
0
)
# enum literals
Assign
=
[
"ASSIGN_HARD"
,
"ASSIGN_BILINEAR"
,
"ASSIGN_SOFT"
,
"ASSIGN_HARD_MAGN"
,
"ASSIGN_SOFT_MAGN"
]
# open binary data file
f
=
open
(
sys
.
argv
[
2
],
'rb'
)
# header
print
"/*"
print
" *"
print
" * Header exported from binary."
print
" * [
%
s
%
s
%
s]"
%
(
sys
.
argv
[
0
],
sys
.
argv
[
1
],
sys
.
argv
[
2
]
)
print
" *"
print
" */"
# ini
nDim
=
1
;
nWLs
=
0
;
# dimensionality (where is the case)
if
(
(
sys
.
argv
[
1
]
==
"LBGM"
)
or
(
sys
.
argv
[
1
]
==
"BINBOOST"
)
):
nDim
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
print
print
"// dimensionality of learner"
print
"static const int nDim =
%
i;"
%
nDim
# week learners (where is the case)
if
(
sys
.
argv
[
1
]
!=
"BINBOOST"
):
nWLs
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
# common header
orientQuant
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
patchSize
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
iGradAssignType
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
print
print
"// orientations"
print
"static const int orientQuant =
%
i;"
%
orientQuant
print
print
"// patch size"
print
"static const int patchSize =
%
i;"
%
patchSize
print
print
"// gradient assignment type"
print
"static const int iGradAssignType =
%
s;"
%
Assign
[
iGradAssignType
]
arr_thresh
=
""
arr_orient
=
""
arr__y_min
=
""
arr__y_max
=
""
arr__x_min
=
""
arr__x_max
=
""
arr__alpha
=
""
arr___beta
=
""
dims
=
nDim
if
(
sys
.
argv
[
1
]
==
"LBGM"
):
dims
=
1
# iterate each dimension
for
d
in
range
(
0
,
dims
):
if
(
sys
.
argv
[
1
]
==
"BINBOOST"
):
nWLs
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
if
(
d
==
0
):
print
print
"// number of weak learners"
print
"static const int nWLs =
%
i;"
%
nWLs
# iterate each members
for
i
in
range
(
0
,
nWLs
):
# unpack structure array
thresh
=
struct
.
unpack
(
'<f'
,
f
.
read
(
4
)
)[
0
]
orient
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
y_min
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
y_max
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
x_min
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
x_max
=
struct
.
unpack
(
'<i'
,
f
.
read
(
4
)
)[
0
]
alpha
=
struct
.
unpack
(
'<f'
,
f
.
read
(
4
)
)[
0
]
beta
=
0
if
(
sys
.
argv
[
1
]
==
"BINBOOST"
):
beta
=
struct
.
unpack
(
'<f'
,
f
.
read
(
4
)
)[
0
]
# first entry
if
(
d
*
dims
+
i
==
0
):
arr_thresh
+=
"
\n
"
arr_thresh
+=
"// threshold array (
%
s x
%
s)
\n
"
%
(
dims
,
nWLs
)
arr_thresh
+=
"static const unsigned int thresh[] =
\n
{
\n
"
arr_orient
+=
"
\n
"
arr_orient
+=
"// orientation array (
%
s x
%
s)
\n
"
%
(
dims
,
nWLs
)
arr_orient
+=
"static const int orient[] =
\n
{
\n
"
arr__y_min
+=
"
\n
"
arr__y_min
+=
"// Y min array (
%
s x
%
s)
\n
"
%
(
dims
,
nWLs
)
arr__y_min
+=
"static const int y_min[] =
\n
{
\n
"
arr__y_max
+=
"
\n
"
arr__y_max
+=
"// Y max array (
%
s x
%
s)
\n
"
%
(
dims
,
nWLs
)
arr__y_max
+=
"static const int y_max[] =
\n
{
\n
"
arr__x_min
+=
"
\n
"
arr__x_min
+=
"// X min array (
%
s x
%
s)
\n
"
%
(
dims
,
nWLs
)
arr__x_min
+=
"static const int x_min[] =
\n
{
\n
"
arr__x_max
+=
"
\n
"
arr__x_max
+=
"// X max array (
%
s x
%
s)
\n
"
%
(
dims
,
nWLs
)
arr__x_max
+=
"static const int x_max[] =
\n
{
\n
"
arr__alpha
+=
"
\n
"
arr__alpha
+=
"// alpha array (
%
s x
%
s)
\n
"
%
(
dims
,
nWLs
)
arr__alpha
+=
"static const unsigned int alpha[] =
\n
{
\n
"
if
(
sys
.
argv
[
1
]
==
"BINBOOST"
):
arr___beta
+=
"
\n
"
arr___beta
+=
"// beta array (
%
s x
%
s)
\n
"
%
(
dims
,
nWLs
)
arr___beta
+=
"static const unsigned int beta[] =
\n
{
\n
"
# last entry
if
(
i
==
nWLs
-
1
)
and
(
d
==
dims
-
1
):
arr_thresh
+=
" 0x
%08
x
\n
};"
%
float_to_hex
(
thresh
)
arr_orient
+=
" 0x
%02
x
\n
};"
%
orient
arr__y_min
+=
" 0x
%02
x
\n
};"
%
y_min
arr__y_max
+=
" 0x
%02
x
\n
};"
%
y_max
arr__x_min
+=
" 0x
%02
x
\n
};"
%
x_min
arr__x_max
+=
" 0x
%02
x
\n
};"
%
x_max
arr__alpha
+=
" 0x
%08
x
\n
};"
%
float_to_hex
(
alpha
)
if
(
sys
.
argv
[
1
]
==
"BINBOOST"
):
arr___beta
+=
" 0x
%08
x
\n
};"
%
float_to_hex
(
beta
)
break
# align entries
if
(
(
d
*
dims
+
i
+
1
)
%
8
):
arr_thresh
+=
" 0x
%08
x,"
%
float_to_hex
(
thresh
)
arr_orient
+=
" 0x
%02
x,"
%
orient
arr__y_min
+=
" 0x
%02
x,"
%
y_min
arr__y_max
+=
" 0x
%02
x,"
%
y_max
arr__x_min
+=
" 0x
%02
x,"
%
x_min
arr__x_max
+=
" 0x
%02
x,"
%
x_max
arr__alpha
+=
" 0x
%08
x,"
%
float_to_hex
(
alpha
)
if
(
sys
.
argv
[
1
]
==
"BINBOOST"
):
arr___beta
+=
" 0x
%08
x,"
%
float_to_hex
(
beta
)
else
:
arr_thresh
+=
" 0x
%08
x,
\n
"
%
float_to_hex
(
thresh
)
arr_orient
+=
" 0x
%02
x,
\n
"
%
orient
arr__y_min
+=
" 0x
%02
x,
\n
"
%
y_min
arr__y_max
+=
" 0x
%02
x,
\n
"
%
y_max
arr__x_min
+=
" 0x
%02
x,
\n
"
%
x_min
arr__x_max
+=
" 0x
%02
x,
\n
"
%
x_max
arr__alpha
+=
" 0x
%08
x,
\n
"
%
float_to_hex
(
alpha
)
if
(
sys
.
argv
[
1
]
==
"BINBOOST"
):
arr___beta
+=
" 0x
%08
x,
\n
"
%
float_to_hex
(
beta
)
# extra array (when LBGM)
if
(
sys
.
argv
[
1
]
==
"LBGM"
):
arr___beta
+=
"
\n
"
arr___beta
+=
"// beta array (
%
s x
%
s)
\n
"
%
(
nWLs
,
nDim
)
arr___beta
+=
"static const unsigned int beta[] =
\n
{
\n
"
for
i
in
range
(
0
,
nWLs
):
for
d
in
range
(
0
,
nDim
):
beta
=
struct
.
unpack
(
'<f'
,
f
.
read
(
4
)
)[
0
]
# last entry
if
(
i
==
nWLs
-
1
)
and
(
d
==
nDim
-
1
):
arr___beta
+=
" 0x
%08
x
\n
};"
%
float_to_hex
(
beta
)
break
# align entries
if
(
(
i
*
nDim
+
d
+
1
)
%
8
):
arr___beta
+=
" 0x
%08
x,"
%
float_to_hex
(
beta
)
else
:
arr___beta
+=
" 0x
%08
x,
\n
"
%
float_to_hex
(
beta
)
# release
f
.
close
()
# dump on screen
print
arr_thresh
print
arr_orient
print
arr__y_min
print
arr__y_max
print
arr__x_min
print
arr__x_max
print
arr__alpha
if
(
(
sys
.
argv
[
1
]
==
"LBGM"
)
or
(
sys
.
argv
[
1
]
==
"BINBOOST"
)
):
print
arr___beta
if
__name__
==
"__main__"
:
main
()
modules/xfeatures2d/src/boostdesc.cpp
0 → 100644
View file @
9c1d01e2
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2013, 2016
*
* Tomasz Trzcinski <t dot trzcinski at ii dot pw dot edu dot pl>
* Mario Christoudias <mariochristoudias at gmail dot com>
* Vincent Lepetit <lepetit at icg dot tugraz dot at>
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/
/*
"Learning Image Descriptors with Boosting"
T. Trzcinski, M. Christoudias and V. Lepetit
IEEE Transactions on Pattern Analysis and Machine Intelligence, 2013
"Boosting Binary Keypoint Descriptors"
T. Trzcinski, M. Christoudias, V. Lepetit and P. Fua
Computer Vision and Pattern Recognition (CVPR), 2013
Original code: Tomasz Trzcinski <t dot trzcinski at ii dot pw dot edu dot pl>
OpenCV port by: Cristian Balint <cristian dot balint at gmail dot com>
*/
#include <bitset>
#include "precomp.hpp"
using
namespace
cv
;
using
namespace
std
;
namespace
cv
{
namespace
xfeatures2d
{
/*
!BoostDesc implementation
*/
class
BoostDesc_Impl
:
public
BoostDesc
{
public
:
// constructor
explicit
BoostDesc_Impl
(
int
desc
=
BINBOOST_256
,
bool
use_scale_orientation
=
true
,
float
scale_factor
=
6.25
f
);
// destructor
virtual
~
BoostDesc_Impl
();
// returns the descriptor length in bytes
virtual
int
descriptorSize
()
const
{
return
m_descriptor_size
;
}
// returns the descriptor type
virtual
int
descriptorType
()
const
{
return
m_descriptor_type
;
}
// returns the default norm type
virtual
int
defaultNorm
()
const
{
return
m_descriptor_norm
;
}
// compute descriptors given keypoints
virtual
void
compute
(
InputArray
image
,
vector
<
KeyPoint
>&
keypoints
,
OutputArray
descriptors
);
protected
:
/*
* BoostDesc parameters
*/
// size, type, norm
int
m_descriptor_size
;
int
m_descriptor_type
;
int
m_descriptor_norm
;
// desc type
int
m_desc_type
;
// gradient
// assignment types
enum
Assign
{
ASSIGN_HARD
=
0
,
ASSIGN_BILINEAR
=
1
,
ASSIGN_SOFT
=
2
,
ASSIGN_HARD_MAGN
=
3
,
ASSIGN_SOFT_MAGN
=
4
};
// dims
int
m_Dims
;
// no. weak
// learners
int
m_nWLs
;
// gradient type
int
m_grad_atype
;
// patch size
int
m_patch_size
;
// orient quantitiy
int
m_orient_q
;
// patch scale factor
float
m_scale_factor
;
/*
* BoostDesc switches
*/
// switch to enable sample by keypoints orientation
bool
m_use_scale_orientation
;
/*
* BoostDesc arrays
*/
// image
Mat
m_image
;
// parameters
// weak learner
Mat
m_wl_thresh
;
Mat
m_wl_orient
;
Mat
m_wl_x_min
,
m_wl_x_max
;
Mat
m_wl_y_min
,
m_wl_y_max
;
Mat
m_wl_alpha
,
m_wl_beta
;
private
:
/*
* BoostDesc functions
*/
// initialize parameters
inline
void
ini_params
(
const
int
orientQuant
,
const
int
patchSize
,
const
int
iGradAssignType
,
const
int
nDim
,
const
int
nWLs
,
const
unsigned
int
thresh
[],
const
int
orient
[],
const
int
x_min
[],
const
int
x_max
[],
const
int
y_min
[],
const
int
y_max
[],
const
unsigned
int
alpha
[],
const
unsigned
int
beta
[]
);
};
// END BoostDesc_Impl CLASS
// -------------------------------------------------
/* BoostDesc internal routines */
static
void
computeGradientMaps
(
const
Mat
&
im
,
const
int
gradAssignType
,
const
int
orientQuant
,
vector
<
Mat
>&
gradMap
)
{
enum
Assign
{
ASSIGN_HARD
=
0
,
ASSIGN_BILINEAR
=
1
,
ASSIGN_SOFT
=
2
,
ASSIGN_HARD_MAGN
=
3
,
ASSIGN_SOFT_MAGN
=
4
};
Mat
derivx
(
im
.
size
(),
CV_32FC1
);
Mat
derivy
(
im
.
size
(),
CV_32FC1
);
Sobel
(
im
,
derivx
,
derivx
.
depth
(),
1
,
0
);
Sobel
(
im
,
derivy
,
derivy
.
depth
(),
0
,
1
);
for
(
int
i
=
0
;
i
<
orientQuant
;
i
++
)
gradMap
.
push_back
(
Mat
::
zeros
(
im
.
size
(),
CV_8UC1
)
);
int
index
,
index2
;
double
binCenter
,
weight
;
double
binSize
=
(
2
*
CV_PI
)
/
orientQuant
;
// fill in temp matrices with
// respones to edge detection
const
float
*
pDerivx
=
derivx
.
ptr
<
float
>
();
const
float
*
pDerivy
=
derivy
.
ptr
<
float
>
();
for
(
int
i
=
0
;
i
<
im
.
rows
;
i
++
)
{
for
(
int
j
=
0
;
j
<
im
.
cols
;
j
++
)
{
float
gradMagnitude
=
sqrt
(
(
*
pDerivx
)
*
(
*
pDerivx
)
+
(
*
pDerivy
)
*
(
*
pDerivy
)
);
if
(
gradMagnitude
>
20
)
{
double
theta
=
atan2
(
*
pDerivy
,
*
pDerivx
);
theta
=
(
theta
<
0
)
?
theta
+
2
*
CV_PI
:
theta
;
index
=
int
(
theta
/
binSize
);
index
=
(
index
==
orientQuant
)
?
0
:
index
;
switch
(
gradAssignType
)
{
case
ASSIGN_HARD
:
gradMap
[
index
].
at
<
uchar
>
(
i
,
j
)
=
1
;
break
;
case
ASSIGN_HARD_MAGN
:
gradMap
[
index
].
at
<
uchar
>
(
i
,
j
)
=
(
uchar
)
round
(
gradMagnitude
);
break
;
case
ASSIGN_BILINEAR
:
index2
=
(
int
)
ceil
(
theta
/
binSize
);
index2
=
(
index2
==
orientQuant
)
?
0
:
index2
;
binCenter
=
(
index
+
0.5
f
)
*
binSize
;
weight
=
1
-
abs
(
theta
-
binCenter
)
/
binSize
;
gradMap
[
index
].
at
<
uchar
>
(
i
,
j
)
=
(
uchar
)
round
(
255
*
weight
);
gradMap
[
index2
].
at
<
uchar
>
(
i
,
j
)
=
(
uchar
)
round
(
255
*
(
1
-
weight
)
);
break
;
case
ASSIGN_SOFT
:
for
(
int
binNum
=
0
;
binNum
<
orientQuant
/
2
+
1
;
binNum
++
)
{
index2
=
(
binNum
+
index
+
orientQuant
-
orientQuant
/
4
)
%
orientQuant
;
binCenter
=
(
index2
+
0.5
f
)
*
binSize
;
weight
=
cos
(
theta
-
binCenter
);
weight
=
(
weight
<
0
)
?
0
:
weight
;
gradMap
[
index2
].
at
<
uchar
>
(
i
,
j
)
=
(
uchar
)
round
(
255
*
weight
);
}
break
;
case
ASSIGN_SOFT_MAGN
:
for
(
int
binNum
=
0
;
binNum
<
orientQuant
/
2
+
1
;
binNum
++
)
{
index2
=
(
binNum
+
index
+
orientQuant
-
orientQuant
/
4
)
%
orientQuant
;
binCenter
=
(
index2
+
0.5
f
)
*
binSize
;
weight
=
cos
(
theta
-
binCenter
);
weight
=
(
weight
<
0
)
?
0
:
weight
;
gradMap
[
index2
].
at
<
uchar
>
(
i
,
j
)
=
(
uchar
)
round
(
gradMagnitude
*
weight
);
}
break
;
}
// end switch
}
++
pDerivy
;
++
pDerivx
;
}
}
}
static
void
computeIntegrals
(
const
vector
<
Mat
>&
gradMap
,
const
int
orientQuant
,
vector
<
Mat
>&
integralMap
)
{
// init integral images
int
rows
=
gradMap
[
0
].
rows
;
int
cols
=
gradMap
[
0
].
cols
;
for
(
int
i
=
0
;
i
<
orientQuant
+
1
;
i
++
)
integralMap
.
push_back
(
Mat
::
zeros
(
rows
+
1
,
cols
+
1
,
CV_8UC1
)
);
// generate corresponding integral images
for
(
int
i
=
0
;
i
<
orientQuant
;
i
++
)
integral
(
gradMap
[
i
],
integralMap
[
i
]
);
// copy the values from the first quantization bin
integralMap
[
0
].
copyTo
(
integralMap
[
orientQuant
]
);
int
*
ptrSum
,
*
ptr
;
for
(
int
k
=
1
;
k
<
orientQuant
;
k
++
)
{
ptr
=
(
int
*
)
integralMap
[
k
].
ptr
<
int
>
();
ptrSum
=
(
int
*
)
integralMap
[
orientQuant
].
ptr
<
int
>
();
for
(
int
i
=
0
;
i
<
(
rows
+
1
)
*
(
cols
+
1
);
++
i
)
{
*
ptrSum
+=
*
ptr
;
++
ptrSum
;
++
ptr
;
}
}
}
static
float
computeWLResponse
(
const
int
x_min
,
const
int
x_max
,
const
int
y_min
,
const
int
y_max
,
const
int
orient
,
const
float
thresh
,
const
int
orientQuant
,
const
vector
<
Mat
>&
integralMap
)
{
const
int
width
=
integralMap
[
0
].
cols
;
const
int
idx1
=
(
y_min
)
*
width
+
x_min
;
const
int
idx2
=
(
y_min
)
*
width
+
x_max
+
1
;
const
int
idx3
=
(
y_max
+
1
)
*
width
+
x_min
;
const
int
idx4
=
(
y_max
+
1
)
*
width
+
x_max
+
1
;
const
int
*
ptr
=
integralMap
[
orient
].
ptr
<
int
>
();
int
A
,
B
,
C
,
D
;
A
=
ptr
[
idx1
];
B
=
ptr
[
idx2
];
C
=
ptr
[
idx3
];
D
=
ptr
[
idx4
];
const
float
current
=
float
(
D
+
A
-
B
-
C
);
ptr
=
integralMap
[
orientQuant
].
ptr
<
int
>
();
A
=
ptr
[
idx1
];
B
=
ptr
[
idx2
];
C
=
ptr
[
idx3
];
D
=
ptr
[
idx4
];
const
float
total
=
float
(
D
+
A
-
B
-
C
);
return
total
?
(
(
current
/
total
)
-
thresh
)
:
0.
f
;
}
static
void
rectifyPatch
(
const
Mat
&
image
,
const
KeyPoint
&
kp
,
const
int
&
patchSize
,
Mat
&
patch
,
const
bool
use_scale_orientation
,
const
float
scale_factor
)
{
Mat
M
;
if
(
use_scale_orientation
)
{
const
float
s
=
scale_factor
*
(
float
)
kp
.
size
/
(
float
)
patchSize
;
const
float
cosine
=
(
kp
.
angle
>=
0
)
?
cos
(
kp
.
angle
*
(
float
)
CV_PI
/
180.0
f
)
:
1.
f
;
const
float
sine
=
(
kp
.
angle
>=
0
)
?
sin
(
kp
.
angle
*
(
float
)
CV_PI
/
180.0
f
)
:
0.
f
;
float
M_
[]
=
{
s
*
cosine
,
-
s
*
sine
,
(
-
s
*
cosine
+
s
*
sine
)
*
patchSize
/
2.0
f
+
kp
.
pt
.
x
,
s
*
sine
,
s
*
cosine
,
(
-
s
*
sine
-
s
*
cosine
)
*
patchSize
/
2.0
f
+
kp
.
pt
.
y
};
M
=
Mat
(
2
,
3
,
CV_32FC1
,
M_
).
clone
();
}
else
{
float
M_
[]
=
{
1.
f
,
0.
f
,
-
1.
f
*
patchSize
/
2.0
f
+
kp
.
pt
.
x
,
0.
f
,
1.
f
,
-
1.
f
*
patchSize
/
2.0
f
+
kp
.
pt
.
y
};
M
=
Mat
(
2
,
3
,
CV_32FC1
,
M_
).
clone
();
}
warpAffine
(
image
,
patch
,
M
,
Size
(
patchSize
,
patchSize
),
WARP_INVERSE_MAP
+
INTER_CUBIC
+
WARP_FILL_OUTLIERS
);
}
// -------------------------------------------------
/* BoostDesc interface implementation */
struct
ComputeBoostDescInvoker
:
ParallelLoopBody
{
ComputeBoostDescInvoker
(
const
Mat
&
_image
,
Mat
*
_descriptors
,
const
vector
<
KeyPoint
>&
_keypoints
,
const
int
_desc_type
,
const
int
_grad_atype
,
const
int
_orient_q
,
const
int
_patch_size
,
const
int
_nWLs
,
const
int
_Dims
,
const
Mat
&
_wl_x_min
,
const
Mat
&
_wl_x_max
,
const
Mat
&
_wl_y_min
,
const
Mat
&
_wl_y_max
,
const
Mat
&
_wl_thresh
,
const
Mat
&
_wl_orient
,
const
Mat
&
_wl_alpha
,
const
Mat
&
_wl_beta
,
const
bool
_use_scale_orientation
,
const
float
_scale_factor
)
{
nWLs
=
_nWLs
;
Dims
=
_Dims
;
image
=
_image
;
orient_q
=
_orient_q
;
desc_type
=
_desc_type
;
keypoints
=
_keypoints
;
grad_atype
=
_grad_atype
;
patch_size
=
_patch_size
;
descriptors
=
_descriptors
;
wl_beta
=
_wl_beta
;
wl_alpha
=
_wl_alpha
;
wl_x_min
=
_wl_x_min
;
wl_x_max
=
_wl_x_max
;
wl_y_min
=
_wl_y_min
;
wl_y_max
=
_wl_y_max
;
wl_thresh
=
_wl_thresh
;
wl_orient
=
_wl_orient
;
scale_factor
=
_scale_factor
;
use_scale_orientation
=
_use_scale_orientation
;
}
void
operator
()(
const
cv
::
Range
&
range
)
const
{
// maps
vector
<
Mat
>
gradMap
,
integralMap
;
// small binary map
uchar
binLookUp
[
8
];
for
(
unsigned
int
i
=
0
;
i
<
8
;
i
++
)
binLookUp
[
i
]
=
(
uchar
)
1
<<
i
;
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Mat
patch
;
// rectify the patch around a given keypoint
rectifyPatch
(
image
,
keypoints
[
i
],
patch_size
,
patch
,
use_scale_orientation
,
scale_factor
);
// compute gradient maps (and integral gradient maps)
computeGradientMaps
(
patch
,
grad_atype
,
orient_q
,
gradMap
);
computeIntegrals
(
gradMap
,
orient_q
,
integralMap
);
float
WLR
;
/*
* BGM
*/
if
(
(
desc_type
==
BGM
)
||
(
desc_type
==
BGM_HARD
)
||
(
desc_type
==
BGM_BILINEAR
)
)
{
uchar
*
desc
=
descriptors
->
ptr
<
uchar
>
(
i
);
for
(
int
j
=
0
;
j
<
nWLs
;
j
++
)
{
WLR
=
computeWLResponse
(
wl_x_min
.
at
<
int
>
(
0
,
j
),
wl_x_max
.
at
<
int
>
(
0
,
j
),
wl_y_min
.
at
<
int
>
(
0
,
j
),
wl_y_max
.
at
<
int
>
(
0
,
j
),
wl_orient
.
at
<
int
>
(
0
,
j
),
wl_thresh
.
at
<
float
>
(
0
,
j
),
orient_q
,
integralMap
);
desc
[
j
/
8
]
|=
(
WLR
>=
0
)
?
binLookUp
[
j
%
8
]
:
0
;
}
}
// end BGM
/*
* LBGM
*/
if
(
desc_type
==
LBGM
)
{
std
::
bitset
<
512
>
wlResponses
;
for
(
int
j
=
0
;
j
<
nWLs
;
j
++
)
{
WLR
=
computeWLResponse
(
wl_x_min
.
at
<
int
>
(
0
,
j
),
wl_x_max
.
at
<
int
>
(
0
,
j
),
wl_y_min
.
at
<
int
>
(
0
,
j
),
wl_y_max
.
at
<
int
>
(
0
,
j
),
wl_orient
.
at
<
int
>
(
0
,
j
),
wl_thresh
.
at
<
float
>
(
0
,
j
),
orient_q
,
integralMap
);
wlResponses
[
j
]
=
(
WLR
>=
0
)
?
1
:
0
;
}
float
*
desc
=
descriptors
->
ptr
<
float
>
(
i
);
for
(
int
d
=
0
;
d
<
Dims
;
d
++
)
{
for
(
int
wl
=
0
;
wl
<
nWLs
;
wl
++
)
{
desc
[
d
]
+=
(
wlResponses
[
wl
]
)
?
wl_beta
.
at
<
float
>
(
wl
,
d
)
:
-
wl_beta
.
at
<
float
>
(
wl
,
d
);
}
}
}
// end LBGM
/*
* BINBOOST
*/
if
(
(
desc_type
==
BINBOOST_64
)
||
(
desc_type
==
BINBOOST_128
)
||
(
desc_type
==
BINBOOST_256
)
)
{
float
resp
;
for
(
int
d
=
0
;
d
<
Dims
;
d
++
)
{
resp
=
0
;
uchar
*
desc
=
descriptors
->
ptr
<
uchar
>
(
i
);
for
(
int
wl
=
0
;
wl
<
nWLs
;
wl
++
)
{
WLR
=
computeWLResponse
(
wl_x_min
.
at
<
int
>
(
d
,
wl
),
wl_x_max
.
at
<
int
>
(
d
,
wl
),
wl_y_min
.
at
<
int
>
(
d
,
wl
),
wl_y_max
.
at
<
int
>
(
d
,
wl
),
wl_orient
.
at
<
int
>
(
d
,
wl
),
wl_thresh
.
at
<
float
>
(
d
,
wl
),
orient_q
,
integralMap
);
resp
+=
(
WLR
>=
0
)
?
wl_beta
.
at
<
float
>
(
d
,
wl
)
:
-
wl_beta
.
at
<
float
>
(
d
,
wl
);
}
desc
[
d
/
8
]
|=
(
resp
>=
0
)
?
binLookUp
[
d
%
8
]
:
0
;
}
}
// end BINBOOST
// clean-up
patch
.
release
();
gradMap
.
clear
();
integralMap
.
clear
();
}
// end for loop
}
// end operator
int
nWLs
;
int
Dims
;
int
orient_q
;
int
desc_type
;
int
patch_size
;
int
grad_atype
;
int
patch_szie
;
Mat
image
;
Mat
*
descriptors
;
vector
<
KeyPoint
>
keypoints
;
Mat
wl_x_min
,
wl_x_max
,
wl_y_min
,
wl_y_max
;
Mat
wl_thresh
,
wl_orient
,
wl_alpha
,
wl_beta
;
float
scale_factor
;
bool
use_scale_orientation
;
enum
{
BGM
=
100
,
BGM_HARD
=
101
,
BGM_BILINEAR
=
102
,
LBGM
=
200
,
BINBOOST_64
=
300
,
BINBOOST_128
=
301
,
BINBOOST_256
=
302
};
};
// descriptor computation using keypoints
void
BoostDesc_Impl
::
compute
(
InputArray
_image
,
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
)
{
// do nothing if no image
if
(
_image
.
getMat
().
empty
()
)
return
;
if
(
keypoints
.
empty
()
)
return
;
m_image
=
_image
.
getMat
().
clone
();
// Only 8bit images
CV_Assert
(
m_image
.
depth
()
==
CV_8U
);
// convert to gray inplace
if
(
m_image
.
channels
()
>
1
)
cvtColor
(
m_image
,
m_image
,
COLOR_BGR2GRAY
);
// initialize the variables
_descriptors
.
create
(
(
int
)
keypoints
.
size
(),
descriptorSize
(),
descriptorType
()
);
_descriptors
.
setTo
(
Scalar
::
all
(
0
)
);
// descriptor storage
Mat
descriptors
=
_descriptors
.
getMat
();
parallel_for_
(
Range
(
0
,
(
int
)
keypoints
.
size
()
),
ComputeBoostDescInvoker
(
m_image
,
&
descriptors
,
keypoints
,
m_desc_type
,
m_grad_atype
,
m_orient_q
,
m_patch_size
,
m_nWLs
,
m_Dims
,
m_wl_x_min
,
m_wl_x_max
,
m_wl_y_min
,
m_wl_y_max
,
m_wl_thresh
,
m_wl_orient
,
m_wl_alpha
,
m_wl_beta
,
m_use_scale_orientation
,
m_scale_factor
)
);
}
void
BoostDesc_Impl
::
ini_params
(
const
int
orientQuant
,
const
int
patchSize
,
const
int
iGradAssignType
,
const
int
nDim
,
const
int
nWLs
,
const
unsigned
int
thresh
[],
const
int
orient
[],
const
int
x_min
[],
const
int
x_max
[],
const
int
y_min
[],
const
int
y_max
[],
const
unsigned
int
alpha
[],
const
unsigned
int
beta
[]
)
{
// desc type, norm, size
if
(
m_desc_type
==
LBGM
)
{
m_descriptor_size
=
nDim
;
m_descriptor_norm
=
NORM_L2
;
m_descriptor_type
=
CV_32FC1
;
}
else
{
if
(
(
m_desc_type
==
BGM
)
||
(
m_desc_type
==
BGM_HARD
)
||
(
m_desc_type
==
BGM_BILINEAR
)
)
m_descriptor_size
=
nWLs
/
8
;
else
m_descriptor_size
=
nDim
/
8
;
m_descriptor_type
=
CV_8UC1
;
m_descriptor_norm
=
NORM_HAMMING
;
}
// 2d array dim
int
dim0
=
nDim
;
int
dim1
=
nWLs
;
// override beta dim0 on LBGM
if
(
m_desc_type
==
LBGM
)
dim0
=
1
;
m_Dims
=
nDim
;
m_nWLs
=
nWLs
;
m_orient_q
=
orientQuant
;
m_patch_size
=
patchSize
;
m_grad_atype
=
iGradAssignType
;
// cast into opencv Mat type as float
m_wl_thresh
=
Mat
(
dim0
,
dim1
,
CV_32F
,
reinterpret_cast
<
float
*>
(
const_cast
<
unsigned
int
*>
(
thresh
))
);
m_wl_alpha
=
Mat
(
dim0
,
dim1
,
CV_32F
,
reinterpret_cast
<
float
*>
(
const_cast
<
unsigned
int
*>
(
alpha
))
);
// cast into opencv Mat type as integer
m_wl_orient
=
Mat
(
dim0
,
dim1
,
CV_32S
,
const_cast
<
int
*>
(
orient
)
);
m_wl_x_min
=
Mat
(
dim0
,
dim1
,
CV_32S
,
const_cast
<
int
*>
(
x_min
)
);
m_wl_x_max
=
Mat
(
dim0
,
dim1
,
CV_32S
,
const_cast
<
int
*>
(
x_max
)
);
m_wl_y_min
=
Mat
(
dim0
,
dim1
,
CV_32S
,
const_cast
<
int
*>
(
y_min
)
);
m_wl_y_max
=
Mat
(
dim0
,
dim1
,
CV_32S
,
const_cast
<
int
*>
(
y_max
)
);
// no beta
if
(
beta
==
NULL
)
return
;
if
(
m_desc_type
==
LBGM
)
m_wl_beta
=
Mat
(
dim1
,
nDim
,
CV_32F
,
reinterpret_cast
<
float
*>
(
const_cast
<
unsigned
int
*>
(
beta
))
);
else
m_wl_beta
=
Mat
(
dim0
,
dim1
,
CV_32F
,
reinterpret_cast
<
float
*>
(
const_cast
<
unsigned
int
*>
(
beta
))
);
}
// constructor
BoostDesc_Impl
::
BoostDesc_Impl
(
int
_desc
,
bool
_use_scale_orientation
,
float
_scale_factor
)
:
m_desc_type
(
_desc
),
m_scale_factor
(
_scale_factor
),
m_use_scale_orientation
(
_use_scale_orientation
)
{
// desc type
switch
(
m_desc_type
)
{
case
BGM
:
{
#include "boostdesc_bgm.i"
ini_params
(
orientQuant
,
patchSize
,
iGradAssignType
,
nDim
,
nWLs
,
thresh
,
orient
,
x_min
,
x_max
,
y_min
,
y_max
,
alpha
,
NULL
);
}
break
;
case
BGM_HARD
:
{
#include "boostdesc_bgm_hd.i"
ini_params
(
orientQuant
,
patchSize
,
iGradAssignType
,
nDim
,
nWLs
,
thresh
,
orient
,
x_min
,
x_max
,
y_min
,
y_max
,
alpha
,
NULL
);
}
break
;
case
BGM_BILINEAR
:
{
#include "boostdesc_bgm_bi.i"
ini_params
(
orientQuant
,
patchSize
,
iGradAssignType
,
nDim
,
nWLs
,
thresh
,
orient
,
x_min
,
x_max
,
y_min
,
y_max
,
alpha
,
NULL
);
}
break
;
case
LBGM
:
{
#include "boostdesc_lbgm.i"
ini_params
(
orientQuant
,
patchSize
,
iGradAssignType
,
nDim
,
nWLs
,
thresh
,
orient
,
x_min
,
x_max
,
y_min
,
y_max
,
alpha
,
beta
);
}
break
;
case
BINBOOST_64
:
{
#include "boostdesc_binboost_064.i"
ini_params
(
orientQuant
,
patchSize
,
iGradAssignType
,
nDim
,
nWLs
,
thresh
,
orient
,
x_min
,
x_max
,
y_min
,
y_max
,
alpha
,
beta
);
}
break
;
case
BINBOOST_128
:
{
#include "boostdesc_binboost_128.i"
ini_params
(
orientQuant
,
patchSize
,
iGradAssignType
,
nDim
,
nWLs
,
thresh
,
orient
,
x_min
,
x_max
,
y_min
,
y_max
,
alpha
,
beta
);
}
break
;
case
BINBOOST_256
:
{
#include "boostdesc_binboost_256.i"
ini_params
(
orientQuant
,
patchSize
,
iGradAssignType
,
nDim
,
nWLs
,
thresh
,
orient
,
x_min
,
x_max
,
y_min
,
y_max
,
alpha
,
beta
);
}
break
;
default
:
CV_Error
(
Error
::
StsInternal
,
"Unknown Descriptor Type."
);
}
}
// destructor
BoostDesc_Impl
::~
BoostDesc_Impl
()
{
}
Ptr
<
BoostDesc
>
BoostDesc
::
create
(
int
desc
,
bool
use_scale_orientation
,
float
scale_factor
)
{
return
makePtr
<
BoostDesc_Impl
>
(
desc
,
use_scale_orientation
,
scale_factor
);
}
}
// END NAMESPACE XFEATURES2D
}
// END NAMESPACE CV
modules/xfeatures2d/src/vgg.cpp
View file @
9c1d01e2
...
...
@@ -315,9 +315,9 @@ static void get_desc( const Mat Patch, Mat& PatchTrans, int anglebins, bool img_
// -------------------------------------------------
/* VGG interface implementation */
struct
Compute
Desc
Invoker
:
ParallelLoopBody
struct
Compute
VGG
Invoker
:
ParallelLoopBody
{
Compute
Desc
Invoker
(
const
Mat
&
_image
,
Mat
*
_descriptors
,
Compute
VGG
Invoker
(
const
Mat
&
_image
,
Mat
*
_descriptors
,
const
vector
<
KeyPoint
>&
_keypoints
,
const
Mat
&
_PRFilters
,
const
Mat
&
_Proj
,
const
int
_anglebins
,
const
bool
_img_normalize
,
...
...
@@ -403,7 +403,7 @@ void VGG_Impl::compute( InputArray _image, vector<KeyPoint>& keypoints, OutputAr
descriptors
.
setTo
(
Scalar
(
0
)
);
parallel_for_
(
Range
(
0
,
(
int
)
keypoints
.
size
()
),
Compute
Desc
Invoker
(
m_image
,
&
descriptors
,
keypoints
,
m_PRFilters
,
m_Proj
,
Compute
VGG
Invoker
(
m_image
,
&
descriptors
,
keypoints
,
m_PRFilters
,
m_Proj
,
m_anglebins
,
m_img_normalize
,
m_use_scale_orientation
,
m_scale_factor
)
);
...
...
modules/xfeatures2d/test/test_features2d.cpp
View file @
9c1d01e2
...
...
@@ -1057,6 +1057,62 @@ TEST( Features2d_DescriptorExtractor_VGG, regression )
test
.
safe_run
();
}
TEST
(
Features2d_DescriptorExtractor_BGM
,
regression
)
{
CV_DescriptorExtractorTest
<
Hamming
>
test
(
"descriptor-boostdesc-bgm"
,
(
CV_DescriptorExtractorTest
<
Hamming
>::
DistanceType
)
12.
f
,
BoostDesc
::
create
(
BoostDesc
::
BGM
)
);
test
.
safe_run
();
}
TEST
(
Features2d_DescriptorExtractor_BGM_HARD
,
regression
)
{
CV_DescriptorExtractorTest
<
Hamming
>
test
(
"descriptor-boostdesc-bgm_hard"
,
(
CV_DescriptorExtractorTest
<
Hamming
>::
DistanceType
)
12.
f
,
BoostDesc
::
create
(
BoostDesc
::
BGM_HARD
)
);
test
.
safe_run
();
}
TEST
(
Features2d_DescriptorExtractor_BGM_BILINEAR
,
regression
)
{
CV_DescriptorExtractorTest
<
Hamming
>
test
(
"descriptor-boostdesc-bgm_bilinear"
,
(
CV_DescriptorExtractorTest
<
Hamming
>::
DistanceType
)
15.
f
,
BoostDesc
::
create
(
BoostDesc
::
BGM_BILINEAR
)
);
test
.
safe_run
();
}
TEST
(
Features2d_DescriptorExtractor_LBGM
,
regression
)
{
CV_DescriptorExtractorTest
<
L2
<
float
>
>
test
(
"descriptor-boostdesc-lbgm"
,
1.0
f
,
BoostDesc
::
create
(
BoostDesc
::
LBGM
)
);
test
.
safe_run
();
}
TEST
(
Features2d_DescriptorExtractor_BINBOOST_64
,
regression
)
{
CV_DescriptorExtractorTest
<
Hamming
>
test
(
"descriptor-boostdesc-binboost_64"
,
(
CV_DescriptorExtractorTest
<
Hamming
>::
DistanceType
)
12.
f
,
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_64
)
);
test
.
safe_run
();
}
TEST
(
Features2d_DescriptorExtractor_BINBOOST_128
,
regression
)
{
CV_DescriptorExtractorTest
<
Hamming
>
test
(
"descriptor-boostdesc-binboost_128"
,
(
CV_DescriptorExtractorTest
<
Hamming
>::
DistanceType
)
12.
f
,
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_128
)
);
test
.
safe_run
();
}
TEST
(
Features2d_DescriptorExtractor_BINBOOST_256
,
regression
)
{
CV_DescriptorExtractorTest
<
Hamming
>
test
(
"descriptor-boostdesc-binboost_256"
,
(
CV_DescriptorExtractorTest
<
Hamming
>::
DistanceType
)
12.
f
,
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_256
)
);
test
.
safe_run
();
}
/*#if CV_SSE2
TEST( Features2d_DescriptorExtractor_Calonder_uchar, regression )
...
...
modules/xfeatures2d/test/test_rotation_and_scale_invariance.cpp
View file @
9c1d01e2
...
...
@@ -744,6 +744,69 @@ TEST(Features2d_RotationInvariance_Descriptor_FREAK, regression)
test
.
safe_run
();
}
TEST
(
Features2d_RotationInvariance_Descriptor_BoostDesc_BGM
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BGM
,
true
,
6.25
f
),
NORM_HAMMING
,
0.999
f
);
test
.
safe_run
();
}
TEST
(
Features2d_RotationInvariance_Descriptor_BoostDesc_BGM_HARD
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BGM_HARD
,
true
,
6.25
f
),
NORM_HAMMING
,
0.98
f
);
test
.
safe_run
();
}
TEST
(
Features2d_RotationInvariance_Descriptor_BoostDesc_BGM_BILINEAR
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BGM_BILINEAR
,
true
,
6.25
f
),
NORM_HAMMING
,
0.98
f
);
test
.
safe_run
();
}
TEST
(
Features2d_RotationInvariance_Descriptor_BoostDesc_LBGM
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
LBGM
,
true
,
6.25
f
),
NORM_L1
,
0.999
f
);
test
.
safe_run
();
}
TEST
(
Features2d_RotationInvariance_Descriptor_BoostDesc_BINBOOST_64
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_64
,
true
,
6.25
f
),
NORM_HAMMING
,
0.98
f
);
test
.
safe_run
();
}
TEST
(
Features2d_RotationInvariance_Descriptor_BoostDesc_BINBOOST_128
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_128
,
true
,
6.25
f
),
NORM_HAMMING
,
0.98
f
);
test
.
safe_run
();
}
TEST
(
Features2d_RotationInvariance_Descriptor_BoostDesc_BINBOOST_256
,
regression
)
{
DescriptorRotationInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_256
,
true
,
6.25
f
),
NORM_HAMMING
,
0.999
f
);
test
.
safe_run
();
}
/*
* Detector's scale invariance check
*/
...
...
@@ -846,3 +909,66 @@ TEST(Features2d_ScaleInvariance_Descriptor_VGG48, regression)
0.93
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Descriptor_BoostDesc_BGM
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BGM
,
true
,
6.25
f
),
NORM_HAMMING
,
0.98
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Descriptor_BoostDesc_BGM_HARD
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BGM_HARD
,
true
,
6.25
f
),
NORM_HAMMING
,
0.75
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Descriptor_BoostDesc_BGM_BILINEAR
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BGM_BILINEAR
,
true
,
6.25
f
),
NORM_HAMMING
,
0.95
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Descriptor_BoostDesc_LBGM
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
LBGM
,
true
,
6.25
f
),
NORM_L1
,
0.98
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Descriptor_BoostDesc_BINBOOST_64
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_64
,
true
,
6.25
f
),
NORM_HAMMING
,
0.75
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Descriptor_BoostDesc_BINBOOST_128
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_128
,
true
,
6.25
f
),
NORM_HAMMING
,
0.95
f
);
test
.
safe_run
();
}
TEST
(
Features2d_ScaleInvariance_Descriptor_BoostDesc_BINBOOST_256
,
regression
)
{
DescriptorScaleInvarianceTest
test
(
SURF
::
create
(),
BoostDesc
::
create
(
BoostDesc
::
BINBOOST_256
,
true
,
6.25
f
),
NORM_HAMMING
,
0.98
f
);
test
.
safe_run
();
}
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