Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
O
opencv
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
Commits
922ac1a1
Commit
922ac1a1
authored
Aug 03, 2017
by
Alexander Alekhin
Committed by
GitHub
Aug 03, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #9303 from alalek:akaze_update
parents
c95a9738
2a8322dd
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
325 additions
and
298 deletions
+325
-298
utility.hpp
modules/core/include/opencv2/core/utility.hpp
+17
-0
matrix.cpp
modules/core/src/matrix.cpp
+0
-5
akaze.cpp
modules/features2d/src/akaze.cpp
+2
-2
AKAZEFeatures.cpp
modules/features2d/src/kaze/AKAZEFeatures.cpp
+197
-157
AKAZEFeatures.h
modules/features2d/src/kaze/AKAZEFeatures.h
+2
-0
KAZEFeatures.cpp
modules/features2d/src/kaze/KAZEFeatures.cpp
+24
-24
fed.cpp
modules/features2d/src/kaze/fed.cpp
+1
-1
nldiffusion_functions.cpp
modules/features2d/src/kaze/nldiffusion_functions.cpp
+1
-1
utils.h
modules/features2d/src/kaze/utils.h
+0
-55
test_descriptors_invariance.cpp
modules/features2d/test/test_descriptors_invariance.cpp
+5
-3
test_descriptors_regression.cpp
modules/features2d/test/test_descriptors_regression.cpp
+73
-42
test_detectors_invariance.cpp
modules/features2d/test/test_detectors_invariance.cpp
+1
-1
fast_nlmeans_denoising_opencl.hpp
modules/photo/src/fast_nlmeans_denoising_opencl.hpp
+0
-5
perf_stich.cpp
modules/stitching/perf/perf_stich.cpp
+2
-2
No files found.
modules/core/include/opencv2/core/utility.hpp
View file @
922ac1a1
...
...
@@ -444,6 +444,23 @@ static inline size_t alignSize(size_t sz, int n)
return
(
sz
+
n
-
1
)
&
-
n
;
}
/** @brief Integer division with result round up.
Use this function instead of `ceil((float)a / b)` expressions.
@sa alignSize
*/
static
inline
int
divUp
(
int
a
,
unsigned
int
b
)
{
CV_DbgAssert
(
a
>=
0
);
return
(
a
+
b
-
1
)
/
b
;
}
/** @overload */
static
inline
size_t
divUp
(
size_t
a
,
unsigned
int
b
)
{
return
(
a
+
b
-
1
)
/
b
;
}
/** @brief Enables or disables the optimized code.
The function can be used to dynamically turn on and off optimized code (code that uses SSE2, AVX,
...
...
modules/core/src/matrix.cpp
View file @
922ac1a1
...
...
@@ -3406,11 +3406,6 @@ static TransposeInplaceFunc transposeInplaceTab[] =
#ifdef HAVE_OPENCL
static
inline
int
divUp
(
int
a
,
int
b
)
{
return
(
a
+
b
-
1
)
/
b
;
}
static
bool
ocl_transpose
(
InputArray
_src
,
OutputArray
_dst
)
{
const
ocl
::
Device
&
dev
=
ocl
::
Device
::
getDefault
();
...
...
modules/features2d/src/akaze.cpp
View file @
922ac1a1
...
...
@@ -113,12 +113,12 @@ namespace cv
if
(
descriptor_size
==
0
)
{
int
t
=
(
6
+
36
+
120
)
*
descriptor_channels
;
return
(
int
)
ceil
(
t
/
8.
);
return
divUp
(
t
,
8
);
}
else
{
// We use the random bit selection length binary descriptor
return
(
int
)
ceil
(
descriptor_size
/
8.
);
return
divUp
(
descriptor_size
,
8
);
}
default
:
...
...
modules/features2d/src/kaze/AKAZEFeatures.cpp
View file @
922ac1a1
...
...
@@ -74,12 +74,12 @@ void AKAZEFeatures::Allocate_Memory_Evolution(void) {
Evolution
step
;
step
.
size
=
Size
(
level_width
,
level_height
);
step
.
esigma
=
options_
.
soffset
*
pow
(
2.
f
,
(
float
)(
j
)
/
(
float
)(
options_
.
nsublevels
)
+
i
);
step
.
sigma_size
=
f
Round
(
step
.
esigma
*
options_
.
derivative_factor
/
power
);
// In fact sigma_size only depends on j
step
.
sigma_size
=
cv
Round
(
step
.
esigma
*
options_
.
derivative_factor
/
power
);
// In fact sigma_size only depends on j
step
.
etime
=
0.5
f
*
(
step
.
esigma
*
step
.
esigma
);
step
.
octave
=
i
;
step
.
sublevel
=
j
;
step
.
octave_ratio
=
(
float
)
power
;
step
.
border
=
f
Round
(
smax
*
step
.
sigma_size
)
+
1
;
step
.
border
=
cv
Round
(
smax
*
step
.
sigma_size
)
+
1
;
evolution_
.
push_back
(
step
);
}
...
...
@@ -106,7 +106,7 @@ void AKAZEFeatures::Allocate_Memory_Evolution(void) {
*/
static
inline
int
getGaussianKernelSize
(
float
sigma
)
{
// Compute an appropriate kernel size according to the specified sigma
int
ksize
=
(
int
)
ceil
(
2.0
f
*
(
1.0
f
+
(
sigma
-
0.8
f
)
/
(
0.3
f
)));
int
ksize
=
(
int
)
c
vC
eil
(
2.0
f
*
(
1.0
f
+
(
sigma
-
0.8
f
)
/
(
0.3
f
)));
ksize
|=
1
;
// kernel should be odd
return
ksize
;
}
...
...
@@ -890,11 +890,11 @@ public:
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Get_SURF_Descriptor_Upright_64
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
float
>
(
i
));
Get_SURF_Descriptor_Upright_64
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
float
>
(
i
)
,
descriptors_
->
cols
);
}
}
void
Get_SURF_Descriptor_Upright_64
(
const
KeyPoint
&
kpt
,
float
*
desc
)
const
;
void
Get_SURF_Descriptor_Upright_64
(
const
KeyPoint
&
kpt
,
float
*
desc
,
int
desc_size
)
const
;
private
:
std
::
vector
<
KeyPoint
>*
keypoints_
;
...
...
@@ -916,11 +916,11 @@ public:
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Get_SURF_Descriptor_64
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
float
>
(
i
));
Get_SURF_Descriptor_64
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
float
>
(
i
)
,
descriptors_
->
cols
);
}
}
void
Get_SURF_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
)
const
;
void
Get_SURF_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
,
int
desc_size
)
const
;
private
:
std
::
vector
<
KeyPoint
>*
keypoints_
;
...
...
@@ -942,11 +942,11 @@ public:
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Get_MSURF_Upright_Descriptor_64
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
float
>
(
i
));
Get_MSURF_Upright_Descriptor_64
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
float
>
(
i
)
,
descriptors_
->
cols
);
}
}
void
Get_MSURF_Upright_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
)
const
;
void
Get_MSURF_Upright_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
,
int
desc_size
)
const
;
private
:
std
::
vector
<
KeyPoint
>*
keypoints_
;
...
...
@@ -968,11 +968,11 @@ public:
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Get_MSURF_Descriptor_64
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
float
>
(
i
));
Get_MSURF_Descriptor_64
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
float
>
(
i
)
,
descriptors_
->
cols
);
}
}
void
Get_MSURF_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
)
const
;
void
Get_MSURF_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
,
int
desc_size
)
const
;
private
:
std
::
vector
<
KeyPoint
>*
keypoints_
;
...
...
@@ -995,11 +995,11 @@ public:
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Get_Upright_MLDB_Full_Descriptor
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
unsigned
char
>
(
i
));
Get_Upright_MLDB_Full_Descriptor
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
unsigned
char
>
(
i
)
,
descriptors_
->
cols
);
}
}
void
Get_Upright_MLDB_Full_Descriptor
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
)
const
;
void
Get_Upright_MLDB_Full_Descriptor
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
,
int
desc_size
)
const
;
private
:
std
::
vector
<
KeyPoint
>*
keypoints_
;
...
...
@@ -1030,11 +1030,11 @@ public:
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Get_Upright_MLDB_Descriptor_Subset
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
unsigned
char
>
(
i
));
Get_Upright_MLDB_Descriptor_Subset
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
unsigned
char
>
(
i
)
,
descriptors_
->
cols
);
}
}
void
Get_Upright_MLDB_Descriptor_Subset
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
)
const
;
void
Get_Upright_MLDB_Descriptor_Subset
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
,
int
desc_size
)
const
;
private
:
std
::
vector
<
KeyPoint
>*
keypoints_
;
...
...
@@ -1061,11 +1061,11 @@ public:
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Get_MLDB_Full_Descriptor
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
unsigned
char
>
(
i
));
Get_MLDB_Full_Descriptor
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
unsigned
char
>
(
i
)
,
descriptors_
->
cols
);
}
}
void
Get_MLDB_Full_Descriptor
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
)
const
;
void
Get_MLDB_Full_Descriptor
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
,
int
desc_size
)
const
;
void
MLDB_Fill_Values
(
float
*
values
,
int
sample_step
,
int
level
,
float
xf
,
float
yf
,
float
co
,
float
si
,
float
scale
)
const
;
void
MLDB_Binary_Comparisons
(
float
*
values
,
unsigned
char
*
desc
,
...
...
@@ -1100,11 +1100,11 @@ public:
{
for
(
int
i
=
range
.
start
;
i
<
range
.
end
;
i
++
)
{
Get_MLDB_Descriptor_Subset
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
unsigned
char
>
(
i
));
Get_MLDB_Descriptor_Subset
((
*
keypoints_
)[
i
],
descriptors_
->
ptr
<
unsigned
char
>
(
i
)
,
descriptors_
->
cols
);
}
}
void
Get_MLDB_Descriptor_Subset
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
)
const
;
void
Get_MLDB_Descriptor_Subset
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
,
int
desc_size
)
const
;
private
:
std
::
vector
<
KeyPoint
>*
keypoints_
;
...
...
@@ -1131,20 +1131,17 @@ void AKAZEFeatures::Compute_Descriptors(std::vector<KeyPoint>& kpts, OutputArray
}
// Allocate memory for the matrix with the descriptors
if
(
options_
.
descriptor
<
AKAZE
::
DESCRIPTOR_MLDB_UPRIGHT
)
{
descriptors
.
create
((
int
)
kpts
.
size
(),
64
,
CV_32FC1
);
}
else
{
// We use the full length binary descriptor -> 486 bits
if
(
options_
.
descriptor_size
==
0
)
{
int
t
=
(
6
+
36
+
120
)
*
options_
.
descriptor_channels
;
descriptors
.
create
((
int
)
kpts
.
size
(),
(
int
)
ceil
(
t
/
8.
),
CV_8UC1
);
}
else
{
// We use the random bit selection length binary descriptor
descriptors
.
create
((
int
)
kpts
.
size
(),
(
int
)
ceil
(
options_
.
descriptor_size
/
8.
),
CV_8UC1
);
}
int
descriptor_size
=
64
;
int
descriptor_type
=
CV_32FC1
;
if
(
options_
.
descriptor
>=
AKAZE
::
DESCRIPTOR_MLDB_UPRIGHT
)
{
int
descriptor_bits
=
(
options_
.
descriptor_size
==
0
)
?
(
6
+
36
+
120
)
*
options_
.
descriptor_channels
// the full length binary descriptor -> 486 bits
:
options_
.
descriptor_size
;
// the random bit selection length binary descriptor
descriptor_size
=
divUp
(
descriptor_bits
,
8
);
descriptor_type
=
CV_8UC1
;
}
descriptors
.
create
((
int
)
kpts
.
size
(),
descriptor_size
,
descriptor_type
);
Mat
desc
=
descriptors
.
getMat
();
...
...
@@ -1208,12 +1205,11 @@ void Sample_Derivative_Response_Radius6(const Mat &Lx, const Mat &Ly,
{
0.00344629
f
,
0.00318132
f
,
0.00250252
f
,
0.00167749
f
,
0.00095820
f
,
0.00046640
f
,
0.00019346
f
},
{
0.00142946
f
,
0.00131956
f
,
0.00103800
f
,
0.00069579
f
,
0.00039744
f
,
0.00019346
f
,
0.00008024
f
}
};
static
const
int
id
[]
=
{
6
,
5
,
4
,
3
,
2
,
1
,
0
,
1
,
2
,
3
,
4
,
5
,
6
};
static
const
struct
gtable
{
float
weight
[
109
];
int
8_t
xidx
[
109
];
int
8_t
yidx
[
109
];
int
xidx
[
109
];
int
yidx
[
109
];
explicit
gtable
(
void
)
{
...
...
@@ -1222,29 +1218,28 @@ void Sample_Derivative_Response_Radius6(const Mat &Lx, const Mat &Ly,
for
(
int
i
=
-
6
;
i
<=
6
;
++
i
)
{
for
(
int
j
=
-
6
;
j
<=
6
;
++
j
)
{
if
(
i
*
i
+
j
*
j
<
36
)
{
weight
[
k
]
=
gauss25
[
id
[
i
+
6
]][
id
[
j
+
6
]];
yidx
[
k
]
=
static_cast
<
int8_t
>
(
i
);
xidx
[
k
]
=
static_cast
<
int8_t
>
(
j
);
CV_Assert
(
k
<
109
);
weight
[
k
]
=
gauss25
[
abs
(
i
)][
abs
(
j
)];
yidx
[
k
]
=
i
;
xidx
[
k
]
=
j
;
++
k
;
}
}
}
CV_DbgAssert
(
k
==
109
);
}
}
g
;
const
float
*
lx
=
Lx
.
ptr
<
float
>
(
0
);
const
float
*
ly
=
Ly
.
ptr
<
float
>
(
0
);
int
cols
=
Lx
.
cols
;
for
(
int
i
=
0
;
i
<
109
;
i
++
)
{
int
j
=
(
y0
+
g
.
yidx
[
i
]
*
scale
)
*
cols
+
(
x0
+
g
.
xidx
[
i
]
*
scale
);
CV_Assert
(
x0
-
6
*
scale
>=
0
&&
x0
+
6
*
scale
<
Lx
.
cols
);
CV_Assert
(
y0
-
6
*
scale
>=
0
&&
y0
+
6
*
scale
<
Lx
.
rows
);
resX
[
i
]
=
g
.
weight
[
i
]
*
lx
[
j
];
resY
[
i
]
=
g
.
weight
[
i
]
*
ly
[
j
];
for
(
int
i
=
0
;
i
<
109
;
i
++
)
{
int
y
=
y0
+
g
.
yidx
[
i
]
*
scale
;
int
x
=
x0
+
g
.
xidx
[
i
]
*
scale
;
CV_DbgAssert
(
isfinite
(
resX
[
i
]));
CV_DbgAssert
(
isfinite
(
resY
[
i
]));
float
w
=
g
.
weight
[
i
];
resX
[
i
]
=
w
*
Lx
.
at
<
float
>
(
y
,
x
);
resY
[
i
]
=
w
*
Ly
.
at
<
float
>
(
y
,
x
);
}
}
...
...
@@ -1253,7 +1248,7 @@ void Sample_Derivative_Response_Radius6(const Mat &Lx, const Mat &Ly,
* @param a[] Input floating point array to sort
* @param n The length of a[]
* @param quantum The interval to convert a[i]'s float values to integers
* @param
max The upper bound of a[], meaning a[i] must be in [0, max]
* @param
nkeys a[i] < nkeys * quantum
* @param idx[] Output array of the indices: a[idx[i]] forms a sorted array
* @param cum[] Output array of the starting indices of quantized floats
* @note The values of a[] in [k*quantum, (k + 1)*quantum) is labeled by
...
...
@@ -1263,25 +1258,35 @@ void Sample_Derivative_Response_Radius6(const Mat &Lx, const Mat &Ly,
*/
static
inline
void
quantized_counting_sort
(
const
float
a
[],
const
int
n
,
const
float
quantum
,
const
float
max
,
uint8_t
idx
[],
uint8_t
cum
[
])
const
float
quantum
,
const
int
nkeys
,
int
idx
[
/*n*/
],
int
cum
[
/*nkeys + 1*/
])
{
const
int
nkeys
=
(
int
)(
max
/
quantum
);
// The size of cum[] must be nkeys + 1
memset
(
cum
,
0
,
nkeys
+
1
);
memset
(
cum
,
0
,
sizeof
(
cum
[
0
])
*
(
nkeys
+
1
));
// Count up the quantized values
for
(
int
i
=
0
;
i
<
n
;
i
++
)
cum
[(
int
)(
a
[
i
]
/
quantum
)]
++
;
{
int
b
=
(
int
)(
a
[
i
]
/
quantum
);
if
(
b
<
0
||
b
>=
nkeys
)
b
=
0
;
cum
[
b
]
++
;
}
// Compute the inclusive prefix sum i.e. the end indices; cum[nkeys] is the total
for
(
int
i
=
1
;
i
<=
nkeys
;
i
++
)
{
cum
[
i
]
+=
cum
[
i
-
1
];
}
CV_Assert
(
cum
[
nkeys
]
==
n
);
// Generate the sorted indices; cum[] becomes the exclusive prefix sum i.e. the start indices of keys
for
(
int
i
=
0
;
i
<
n
;
i
++
)
idx
[
--
cum
[(
int
)(
a
[
i
]
/
quantum
)]]
=
static_cast
<
uint8_t
>
(
i
);
{
int
b
=
(
int
)(
a
[
i
]
/
quantum
);
if
(
b
<
0
||
b
>=
nkeys
)
b
=
0
;
idx
[
--
cum
[
b
]]
=
i
;
}
}
/**
...
...
@@ -1296,9 +1301,9 @@ void Compute_Main_Orientation(KeyPoint& kpt, const std::vector<Evolution>& evolu
// get the right evolution level for this keypoint
const
Evolution
&
e
=
evolution
[
kpt
.
class_id
];
// Get the information from the keypoint
int
scale
=
f
Round
(
0.5
f
*
kpt
.
size
/
e
.
octave_ratio
);
int
x0
=
f
Round
(
kpt
.
pt
.
x
/
e
.
octave_ratio
);
int
y0
=
f
Round
(
kpt
.
pt
.
y
/
e
.
octave_ratio
);
int
scale
=
cv
Round
(
0.5
f
*
kpt
.
size
/
e
.
octave_ratio
);
int
x0
=
cv
Round
(
kpt
.
pt
.
x
/
e
.
octave_ratio
);
int
y0
=
cv
Round
(
kpt
.
pt
.
y
/
e
.
octave_ratio
);
// Sample derivatives responses for the points within radius of 6*scale
const
int
ang_size
=
109
;
...
...
@@ -1312,17 +1317,18 @@ void Compute_Main_Orientation(KeyPoint& kpt, const std::vector<Evolution>& evolu
// Sort by the angles; angles are labeled by slices of 0.15 radian
const
int
slices
=
42
;
const
float
ang_step
=
(
float
)(
2.0
*
CV_PI
/
slices
);
uint8_
t
slice
[
slices
+
1
];
uint8_
t
sorted_idx
[
ang_size
];
quantized_counting_sort
(
Ang
,
ang_size
,
ang_step
,
(
float
)(
2.0
*
CV_PI
)
,
sorted_idx
,
slice
);
in
t
slice
[
slices
+
1
];
in
t
sorted_idx
[
ang_size
];
quantized_counting_sort
(
Ang
,
ang_size
,
ang_step
,
slices
,
sorted_idx
,
slice
);
// Find the main angle by sliding a window of 7-slice size(=PI/3) around the keypoint
const
int
win
=
7
;
float
maxX
=
0.0
f
,
maxY
=
0.0
f
;
for
(
int
i
=
slice
[
0
];
i
<
slice
[
win
];
i
++
)
{
maxX
+=
resX
[
sorted_idx
[
i
]];
maxY
+=
resY
[
sorted_idx
[
i
]];
const
int
idx
=
sorted_idx
[
i
];
maxX
+=
resX
[
idx
];
maxY
+=
resY
[
idx
];
}
float
maxNorm
=
maxX
*
maxX
+
maxY
*
maxY
;
...
...
@@ -1333,8 +1339,9 @@ void Compute_Main_Orientation(KeyPoint& kpt, const std::vector<Evolution>& evolu
float
sumX
=
0.0
f
,
sumY
=
0.0
f
;
for
(
int
i
=
slice
[
sn
];
i
<
slice
[
sn
+
win
];
i
++
)
{
sumX
+=
resX
[
sorted_idx
[
i
]];
sumY
+=
resY
[
sorted_idx
[
i
]];
const
int
idx
=
sorted_idx
[
i
];
sumX
+=
resX
[
idx
];
sumY
+=
resY
[
idx
];
}
float
norm
=
sumX
*
sumX
+
sumY
*
sumY
;
...
...
@@ -1350,12 +1357,14 @@ void Compute_Main_Orientation(KeyPoint& kpt, const std::vector<Evolution>& evolu
float
sumX
=
0.0
f
,
sumY
=
0.0
f
;
for
(
int
i
=
slice
[
sn
];
i
<
slice
[
slices
];
i
++
)
{
sumX
+=
resX
[
sorted_idx
[
i
]];
sumY
+=
resY
[
sorted_idx
[
i
]];
const
int
idx
=
sorted_idx
[
i
];
sumX
+=
resX
[
idx
];
sumY
+=
resY
[
idx
];
}
for
(
int
i
=
slice
[
0
];
i
<
slice
[
remain
];
i
++
)
{
sumX
+=
resX
[
sorted_idx
[
i
]];
sumY
+=
resY
[
sorted_idx
[
i
]];
const
int
idx
=
sorted_idx
[
i
];
sumX
+=
resX
[
idx
];
sumY
+=
resY
[
idx
];
}
float
norm
=
sumX
*
sumX
+
sumY
*
sumY
;
...
...
@@ -1410,7 +1419,10 @@ void AKAZEFeatures::Compute_Keypoints_Orientation(std::vector<KeyPoint>& kpts) c
* from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching,
* ECCV 2008
*/
void
MSURF_Upright_Descriptor_64_Invoker
::
Get_MSURF_Upright_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
)
const
{
void
MSURF_Upright_Descriptor_64_Invoker
::
Get_MSURF_Upright_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
,
int
desc_size
)
const
{
const
int
dsize
=
64
;
CV_Assert
(
desc_size
==
dsize
);
float
dx
=
0.0
,
dy
=
0.0
,
mdx
=
0.0
,
mdy
=
0.0
,
gauss_s1
=
0.0
,
gauss_s2
=
0.0
;
float
rx
=
0.0
,
ry
=
0.0
,
len
=
0.0
,
xf
=
0.0
,
yf
=
0.0
,
ys
=
0.0
,
xs
=
0.0
;
...
...
@@ -1418,7 +1430,7 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
int
x1
=
0
,
y1
=
0
,
sample_step
=
0
,
pattern_size
=
0
;
int
x2
=
0
,
y2
=
0
,
kx
=
0
,
ky
=
0
,
i
=
0
,
j
=
0
,
dcount
=
0
;
float
fx
=
0.0
,
fy
=
0.0
,
ratio
=
0.0
,
res1
=
0.0
,
res2
=
0.0
,
res3
=
0.0
,
res4
=
0.0
;
int
scale
=
0
,
dsize
=
0
;
int
scale
=
0
;
// Subregion centers for the 4x4 gaussian weighting
float
cx
=
-
0.5
f
,
cy
=
0.5
f
;
...
...
@@ -1426,13 +1438,12 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
const
std
::
vector
<
Evolution
>&
evolution
=
*
evolution_
;
// Set the descriptor size and the sample and pattern sizes
dsize
=
64
;
sample_step
=
5
;
pattern_size
=
12
;
// Get the information from the keypoint
ratio
=
(
float
)(
1
<<
kpt
.
octave
);
scale
=
f
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
scale
=
cv
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
const
int
level
=
kpt
.
class_id
;
Mat
Lx
=
evolution
[
level
].
Mx
;
Mat
Ly
=
evolution
[
level
].
My
;
...
...
@@ -1469,11 +1480,11 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
//Get the gaussian weighted x and y responses
gauss_s1
=
gaussian
(
xs
-
sample_x
,
ys
-
sample_y
,
2.50
f
*
scale
);
y1
=
(
int
)(
sample_y
-
.5
);
x1
=
(
int
)(
sample_x
-
.5
);
y1
=
(
int
)(
sample_y
-
.5
f
);
x1
=
(
int
)(
sample_x
-
.5
f
);
y2
=
(
int
)(
sample_y
+
.5
);
x2
=
(
int
)(
sample_x
+
.5
);
y2
=
(
int
)(
sample_y
+
.5
f
);
x2
=
(
int
)(
sample_x
+
.5
f
);
fx
=
sample_x
-
x1
;
fy
=
sample_y
-
y1
;
...
...
@@ -1517,6 +1528,8 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
i
+=
9
;
}
CV_Assert
(
dcount
==
desc_size
);
// convert to unit vector
len
=
sqrt
(
len
);
...
...
@@ -1535,7 +1548,10 @@ void MSURF_Upright_Descriptor_64_Invoker::Get_MSURF_Upright_Descriptor_64(const
* from Agrawal et al., CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching,
* ECCV 2008
*/
void
MSURF_Descriptor_64_Invoker
::
Get_MSURF_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
)
const
{
void
MSURF_Descriptor_64_Invoker
::
Get_MSURF_Descriptor_64
(
const
KeyPoint
&
kpt
,
float
*
desc
,
int
desc_size
)
const
{
const
int
dsize
=
64
;
CV_Assert
(
desc_size
==
dsize
);
float
dx
=
0.0
,
dy
=
0.0
,
mdx
=
0.0
,
mdy
=
0.0
,
gauss_s1
=
0.0
,
gauss_s2
=
0.0
;
float
rx
=
0.0
,
ry
=
0.0
,
rrx
=
0.0
,
rry
=
0.0
,
len
=
0.0
,
xf
=
0.0
,
yf
=
0.0
,
ys
=
0.0
,
xs
=
0.0
;
...
...
@@ -1543,7 +1559,7 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
float
fx
=
0.0
,
fy
=
0.0
,
ratio
=
0.0
,
res1
=
0.0
,
res2
=
0.0
,
res3
=
0.0
,
res4
=
0.0
;
int
x1
=
0
,
y1
=
0
,
x2
=
0
,
y2
=
0
,
sample_step
=
0
,
pattern_size
=
0
;
int
kx
=
0
,
ky
=
0
,
i
=
0
,
j
=
0
,
dcount
=
0
;
int
scale
=
0
,
dsize
=
0
;
int
scale
=
0
;
// Subregion centers for the 4x4 gaussian weighting
float
cx
=
-
0.5
f
,
cy
=
0.5
f
;
...
...
@@ -1551,14 +1567,13 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
const
std
::
vector
<
Evolution
>&
evolution
=
*
evolution_
;
// Set the descriptor size and the sample and pattern sizes
dsize
=
64
;
sample_step
=
5
;
pattern_size
=
12
;
// Get the information from the keypoint
ratio
=
(
float
)(
1
<<
kpt
.
octave
);
scale
=
f
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
angle
=
(
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
))
/
180.
f
;
scale
=
cv
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
angle
=
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
/
180.
f
)
;
const
int
level
=
kpt
.
class_id
;
Mat
Lx
=
evolution
[
level
].
Mx
;
Mat
Ly
=
evolution
[
level
].
My
;
...
...
@@ -1598,11 +1613,11 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
// Get the gaussian weighted x and y responses
gauss_s1
=
gaussian
(
xs
-
sample_x
,
ys
-
sample_y
,
2.5
f
*
scale
);
y1
=
f
Round
(
sample_y
-
0.5
f
);
x1
=
f
Round
(
sample_x
-
0.5
f
);
y1
=
cv
Round
(
sample_y
-
0.5
f
);
x1
=
cv
Round
(
sample_x
-
0.5
f
);
y2
=
f
Round
(
sample_y
+
0.5
f
);
x2
=
f
Round
(
sample_x
+
0.5
f
);
y2
=
cv
Round
(
sample_y
+
0.5
f
);
x2
=
cv
Round
(
sample_x
+
0.5
f
);
// fix crash: indexing with out-of-bounds index, this might happen near the edges of image
// clip values so they fit into the image
...
...
@@ -1655,6 +1670,8 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
i
+=
9
;
}
CV_Assert
(
dcount
==
desc_size
);
// convert to unit vector
len
=
sqrt
(
len
);
...
...
@@ -1670,7 +1687,7 @@ void MSURF_Descriptor_64_Invoker::Get_MSURF_Descriptor_64(const KeyPoint& kpt, f
* @param kpt Input keypoint
* @param desc Descriptor vector
*/
void
Upright_MLDB_Full_Descriptor_Invoker
::
Get_Upright_MLDB_Full_Descriptor
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
)
const
{
void
Upright_MLDB_Full_Descriptor_Invoker
::
Get_Upright_MLDB_Full_Descriptor
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
,
int
desc_size
)
const
{
float
di
=
0.0
,
dx
=
0.0
,
dy
=
0.0
;
float
ri
=
0.0
,
rx
=
0.0
,
ry
=
0.0
,
xf
=
0.0
,
yf
=
0.0
;
...
...
@@ -1682,16 +1699,14 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
const
AKAZEOptions
&
options
=
*
options_
;
const
std
::
vector
<
Evolution
>&
evolution
=
*
evolution_
;
// Matrices for the M-LDB descriptor
Mat
values
[
3
]
=
{
Mat
(
4
,
options
.
descriptor_channels
,
CV_32FC1
),
Mat
(
9
,
options
.
descriptor_channels
,
CV_32FC1
),
Mat
(
16
,
options
.
descriptor_channels
,
CV_32FC1
)
};
// Buffer for the M-LDB descriptor
const
int
max_channels
=
3
;
CV_Assert
(
options
.
descriptor_channels
<=
max_channels
);
float
values
[
16
*
max_channels
];
// Get the information from the keypoint
ratio
=
(
float
)(
1
<<
kpt
.
octave
);
scale
=
f
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
scale
=
cv
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
const
int
level
=
kpt
.
class_id
;
Mat
Lx
=
evolution
[
level
].
Mx
;
Mat
Ly
=
evolution
[
level
].
My
;
...
...
@@ -1701,12 +1716,15 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
// For 2x2 grid, 3x3 grid and 4x4 grid
const
int
pattern_size
=
options_
->
descriptor_pattern_size
;
int
sample_step
[
3
]
=
{
CV_Assert
((
pattern_size
&
1
)
==
0
);
const
int
sample_step
[
3
]
=
{
pattern_size
,
static_cast
<
int
>
(
ceil
(
pattern_size
*
2.
/
3.
)
),
pattern_size
/
2
divUp
(
pattern_size
*
2
,
3
),
divUp
(
pattern_size
,
2
)
};
memset
(
desc
,
0
,
desc_size
);
// For the three grids
for
(
int
z
=
0
;
z
<
3
;
z
++
)
{
dcount2
=
0
;
...
...
@@ -1723,8 +1741,8 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
sample_y
=
yf
+
l
*
scale
;
sample_x
=
xf
+
k
*
scale
;
y1
=
f
Round
(
sample_y
);
x1
=
f
Round
(
sample_x
);
y1
=
cv
Round
(
sample_y
);
x1
=
cv
Round
(
sample_x
);
ri
=
*
(
Lt
.
ptr
<
float
>
(
y1
)
+
x1
);
rx
=
*
(
Lx
.
ptr
<
float
>
(
y1
)
+
x1
);
...
...
@@ -1741,7 +1759,7 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
dx
/=
nsamples
;
dy
/=
nsamples
;
float
*
val
=
values
[
z
].
ptr
<
float
>
(
dcount2
)
;
float
*
val
=
&
values
[
dcount2
*
max_channels
]
;
*
(
val
)
=
di
;
*
(
val
+
1
)
=
dx
;
*
(
val
+
2
)
=
dy
;
...
...
@@ -1753,13 +1771,11 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
const
int
num
=
(
z
+
2
)
*
(
z
+
2
);
for
(
int
i
=
0
;
i
<
num
;
i
++
)
{
for
(
int
j
=
i
+
1
;
j
<
num
;
j
++
)
{
const
float
*
valI
=
values
[
z
].
ptr
<
float
>
(
i
)
;
const
float
*
valJ
=
values
[
z
].
ptr
<
float
>
(
j
)
;
const
float
*
valI
=
&
values
[
i
*
max_channels
]
;
const
float
*
valJ
=
&
values
[
j
*
max_channels
]
;
for
(
int
k
=
0
;
k
<
3
;
++
k
)
{
if
(
*
(
valI
+
k
)
>
*
(
valJ
+
k
))
{
desc
[
dcount1
/
8
]
|=
(
1
<<
(
dcount1
%
8
));
}
else
{
desc
[
dcount1
/
8
]
&=
~
(
1
<<
(
dcount1
%
8
));
}
dcount1
++
;
}
...
...
@@ -1767,6 +1783,9 @@ void Upright_MLDB_Full_Descriptor_Invoker::Get_Upright_MLDB_Full_Descriptor(cons
}
}
// for (int z = 0; z < 3; z++)
CV_Assert
(
dcount1
<=
desc_size
*
8
);
CV_Assert
(
divUp
(
dcount1
,
8
)
==
desc_size
);
}
void
MLDB_Full_Descriptor_Invoker
::
MLDB_Fill_Values
(
float
*
values
,
int
sample_step
,
const
int
level
,
...
...
@@ -1791,8 +1810,8 @@ void MLDB_Full_Descriptor_Invoker::MLDB_Fill_Values(float* values, int sample_st
float
sample_y
=
yf
+
(
l
*
co
*
scale
+
k
*
si
*
scale
);
float
sample_x
=
xf
+
(
-
l
*
si
*
scale
+
k
*
co
*
scale
);
int
y1
=
f
Round
(
sample_y
);
int
x1
=
f
Round
(
sample_x
);
int
y1
=
cv
Round
(
sample_y
);
int
x1
=
cv
Round
(
sample_x
);
// fix crash: indexing with out-of-bounds index, this might happen near the edges of image
// clip values so they fit into the image
...
...
@@ -1852,10 +1871,6 @@ void MLDB_Full_Descriptor_Invoker::MLDB_Binary_Comparisons(float* values, unsign
if
(
ival
>
ivalues
[
chan
*
j
+
pos
])
{
desc
[
dpos
>>
3
]
|=
(
1
<<
(
dpos
&
7
));
}
else
{
desc
[
dpos
>>
3
]
&=
~
(
1
<<
(
dpos
&
7
));
}
dpos
++
;
}
}
...
...
@@ -1869,30 +1884,41 @@ void MLDB_Full_Descriptor_Invoker::MLDB_Binary_Comparisons(float* values, unsign
* @param kpt Input keypoint
* @param desc Descriptor vector
*/
void
MLDB_Full_Descriptor_Invoker
::
Get_MLDB_Full_Descriptor
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
)
const
{
void
MLDB_Full_Descriptor_Invoker
::
Get_MLDB_Full_Descriptor
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
,
int
desc_size
)
const
{
const
int
max_channels
=
3
;
CV_Assert
(
options_
->
descriptor_channels
<=
max_channels
);
const
int
pattern_size
=
options_
->
descriptor_pattern_size
;
float
values
[
16
*
max_channels
];
const
double
size_mult
[
3
]
=
{
1
,
2.0
/
3.0
,
1.0
/
2.0
};
CV_Assert
((
pattern_size
&
1
)
==
0
);
//const double size_mult[3] = {1, 2.0/3.0, 1.0/2.0};
const
int
sample_step
[
3
]
=
{
// static_cast<int>(ceil(pattern_size * size_mult[lvl]))
pattern_size
,
divUp
(
pattern_size
*
2
,
3
),
divUp
(
pattern_size
,
2
)
};
float
ratio
=
(
float
)(
1
<<
kpt
.
octave
);
float
scale
=
(
float
)
f
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
float
scale
=
(
float
)
cv
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
float
xf
=
kpt
.
pt
.
x
/
ratio
;
float
yf
=
kpt
.
pt
.
y
/
ratio
;
float
angle
=
(
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
))
/
180.
f
;
float
angle
=
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
/
180.
f
)
;
float
co
=
cos
(
angle
);
float
si
=
sin
(
angle
);
int
pattern_size
=
options_
->
descriptor_pattern_size
;
int
dpos
=
0
;
for
(
int
lvl
=
0
;
lvl
<
3
;
lvl
++
)
{
memset
(
desc
,
0
,
desc_size
);
int
dpos
=
0
;
for
(
int
lvl
=
0
;
lvl
<
3
;
lvl
++
)
{
int
val_count
=
(
lvl
+
2
)
*
(
lvl
+
2
);
int
sample_step
=
static_cast
<
int
>
(
ceil
(
pattern_size
*
size_mult
[
lvl
]));
MLDB_Fill_Values
(
values
,
sample_step
,
kpt
.
class_id
,
xf
,
yf
,
co
,
si
,
scale
);
MLDB_Fill_Values
(
values
,
sample_step
[
lvl
],
kpt
.
class_id
,
xf
,
yf
,
co
,
si
,
scale
);
MLDB_Binary_Comparisons
(
values
,
desc
,
val_count
,
dpos
);
}
CV_Assert
(
dpos
==
486
);
CV_Assert
(
divUp
(
dpos
,
8
)
==
desc_size
);
}
/* ************************************************************************* */
...
...
@@ -1903,7 +1929,7 @@ void MLDB_Full_Descriptor_Invoker::Get_MLDB_Full_Descriptor(const KeyPoint& kpt,
* @param kpt Input keypoint
* @param desc Descriptor vector
*/
void
MLDB_Descriptor_Subset_Invoker
::
Get_MLDB_Descriptor_Subset
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
)
const
{
void
MLDB_Descriptor_Subset_Invoker
::
Get_MLDB_Descriptor_Subset
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
,
int
desc_size
)
const
{
float
di
=
0.
f
,
dx
=
0.
f
,
dy
=
0.
f
;
float
rx
=
0.
f
,
ry
=
0.
f
;
...
...
@@ -1915,8 +1941,8 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
// Get the information from the keypoint
float
ratio
=
(
float
)(
1
<<
kpt
.
octave
);
int
scale
=
f
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
float
angle
=
(
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
))
/
180.
f
;
int
scale
=
cv
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
float
angle
=
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
/
180.
f
)
;
const
int
level
=
kpt
.
class_id
;
Mat
Lx
=
evolution
[
level
].
Mx
;
Mat
Ly
=
evolution
[
level
].
My
;
...
...
@@ -1927,17 +1953,25 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
float
si
=
sin
(
angle
);
// Allocate memory for the matrix of values
Mat
values
((
4
+
9
+
16
)
*
options
.
descriptor_channels
,
1
,
CV_32FC1
);
// Buffer for the M-LDB descriptor
const
int
max_channels
=
3
;
const
int
channels
=
options
.
descriptor_channels
;
CV_Assert
(
channels
<=
max_channels
);
float
values
[(
4
+
9
+
16
)
*
max_channels
];
// Sample everything, but only do the comparisons
vector
<
int
>
steps
(
3
);
steps
.
at
(
0
)
=
options
.
descriptor_pattern_size
;
steps
.
at
(
1
)
=
(
int
)
ceil
(
2.
f
*
options
.
descriptor_pattern_size
/
3.
f
);
steps
.
at
(
2
)
=
options
.
descriptor_pattern_size
/
2
;
const
int
pattern_size
=
options
.
descriptor_pattern_size
;
CV_Assert
((
pattern_size
&
1
)
==
0
);
const
int
sample_steps
[
3
]
=
{
pattern_size
,
divUp
(
pattern_size
*
2
,
3
),
divUp
(
pattern_size
,
2
)
};
for
(
int
i
=
0
;
i
<
descriptorSamples_
.
rows
;
i
++
)
{
const
int
*
coords
=
descriptorSamples_
.
ptr
<
int
>
(
i
);
int
sample_step
=
steps
.
at
(
coords
[
0
]);
CV_Assert
(
coords
[
0
]
>=
0
&&
coords
[
0
]
<
3
);
const
int
sample_step
=
sample_steps
[
coords
[
0
]];
di
=
0.0
f
;
dx
=
0.0
f
;
dy
=
0.0
f
;
...
...
@@ -1949,8 +1983,8 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
sample_y
=
yf
+
(
l
*
scale
*
co
+
k
*
scale
*
si
);
sample_x
=
xf
+
(
-
l
*
scale
*
si
+
k
*
scale
*
co
);
y1
=
f
Round
(
sample_y
);
x1
=
f
Round
(
sample_x
);
y1
=
cv
Round
(
sample_y
);
x1
=
cv
Round
(
sample_x
);
di
+=
*
(
Lt
.
ptr
<
float
>
(
y1
)
+
x1
);
...
...
@@ -1970,26 +2004,27 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
}
}
*
(
values
.
ptr
<
float
>
(
options
.
descriptor_channels
*
i
))
=
di
;
float
*
pValues
=
&
values
[
channels
*
i
];
pValues
[
0
]
=
di
;
if
(
options
.
descriptor_
channels
==
2
)
{
*
(
values
.
ptr
<
float
>
(
options
.
descriptor_channels
*
i
+
1
))
=
dx
;
if
(
channels
==
2
)
{
pValues
[
1
]
=
dx
;
}
else
if
(
options
.
descriptor_
channels
==
3
)
{
*
(
values
.
ptr
<
float
>
(
options
.
descriptor_channels
*
i
+
1
))
=
dx
;
*
(
values
.
ptr
<
float
>
(
options
.
descriptor_channels
*
i
+
2
))
=
dy
;
else
if
(
channels
==
3
)
{
pValues
[
1
]
=
dx
;
pValues
[
2
]
=
dy
;
}
}
// Do the comparisons
const
float
*
vals
=
values
.
ptr
<
float
>
(
0
);
const
int
*
comps
=
descriptorBits_
.
ptr
<
int
>
(
0
);
CV_Assert
(
divUp
(
descriptorBits_
.
rows
,
8
)
==
desc_size
);
memset
(
desc
,
0
,
desc_size
);
for
(
int
i
=
0
;
i
<
descriptorBits_
.
rows
;
i
++
)
{
if
(
val
s
[
comps
[
2
*
i
]]
>
val
s
[
comps
[
2
*
i
+
1
]])
{
if
(
val
ues
[
comps
[
2
*
i
]]
>
value
s
[
comps
[
2
*
i
+
1
]])
{
desc
[
i
/
8
]
|=
(
1
<<
(
i
%
8
));
}
else
{
desc
[
i
/
8
]
&=
~
(
1
<<
(
i
%
8
));
}
}
}
...
...
@@ -2002,7 +2037,7 @@ void MLDB_Descriptor_Subset_Invoker::Get_MLDB_Descriptor_Subset(const KeyPoint&
* @param kpt Input keypoint
* @param desc Descriptor vector
*/
void
Upright_MLDB_Descriptor_Subset_Invoker
::
Get_Upright_MLDB_Descriptor_Subset
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
)
const
{
void
Upright_MLDB_Descriptor_Subset_Invoker
::
Get_Upright_MLDB_Descriptor_Subset
(
const
KeyPoint
&
kpt
,
unsigned
char
*
desc
,
int
desc_size
)
const
{
float
di
=
0.0
f
,
dx
=
0.0
f
,
dy
=
0.0
f
;
float
rx
=
0.0
f
,
ry
=
0.0
f
;
...
...
@@ -2014,7 +2049,7 @@ void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(
// Get the information from the keypoint
float
ratio
=
(
float
)(
1
<<
kpt
.
octave
);
int
scale
=
f
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
int
scale
=
cv
Round
(
0.5
f
*
kpt
.
size
/
ratio
);
const
int
level
=
kpt
.
class_id
;
Mat
Lx
=
evolution
[
level
].
Mx
;
Mat
Ly
=
evolution
[
level
].
My
;
...
...
@@ -2025,14 +2060,18 @@ void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(
// Allocate memory for the matrix of values
Mat
values
((
4
+
9
+
16
)
*
options
.
descriptor_channels
,
1
,
CV_32FC1
);
vector
<
int
>
steps
(
3
);
steps
.
at
(
0
)
=
options
.
descriptor_pattern_size
;
steps
.
at
(
1
)
=
static_cast
<
int
>
(
ceil
(
2.
f
*
options
.
descriptor_pattern_size
/
3.
f
));
steps
.
at
(
2
)
=
options
.
descriptor_pattern_size
/
2
;
const
int
pattern_size
=
options
.
descriptor_pattern_size
;
CV_Assert
((
pattern_size
&
1
)
==
0
);
const
int
sample_steps
[
3
]
=
{
pattern_size
,
divUp
(
pattern_size
*
2
,
3
),
divUp
(
pattern_size
,
2
)
};
for
(
int
i
=
0
;
i
<
descriptorSamples_
.
rows
;
i
++
)
{
const
int
*
coords
=
descriptorSamples_
.
ptr
<
int
>
(
i
);
int
sample_step
=
steps
.
at
(
coords
[
0
]);
CV_Assert
(
coords
[
0
]
>=
0
&&
coords
[
0
]
<
3
);
int
sample_step
=
sample_steps
[
coords
[
0
]];
di
=
0.0
f
,
dx
=
0.0
f
,
dy
=
0.0
f
;
for
(
int
k
=
coords
[
1
];
k
<
coords
[
1
]
+
sample_step
;
k
++
)
{
...
...
@@ -2042,8 +2081,8 @@ void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(
sample_y
=
yf
+
l
*
scale
;
sample_x
=
xf
+
k
*
scale
;
y1
=
f
Round
(
sample_y
);
x1
=
f
Round
(
sample_x
);
y1
=
cv
Round
(
sample_y
);
x1
=
cv
Round
(
sample_x
);
di
+=
*
(
Lt
.
ptr
<
float
>
(
y1
)
+
x1
);
if
(
options
.
descriptor_channels
>
1
)
{
...
...
@@ -2076,11 +2115,12 @@ void Upright_MLDB_Descriptor_Subset_Invoker::Get_Upright_MLDB_Descriptor_Subset(
const
float
*
vals
=
values
.
ptr
<
float
>
(
0
);
const
int
*
comps
=
descriptorBits_
.
ptr
<
int
>
(
0
);
CV_Assert
(
divUp
(
descriptorBits_
.
rows
,
8
)
==
desc_size
);
memset
(
desc
,
0
,
desc_size
);
for
(
int
i
=
0
;
i
<
descriptorBits_
.
rows
;
i
++
)
{
if
(
vals
[
comps
[
2
*
i
]]
>
vals
[
comps
[
2
*
i
+
1
]])
{
desc
[
i
/
8
]
|=
(
1
<<
(
i
%
8
));
}
else
{
desc
[
i
/
8
]
&=
~
(
1
<<
(
i
%
8
));
}
}
}
...
...
@@ -2120,7 +2160,7 @@ void generateDescriptorSubsample(Mat& sampleList, Mat& comparisons, int nbits,
for
(
int
i
=
0
,
c
=
0
;
i
<
3
;
i
++
)
{
int
gdiv
=
i
+
2
;
//grid divisions, per row
int
gsz
=
gdiv
*
gdiv
;
int
psz
=
(
int
)
ceil
(
2.
f
*
pattern_size
/
(
float
)
gdiv
);
int
psz
=
divUp
(
2
*
pattern_size
,
gdiv
);
for
(
int
j
=
0
;
j
<
gsz
;
j
++
)
{
for
(
int
k
=
j
+
1
;
k
<
gsz
;
k
++
,
c
++
)
{
...
...
@@ -2134,12 +2174,12 @@ void generateDescriptorSubsample(Mat& sampleList, Mat& comparisons, int nbits,
}
RNG
rng
(
1024
);
Mat_
<
int
>
comps
=
Mat_
<
int
>
(
nchannels
*
(
int
)
ceil
(
nbits
/
(
float
)
nchannels
),
2
);
const
int
npicks
=
divUp
(
nbits
,
nchannels
);
Mat_
<
int
>
comps
=
Mat_
<
int
>
(
nchannels
*
npicks
,
2
);
comps
=
1000
;
// Select some samples. A sample includes all channels
int
count
=
0
;
int
npicks
=
(
int
)
ceil
(
nbits
/
(
float
)
nchannels
);
Mat_
<
int
>
samples
(
29
,
3
);
Mat_
<
int
>
fullcopy
=
fullM
.
clone
();
samples
=
-
1
;
...
...
modules/features2d/src/kaze/AKAZEFeatures.h
View file @
922ac1a1
...
...
@@ -25,6 +25,8 @@ struct Evolution
octave
=
0
;
sublevel
=
0
;
sigma_size
=
0
;
octave_ratio
=
0
.
0
f
;
border
=
0
;
}
UMat
Lx
,
Ly
;
///< First order spatial derivatives
...
...
modules/features2d/src/kaze/KAZEFeatures.cpp
View file @
922ac1a1
...
...
@@ -68,7 +68,7 @@ void KAZEFeatures::Allocate_Memory_Evolution(void) {
aux
.
Ldet
=
Mat
::
zeros
(
options_
.
img_height
,
options_
.
img_width
,
CV_32F
);
aux
.
esigma
=
options_
.
soffset
*
pow
((
float
)
2.0
f
,
(
float
)(
j
)
/
(
float
)(
options_
.
nsublevels
)
+
i
);
aux
.
etime
=
0.5
f
*
(
aux
.
esigma
*
aux
.
esigma
);
aux
.
sigma_size
=
f
Round
(
aux
.
esigma
);
aux
.
sigma_size
=
cv
Round
(
aux
.
esigma
);
aux
.
octave
=
i
;
aux
.
sublevel
=
j
;
evolution_
.
push_back
(
aux
);
...
...
@@ -363,10 +363,10 @@ void KAZEFeatures::Determinant_Hessian(std::vector<KeyPoint>& kpts)
if
(
is_extremum
==
true
)
{
// Check that the point is under the image limits for the descriptor computation
left_x
=
f
Round
(
kpts_par_
[
i
][
j
].
pt
.
x
-
smax
*
kpts_par_
[
i
][
j
].
size
);
right_x
=
f
Round
(
kpts_par_
[
i
][
j
].
pt
.
x
+
smax
*
kpts_par_
[
i
][
j
].
size
);
up_y
=
f
Round
(
kpts_par_
[
i
][
j
].
pt
.
y
-
smax
*
kpts_par_
[
i
][
j
].
size
);
down_y
=
f
Round
(
kpts_par_
[
i
][
j
].
pt
.
y
+
smax
*
kpts_par_
[
i
][
j
].
size
);
left_x
=
cv
Round
(
kpts_par_
[
i
][
j
].
pt
.
x
-
smax
*
kpts_par_
[
i
][
j
].
size
);
right_x
=
cv
Round
(
kpts_par_
[
i
][
j
].
pt
.
x
+
smax
*
kpts_par_
[
i
][
j
].
size
);
up_y
=
cv
Round
(
kpts_par_
[
i
][
j
].
pt
.
y
-
smax
*
kpts_par_
[
i
][
j
].
size
);
down_y
=
cv
Round
(
kpts_par_
[
i
][
j
].
pt
.
y
+
smax
*
kpts_par_
[
i
][
j
].
size
);
if
(
left_x
<
0
||
right_x
>=
evolution_
[
level
].
Ldet
.
cols
||
up_y
<
0
||
down_y
>=
evolution_
[
level
].
Ldet
.
rows
)
{
...
...
@@ -587,14 +587,14 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv
xf
=
kpt
.
pt
.
x
;
yf
=
kpt
.
pt
.
y
;
level
=
kpt
.
class_id
;
s
=
f
Round
(
kpt
.
size
/
2.0
f
);
s
=
cv
Round
(
kpt
.
size
/
2.0
f
);
// Calculate derivatives responses for points within radius of 6*scale
for
(
int
i
=
-
6
;
i
<=
6
;
++
i
)
{
for
(
int
j
=
-
6
;
j
<=
6
;
++
j
)
{
if
(
i
*
i
+
j
*
j
<
36
)
{
iy
=
f
Round
(
yf
+
j
*
s
);
ix
=
f
Round
(
xf
+
i
*
s
);
iy
=
cv
Round
(
yf
+
j
*
s
);
ix
=
cv
Round
(
xf
+
i
*
s
);
if
(
iy
>=
0
&&
iy
<
options
.
img_height
&&
ix
>=
0
&&
ix
<
options
.
img_width
)
{
gweight
=
gaussian
(
iy
-
yf
,
ix
-
xf
,
2.5
f
*
s
);
...
...
@@ -606,7 +606,7 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv
resY
[
idx
]
=
0.0
;
}
Ang
[
idx
]
=
getAngle
(
resX
[
idx
],
resY
[
idx
]
);
Ang
[
idx
]
=
fastAtan2
(
resX
[
idx
],
resY
[
idx
])
*
(
float
)(
CV_PI
/
180.0
f
);
++
idx
;
}
}
...
...
@@ -638,7 +638,7 @@ void KAZEFeatures::Compute_Main_Orientation(KeyPoint &kpt, const std::vector<TEv
if
(
sumX
*
sumX
+
sumY
*
sumY
>
max
)
{
// store largest orientation
max
=
sumX
*
sumX
+
sumY
*
sumY
;
kpt
.
angle
=
getAngle
(
sumX
,
sumY
)
*
180.
f
/
static_cast
<
float
>
(
CV_PI
);
kpt
.
angle
=
fastAtan2
(
sumX
,
sumY
);
}
}
}
...
...
@@ -676,7 +676,7 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_64(const KeyPoint &kpt
// Get the information from the keypoint
yf
=
kpt
.
pt
.
y
;
xf
=
kpt
.
pt
.
x
;
scale
=
f
Round
(
kpt
.
size
/
2.0
f
);
scale
=
cv
Round
(
kpt
.
size
/
2.0
f
);
level
=
kpt
.
class_id
;
i
=
-
8
;
...
...
@@ -804,8 +804,8 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_64(const KeyPoint &kpt, float
// Get the information from the keypoint
yf
=
kpt
.
pt
.
y
;
xf
=
kpt
.
pt
.
x
;
scale
=
f
Round
(
kpt
.
size
/
2.0
f
);
angle
=
(
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
))
/
180.
f
;
scale
=
cv
Round
(
kpt
.
size
/
2.0
f
);
angle
=
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
/
180.
f
)
;
level
=
kpt
.
class_id
;
co
=
cos
(
angle
);
si
=
sin
(
angle
);
...
...
@@ -843,13 +843,13 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_64(const KeyPoint &kpt, float
// Get the gaussian weighted x and y responses
gauss_s1
=
gaussian
(
xs
-
sample_x
,
ys
-
sample_y
,
2.5
f
*
scale
);
y1
=
fRound
(
sample_y
-
0.5
f
);
x1
=
fRound
(
sample_x
-
0.5
f
);
y1
=
cvFloor
(
sample_y
);
x1
=
cvFloor
(
sample_x
);
checkDescriptorLimits
(
x1
,
y1
,
options_
.
img_width
,
options_
.
img_height
);
y2
=
(
int
)(
sample_y
+
0.5
f
)
;
x2
=
(
int
)(
sample_x
+
0.5
f
)
;
y2
=
y1
+
1
;
x2
=
x1
+
1
;
checkDescriptorLimits
(
x2
,
y2
,
options_
.
img_width
,
options_
.
img_height
);
...
...
@@ -935,7 +935,7 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Upright_Descriptor_128(const KeyPoint &kp
// Get the information from the keypoint
yf
=
kpt
.
pt
.
y
;
xf
=
kpt
.
pt
.
x
;
scale
=
f
Round
(
kpt
.
size
/
2.0
f
);
scale
=
cv
Round
(
kpt
.
size
/
2.0
f
);
level
=
kpt
.
class_id
;
i
=
-
8
;
...
...
@@ -1087,8 +1087,8 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_128(const KeyPoint &kpt, float
// Get the information from the keypoint
yf
=
kpt
.
pt
.
y
;
xf
=
kpt
.
pt
.
x
;
scale
=
f
Round
(
kpt
.
size
/
2.0
f
);
angle
=
(
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
))
/
180.
f
;
scale
=
cv
Round
(
kpt
.
size
/
2.0
f
);
angle
=
kpt
.
angle
*
static_cast
<
float
>
(
CV_PI
/
180.
f
)
;
level
=
kpt
.
class_id
;
co
=
cos
(
angle
);
si
=
sin
(
angle
);
...
...
@@ -1129,13 +1129,13 @@ void KAZE_Descriptor_Invoker::Get_KAZE_Descriptor_128(const KeyPoint &kpt, float
// Get the gaussian weighted x and y responses
gauss_s1
=
gaussian
(
xs
-
sample_x
,
ys
-
sample_y
,
2.5
f
*
scale
);
y1
=
fRound
(
sample_y
-
0.5
f
);
x1
=
fRound
(
sample_x
-
0.5
f
);
y1
=
cvFloor
(
sample_y
);
x1
=
cvFloor
(
sample_x
);
checkDescriptorLimits
(
x1
,
y1
,
options_
.
img_width
,
options_
.
img_height
);
y2
=
(
int
)(
sample_y
+
0.5
f
)
;
x2
=
(
int
)(
sample_x
+
0.5
f
)
;
y2
=
y1
+
1
;
x2
=
x1
+
1
;
checkDescriptorLimits
(
x2
,
y2
,
options_
.
img_width
,
options_
.
img_height
);
...
...
modules/features2d/src/kaze/fed.cpp
View file @
922ac1a1
...
...
@@ -72,7 +72,7 @@ int fed_tau_by_cycle_time(const float& t, const float& tau_max,
float
scale
=
0.0
;
// Ratio of t we search to maximal t
// Compute necessary number of time steps
n
=
(
int
)(
ceilf
(
sqrtf
(
3.0
f
*
t
/
tau_max
+
0.25
f
)
-
0.5
f
-
1.0e-8
f
)
+
0.5
f
);
n
=
cvCeil
(
sqrtf
(
3.0
f
*
t
/
tau_max
+
0.25
f
)
-
0.5
f
-
1.0e-8
f
);
scale
=
3.0
f
*
t
/
(
tau_max
*
(
float
)(
n
*
(
n
+
1
)));
// Call internal FED time step creation routine
...
...
modules/features2d/src/kaze/nldiffusion_functions.cpp
View file @
922ac1a1
...
...
@@ -49,7 +49,7 @@ void gaussian_2D_convolution(const cv::Mat& src, cv::Mat& dst, int ksize_x, int
// Compute an appropriate kernel size according to the specified sigma
if
(
sigma
>
ksize_x
||
sigma
>
ksize_y
||
ksize_x
==
0
||
ksize_y
==
0
)
{
ksize_x_
=
(
int
)
c
eil
(
2.0
f
*
(
1.0
f
+
(
sigma
-
0.8
f
)
/
(
0.3
f
)));
ksize_x_
=
cvC
eil
(
2.0
f
*
(
1.0
f
+
(
sigma
-
0.8
f
)
/
(
0.3
f
)));
ksize_y_
=
ksize_x_
;
}
...
...
modules/features2d/src/kaze/utils.h
View file @
922ac1a1
#ifndef __OPENCV_FEATURES_2D_KAZE_UTILS_H__
#define __OPENCV_FEATURES_2D_KAZE_UTILS_H__
/* ************************************************************************* */
/**
* @brief This function computes the angle from the vector given by (X Y). From 0 to 2*Pi
*/
inline
float
getAngle
(
float
x
,
float
y
)
{
if
(
x
>=
0
&&
y
>=
0
)
{
return
atanf
(
y
/
x
);
}
if
(
x
<
0
&&
y
>=
0
)
{
return
static_cast
<
float
>
(
CV_PI
)
-
atanf
(
-
y
/
x
);
}
if
(
x
<
0
&&
y
<
0
)
{
return
static_cast
<
float
>
(
CV_PI
)
+
atanf
(
y
/
x
);
}
if
(
x
>=
0
&&
y
<
0
)
{
return
static_cast
<
float
>
(
2
.
0
*
CV_PI
)
-
atanf
(
-
y
/
x
);
}
return
0
;
}
/* ************************************************************************* */
/**
* @brief This function computes the value of a 2D Gaussian function
...
...
@@ -64,34 +39,4 @@ inline void checkDescriptorLimits(int &x, int &y, int width, int height) {
}
}
/* ************************************************************************* */
/**
* @brief This funtion rounds float to nearest integer
* @param flt Input float
* @return dst Nearest integer
*/
inline
int
fRound
(
float
flt
)
{
return
(
int
)(
flt
+
0
.
5
f
);
}
/* ************************************************************************* */
/**
* @brief Exponentiation by squaring
* @param flt Exponentiation base
* @return dst Exponentiation value
*/
inline
int
fastpow
(
int
base
,
int
exp
)
{
int
res
=
1
;
while
(
exp
>
0
)
{
if
(
exp
&
1
)
{
exp
--
;
res
*=
base
;
}
else
{
exp
/=
2
;
base
*=
base
;
}
}
return
res
;
}
#endif
modules/features2d/test/test_descriptors_invariance.cpp
View file @
922ac1a1
...
...
@@ -11,7 +11,7 @@ using std::tr1::make_tuple;
using
std
::
tr1
::
get
;
using
namespace
testing
;
#define SHOW_DEBUG_LOG
0
#define SHOW_DEBUG_LOG
1
typedef
std
::
tr1
::
tuple
<
std
::
string
,
Ptr
<
FeatureDetector
>
,
Ptr
<
DescriptorExtractor
>
,
float
>
String_FeatureDetector_DescriptorExtractor_Float_t
;
...
...
@@ -72,7 +72,7 @@ TEST_P(DescriptorRotationInvariance, rotation)
vector
<
KeyPoint
>
keypoints0
;
Mat
descriptors0
;
featureDetector
->
detect
(
image0
,
keypoints0
,
mask0
);
std
::
cout
<<
"
Intial k
eypoints: "
<<
keypoints0
.
size
()
<<
std
::
endl
;
std
::
cout
<<
"
K
eypoints: "
<<
keypoints0
.
size
()
<<
std
::
endl
;
EXPECT_GE
(
keypoints0
.
size
(),
15u
);
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
...
...
@@ -109,7 +109,7 @@ TEST_P(DescriptorRotationInvariance, rotation)
#if SHOW_DEBUG_LOG
std
::
cout
<<
"angle = "
<<
angle
<<
",
keypoints = "
<<
keypoints1
.
size
()
<<
",
inliers = "
<<
descInliersCount
<<
", descInliersRatio = "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
()
<<
std
::
endl
;
#endif
...
...
@@ -121,6 +121,7 @@ TEST_P(DescriptorScaleInvariance, scale)
{
vector
<
KeyPoint
>
keypoints0
;
featureDetector
->
detect
(
image0
,
keypoints0
);
std
::
cout
<<
"Keypoints: "
<<
keypoints0
.
size
()
<<
std
::
endl
;
EXPECT_GE
(
keypoints0
.
size
(),
15u
);
Mat
descriptors0
;
descriptorExtractor
->
compute
(
image0
,
keypoints0
,
descriptors0
);
...
...
@@ -159,6 +160,7 @@ TEST_P(DescriptorScaleInvariance, scale)
#if SHOW_DEBUG_LOG
std
::
cout
<<
"scale = "
<<
scale
<<
", inliers = "
<<
descInliersCount
<<
", descInliersRatio = "
<<
static_cast
<
float
>
(
descInliersCount
)
/
keypoints0
.
size
()
<<
std
::
endl
;
#endif
...
...
modules/features2d/test/test_descriptors_regression.cpp
View file @
922ac1a1
...
...
@@ -56,6 +56,7 @@ static void writeMatInBin( const Mat& mat, const string& filename )
FILE
*
f
=
fopen
(
filename
.
c_str
(),
"wb"
);
if
(
f
)
{
CV_Assert
(
4
==
sizeof
(
int
));
int
type
=
mat
.
type
();
fwrite
(
(
void
*
)
&
mat
.
rows
,
sizeof
(
int
),
1
,
f
);
fwrite
(
(
void
*
)
&
mat
.
cols
,
sizeof
(
int
),
1
,
f
);
...
...
@@ -72,6 +73,7 @@ static Mat readMatFromBin( const string& filename )
FILE
*
f
=
fopen
(
filename
.
c_str
(),
"rb"
);
if
(
f
)
{
CV_Assert
(
4
==
sizeof
(
int
));
int
rows
,
cols
,
type
,
dataSize
;
size_t
elements_read1
=
fread
(
(
void
*
)
&
rows
,
sizeof
(
int
),
1
,
f
);
size_t
elements_read2
=
fread
(
(
void
*
)
&
cols
,
sizeof
(
int
),
1
,
f
);
...
...
@@ -123,24 +125,37 @@ protected:
CV_Assert
(
DataType
<
ValueType
>::
type
==
validDescriptors
.
type
()
);
int
dimension
=
validDescriptors
.
cols
;
DistanceType
curMaxDist
=
std
::
numeric_limits
<
DistanceType
>::
min
();
DistanceType
curMaxDist
=
0
;
size_t
exact_count
=
0
,
failed_count
=
0
;
for
(
int
y
=
0
;
y
<
validDescriptors
.
rows
;
y
++
)
{
DistanceType
dist
=
distance
(
validDescriptors
.
ptr
<
ValueType
>
(
y
),
calcDescriptors
.
ptr
<
ValueType
>
(
y
),
dimension
);
if
(
dist
==
0
)
exact_count
++
;
if
(
dist
>
curMaxDist
)
{
if
(
dist
>
maxDist
)
failed_count
++
;
curMaxDist
=
dist
;
}
stringstream
ss
;
ss
<<
"Max distance between valid and computed descriptors "
<<
curMaxDist
;
if
(
curMaxDist
<=
maxDist
)
ss
<<
"."
<<
endl
;
else
#if 0
if (dist > 0)
{
ss
<<
">"
<<
maxDist
<<
" - bad accuracy!"
<<
endl
;
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
std::cout << "i=" << y << " fail_count=" << failed_count << " dist=" << dist << std::endl;
std::cout << "valid: " << validDescriptors.row(y) << std::endl;
std::cout << " calc: " << calcDescriptors.row(y) << std::endl;
}
#endif
}
ts
->
printf
(
cvtest
::
TS
::
LOG
,
ss
.
str
().
c_str
()
);
float
exact_percents
=
(
100
*
(
float
)
exact_count
/
validDescriptors
.
rows
);
float
failed_percents
=
(
100
*
(
float
)
failed_count
/
validDescriptors
.
rows
);
stringstream
ss
;
ss
<<
"Exact count (dist == 0): "
<<
exact_count
<<
" ("
<<
(
int
)
exact_percents
<<
"%)"
<<
std
::
endl
<<
"Failed count (dist > "
<<
maxDist
<<
"): "
<<
failed_count
<<
" ("
<<
(
int
)
failed_percents
<<
"%)"
<<
std
::
endl
<<
"Max distance between valid and computed descriptors ("
<<
validDescriptors
.
size
()
<<
"): "
<<
curMaxDist
;
EXPECT_LE
(
failed_percents
,
20.0
f
);
std
::
cout
<<
ss
.
str
()
<<
std
::
endl
;
}
void
emptyDataTest
()
...
...
@@ -202,22 +217,57 @@ protected:
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_TEST_DATA
);
return
;
}
const
std
::
string
keypoints_filename
=
string
(
ts
->
get_data_path
())
+
(
detector
.
empty
()
?
(
FEATURES2D_DIR
+
"/"
+
std
::
string
(
"keypoints.xml.gz"
))
:
(
DESCRIPTOR_DIR
+
"/"
+
name
+
"_keypoints.xml.gz"
));
FileStorage
fs
(
keypoints_filename
,
FileStorage
::
READ
);
vector
<
KeyPoint
>
keypoints
;
FileStorage
fs
(
string
(
ts
->
get_data_path
())
+
FEATURES2D_DIR
+
"/keypoints.xml.gz"
,
FileStorage
::
READ
);
if
(
!
detector
.
empty
())
{
EXPECT_TRUE
(
fs
.
isOpened
())
<<
"Keypoint testdata is missing. Re-computing and re-writing keypoints testdata..."
;
if
(
!
fs
.
isOpened
())
{
fs
.
open
(
keypoints_filename
,
FileStorage
::
WRITE
);
ASSERT_TRUE
(
fs
.
isOpened
())
<<
"File for writting keypoints can not be opened."
;
if
(
detector
.
empty
())
{
Ptr
<
ORB
>
fd
=
ORB
::
create
();
fd
->
detect
(
img
,
keypoints
);
}
else
{
detector
->
detect
(
img
,
keypoints
);
}
else
{
read
(
fs
.
getFirstTopLevelNode
(),
keypoints
);
}
if
(
!
keypoints
.
empty
())
write
(
fs
,
"keypoints"
,
keypoints
);
fs
.
release
();
}
else
{
read
(
fs
.
getFirstTopLevelNode
(),
keypoints
);
fs
.
release
();
}
if
(
!
detector
.
empty
())
{
vector
<
KeyPoint
>
calcKeypoints
;
detector
->
detect
(
img
,
calcKeypoints
);
// TODO validate received keypoints
int
diff
=
abs
((
int
)
calcKeypoints
.
size
()
-
(
int
)
keypoints
.
size
());
if
(
diff
>
0
)
{
std
::
cout
<<
"Keypoints difference: "
<<
diff
<<
std
::
endl
;
EXPECT_LE
(
diff
,
(
int
)(
keypoints
.
size
()
*
0.03
f
));
}
}
ASSERT_FALSE
(
keypoints
.
empty
());
{
Mat
calcDescriptors
;
double
t
=
(
double
)
getTickCount
();
dextractor
->
compute
(
img
,
keypoints
,
calcDescriptors
);
dextractor
->
compute
(
img
,
keypoints
,
calcDescriptors
);
t
=
getTickCount
()
-
t
;
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"
\n
Average time of computing one descriptor = %g ms.
\n
"
,
t
/
((
double
)
getTickFrequency
()
*
1000.
)
/
calcDescriptors
.
rows
);
if
(
calcDescriptors
.
rows
!=
(
int
)
keypoints
.
size
()
)
if
(
calcDescriptors
.
rows
!=
(
int
)
keypoints
.
size
()
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Count of computed descriptors and keypoints count must be equal.
\n
"
);
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Count of keypoints is %d.
\n
"
,
(
int
)
keypoints
.
size
()
);
...
...
@@ -226,7 +276,7 @@ protected:
return
;
}
if
(
calcDescriptors
.
cols
!=
dextractor
->
descriptorSize
()
||
calcDescriptors
.
type
()
!=
dextractor
->
descriptorType
()
)
if
(
calcDescriptors
.
cols
!=
dextractor
->
descriptorSize
()
||
calcDescriptors
.
type
()
!=
dextractor
->
descriptorType
()
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Incorrect descriptor size or descriptor type.
\n
"
);
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Expected size is %d.
\n
"
,
dextractor
->
descriptorSize
()
);
...
...
@@ -239,33 +289,14 @@ protected:
// TODO read and write descriptor extractor parameters and check them
Mat
validDescriptors
=
readDescriptors
();
if
(
!
validDescriptors
.
empty
()
)
compareDescriptors
(
validDescriptors
,
calcDescriptors
);
else
{
if
(
!
writeDescriptors
(
calcDescriptors
)
)
EXPECT_FALSE
(
validDescriptors
.
empty
())
<<
"Descriptors testdata is missing. Re-writing descriptors testdata..."
;
if
(
!
validDescriptors
.
empty
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Descriptors can not be written.
\n
"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_TEST_DATA
);
return
;
}
}
}
if
(
!
fs
.
isOpened
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Compute and write keypoints.
\n
"
);
fs
.
open
(
string
(
ts
->
get_data_path
())
+
FEATURES2D_DIR
+
"/keypoints.xml.gz"
,
FileStorage
::
WRITE
);
if
(
fs
.
isOpened
()
)
{
Ptr
<
ORB
>
fd
=
ORB
::
create
();
fd
->
detect
(
img
,
keypoints
);
write
(
fs
,
"keypoints"
,
keypoints
);
compareDescriptors
(
validDescriptors
,
calcDescriptors
);
}
else
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"File for writting keypoints can not be opened.
\n
"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_TEST_DATA
);
return
;
ASSERT_TRUE
(
writeDescriptors
(
calcDescriptors
))
<<
"Descriptors can not be written."
;
}
}
}
...
...
@@ -344,7 +375,7 @@ TEST( Features2d_DescriptorExtractor_KAZE, regression )
TEST
(
Features2d_DescriptorExtractor_AKAZE
,
regression
)
{
CV_DescriptorExtractorTest
<
Hamming
>
test
(
"descriptor-akaze"
,
(
CV_DescriptorExtractorTest
<
Hamming
>::
DistanceType
)
12.
f
,
(
CV_DescriptorExtractorTest
<
Hamming
>::
DistanceType
)
(
486
*
0.05
f
)
,
AKAZE
::
create
(),
Hamming
(),
AKAZE
::
create
());
test
.
safe_run
();
...
...
modules/features2d/test/test_detectors_invariance.cpp
View file @
922ac1a1
...
...
@@ -11,7 +11,7 @@ using std::tr1::make_tuple;
using
std
::
tr1
::
get
;
using
namespace
testing
;
#define SHOW_DEBUG_LOG
0
#define SHOW_DEBUG_LOG
1
typedef
std
::
tr1
::
tuple
<
std
::
string
,
Ptr
<
FeatureDetector
>
,
float
,
float
>
String_FeatureDetector_Float_Float_t
;
const
static
std
::
string
IMAGE_TSUKUBA
=
"features2d/tsukuba.png"
;
...
...
modules/photo/src/fast_nlmeans_denoising_opencl.hpp
View file @
922ac1a1
...
...
@@ -23,11 +23,6 @@ enum
CTA_SIZE_DEFAULT
=
256
};
static
int
divUp
(
int
a
,
int
b
)
{
return
(
a
+
b
-
1
)
/
b
;
}
template
<
typename
FT
,
typename
ST
,
typename
WT
>
static
bool
ocl_calcAlmostDist2Weight
(
UMat
&
almostDist2Weight
,
int
searchWindowSize
,
int
templateWindowSize
,
...
...
modules/stitching/perf/perf_stich.cpp
View file @
922ac1a1
...
...
@@ -102,7 +102,7 @@ PERF_TEST_P(stitchDatasets, affine, testing::Combine(AFFINE_DATASETS, TEST_DETEC
Mat
pano
;
vector
<
Mat
>
imgs
;
int
width
,
height
,
allowed_diff
=
1
0
;
int
width
,
height
,
allowed_diff
=
2
0
;
Ptr
<
detail
::
FeaturesFinder
>
featuresFinder
=
getFeatureFinder
(
detector
);
if
(
dataset
==
"budapest"
)
...
...
@@ -117,7 +117,7 @@ PERF_TEST_P(stitchDatasets, affine, testing::Combine(AFFINE_DATASETS, TEST_DETEC
height
=
1158
;
// this dataset is big, the results between surf and orb differ slightly,
// but both are still good
allowed_diff
=
27
;
allowed_diff
=
50
;
}
else
if
(
dataset
==
"newspaper"
)
{
...
...
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