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
f960a570
Commit
f960a570
authored
Jan 13, 2015
by
Vladislav Vinogradov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor CUDA ORB feature detector/extractor algorithm:
use new abstract interface and hidden implementation
parent
554ddd2e
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
240 additions
and
235 deletions
+240
-235
cudafeatures2d.hpp
modules/cudafeatures2d/include/opencv2/cudafeatures2d.hpp
+17
-108
perf_features2d.cpp
modules/cudafeatures2d/perf/perf_features2d.cpp
+3
-3
orb.cpp
modules/cudafeatures2d/src/orb.cpp
+211
-116
test_features2d.cpp
modules/cudafeatures2d/test/test_features2d.cpp
+6
-5
tests.cpp
samples/gpu/performance/tests.cpp
+3
-3
No files found.
modules/cudafeatures2d/include/opencv2/cudafeatures2d.hpp
View file @
f960a570
...
...
@@ -284,9 +284,11 @@ public:
virtual
int
getMaxNumPoints
()
const
=
0
;
};
/** @brief Class for extracting ORB features and descriptors from an image. :
*/
class
CV_EXPORTS
ORB_CUDA
//
// ORB
//
class
CV_EXPORTS
ORB
:
public
cv
::
ORB
,
public
Feature2DAsync
{
public
:
enum
...
...
@@ -300,113 +302,20 @@ public:
ROWS_COUNT
};
enum
{
DEFAULT_FAST_THRESHOLD
=
20
};
/** @brief Constructor.
@param nFeatures The number of desired features.
@param scaleFactor Coefficient by which we divide the dimensions from one scale pyramid level to
the next.
@param nLevels The number of levels in the scale pyramid.
@param edgeThreshold How far from the boundary the points should be.
@param firstLevel The level at which the image is given. If 1, that means we will also look at the
image scaleFactor times bigger.
@param WTA_K
@param scoreType
@param patchSize
*/
explicit
ORB_CUDA
(
int
nFeatures
=
500
,
float
scaleFactor
=
1.2
f
,
int
nLevels
=
8
,
int
edgeThreshold
=
31
,
int
firstLevel
=
0
,
int
WTA_K
=
2
,
int
scoreType
=
0
,
int
patchSize
=
31
);
/** @overload */
void
operator
()(
const
GpuMat
&
image
,
const
GpuMat
&
mask
,
std
::
vector
<
KeyPoint
>&
keypoints
);
/** @overload */
void
operator
()(
const
GpuMat
&
image
,
const
GpuMat
&
mask
,
GpuMat
&
keypoints
);
/** @brief Detects keypoints and computes descriptors for them.
@param image Input 8-bit grayscale image.
@param mask Optional input mask that marks the regions where we should detect features.
@param keypoints The input/output vector of keypoints. Can be stored both in CPU and GPU memory.
For GPU memory:
- keypoints.ptr\<float\>(X_ROW)[i] contains x coordinate of the i'th feature.
- keypoints.ptr\<float\>(Y_ROW)[i] contains y coordinate of the i'th feature.
- keypoints.ptr\<float\>(RESPONSE_ROW)[i] contains the response of the i'th feature.
- keypoints.ptr\<float\>(ANGLE_ROW)[i] contains orientation of the i'th feature.
- keypoints.ptr\<float\>(OCTAVE_ROW)[i] contains the octave of the i'th feature.
- keypoints.ptr\<float\>(SIZE_ROW)[i] contains the size of the i'th feature.
@param descriptors Computed descriptors. if blurForDescriptor is true, image will be blurred
before descriptors calculation.
*/
void
operator
()(
const
GpuMat
&
image
,
const
GpuMat
&
mask
,
std
::
vector
<
KeyPoint
>&
keypoints
,
GpuMat
&
descriptors
);
/** @overload */
void
operator
()(
const
GpuMat
&
image
,
const
GpuMat
&
mask
,
GpuMat
&
keypoints
,
GpuMat
&
descriptors
);
/** @brief Download keypoints from GPU to CPU memory.
*/
static
void
downloadKeyPoints
(
const
GpuMat
&
d_keypoints
,
std
::
vector
<
KeyPoint
>&
keypoints
);
/** @brief Converts keypoints from CUDA representation to vector of KeyPoint.
*/
static
void
convertKeyPoints
(
const
Mat
&
d_keypoints
,
std
::
vector
<
KeyPoint
>&
keypoints
);
//! returns the descriptor size in bytes
inline
int
descriptorSize
()
const
{
return
kBytes
;
}
inline
void
setFastParams
(
int
threshold
,
bool
nonmaxSuppression
=
true
)
{
fastDetector_
->
setThreshold
(
threshold
);
fastDetector_
->
setNonmaxSuppression
(
nonmaxSuppression
);
}
/** @brief Releases inner buffer memory.
*/
void
release
();
static
Ptr
<
ORB
>
create
(
int
nfeatures
=
500
,
float
scaleFactor
=
1.2
f
,
int
nlevels
=
8
,
int
edgeThreshold
=
31
,
int
firstLevel
=
0
,
int
WTA_K
=
2
,
int
scoreType
=
ORB
::
HARRIS_SCORE
,
int
patchSize
=
31
,
int
fastThreshold
=
20
,
bool
blurForDescriptor
=
false
);
//! if true, image will be blurred before descriptors calculation
bool
blurForDescriptor
;
private
:
enum
{
kBytes
=
32
};
void
buildScalePyramids
(
const
GpuMat
&
image
,
const
GpuMat
&
mask
);
void
computeKeyPointsPyramid
();
void
computeDescriptors
(
GpuMat
&
descriptors
);
void
mergeKeyPoints
(
GpuMat
&
keypoints
);
int
nFeatures_
;
float
scaleFactor_
;
int
nLevels_
;
int
edgeThreshold_
;
int
firstLevel_
;
int
WTA_K_
;
int
scoreType_
;
int
patchSize_
;
//! The number of desired features per scale
std
::
vector
<
size_t
>
n_features_per_level_
;
//! Points to compute BRIEF descriptors from
GpuMat
pattern_
;
std
::
vector
<
GpuMat
>
imagePyr_
;
std
::
vector
<
GpuMat
>
maskPyr_
;
GpuMat
buf_
;
std
::
vector
<
GpuMat
>
keyPointsPyr_
;
std
::
vector
<
int
>
keyPointsCount_
;
Ptr
<
cv
::
cuda
::
FastFeatureDetector
>
fastDetector_
;
Ptr
<
cuda
::
Filter
>
blurFilter
;
GpuMat
d_keypoints_
;
virtual
void
setBlurForDescriptor
(
bool
blurForDescriptor
)
=
0
;
virtual
bool
getBlurForDescriptor
()
const
=
0
;
};
//! @}
...
...
modules/cudafeatures2d/perf/perf_features2d.cpp
View file @
f960a570
...
...
@@ -109,15 +109,15 @@ PERF_TEST_P(Image_NFeatures, ORB,
if
(
PERF_RUN_CUDA
())
{
cv
::
cuda
::
ORB_CUDA
d_orb
(
nFeatures
);
cv
::
Ptr
<
cv
::
cuda
::
ORB
>
d_orb
=
cv
::
cuda
::
ORB
::
create
(
nFeatures
);
const
cv
::
cuda
::
GpuMat
d_img
(
img
);
cv
::
cuda
::
GpuMat
d_keypoints
,
d_descriptors
;
TEST_CYCLE
()
d_orb
(
d_img
,
cv
::
cuda
::
GpuMat
(),
d_keypoints
,
d_descriptors
);
TEST_CYCLE
()
d_orb
->
detectAndComputeAsync
(
d_img
,
cv
::
noArray
(),
d_keypoints
,
d_descriptors
);
std
::
vector
<
cv
::
KeyPoint
>
gpu_keypoints
;
d_orb
.
downloadKeyPoints
(
d_keypoints
,
gpu_keypoints
);
d_orb
->
convert
(
d_keypoints
,
gpu_keypoints
);
cv
::
Mat
gpu_descriptors
(
d_descriptors
);
...
...
modules/cudafeatures2d/src/orb.cpp
View file @
f960a570
...
...
@@ -47,18 +47,7 @@ using namespace cv::cuda;
#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)
cv
::
cuda
::
ORB_CUDA
::
ORB_CUDA
(
int
,
float
,
int
,
int
,
int
,
int
,
int
,
int
)
:
fastDetector_
(
20
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
operator
()(
const
GpuMat
&
,
const
GpuMat
&
,
std
::
vector
<
KeyPoint
>&
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
operator
()(
const
GpuMat
&
,
const
GpuMat
&
,
GpuMat
&
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
operator
()(
const
GpuMat
&
,
const
GpuMat
&
,
std
::
vector
<
KeyPoint
>&
,
GpuMat
&
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
operator
()(
const
GpuMat
&
,
const
GpuMat
&
,
GpuMat
&
,
GpuMat
&
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
downloadKeyPoints
(
const
GpuMat
&
,
std
::
vector
<
KeyPoint
>&
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
convertKeyPoints
(
const
Mat
&
,
std
::
vector
<
KeyPoint
>&
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
release
()
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
buildScalePyramids
(
const
GpuMat
&
,
const
GpuMat
&
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
computeKeyPointsPyramid
()
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
computeDescriptors
(
GpuMat
&
)
{
throw_no_cuda
();
}
void
cv
::
cuda
::
ORB_CUDA
::
mergeKeyPoints
(
GpuMat
&
)
{
throw_no_cuda
();
}
Ptr
<
cv
::
cuda
::
ORB
>
cv
::
cuda
::
ORB
::
create
(
int
,
float
,
int
,
int
,
int
,
int
,
int
,
int
,
int
,
bool
)
{
throw_no_cuda
();
return
Ptr
<
cv
::
cuda
::
ORB
>
();
}
#else
/* !defined (HAVE_CUDA) */
...
...
@@ -346,7 +335,100 @@ namespace
-
1
,
-
6
,
0
,
-
11
/*mean (0.127148), correlation (0.547401)*/
};
void
initializeOrbPattern
(
const
Point
*
pattern0
,
Mat
&
pattern
,
int
ntuples
,
int
tupleSize
,
int
poolSize
)
class
ORB_Impl
:
public
cv
::
cuda
::
ORB
{
public
:
ORB_Impl
(
int
nfeatures
,
float
scaleFactor
,
int
nlevels
,
int
edgeThreshold
,
int
firstLevel
,
int
WTA_K
,
int
scoreType
,
int
patchSize
,
int
fastThreshold
,
bool
blurForDescriptor
);
virtual
void
detectAndCompute
(
InputArray
_image
,
InputArray
_mask
,
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
bool
useProvidedKeypoints
);
virtual
void
detectAndComputeAsync
(
InputArray
_image
,
InputArray
_mask
,
OutputArray
_keypoints
,
OutputArray
_descriptors
,
bool
useProvidedKeypoints
,
Stream
&
stream
);
virtual
void
convert
(
InputArray
_gpu_keypoints
,
std
::
vector
<
KeyPoint
>&
keypoints
);
virtual
int
descriptorSize
()
const
{
return
kBytes
;
}
virtual
int
descriptorType
()
const
{
return
CV_8U
;
}
virtual
int
defaultNorm
()
const
{
return
NORM_HAMMING
;
}
virtual
void
setMaxFeatures
(
int
maxFeatures
)
{
nFeatures_
=
maxFeatures
;
}
virtual
int
getMaxFeatures
()
const
{
return
nFeatures_
;
}
virtual
void
setScaleFactor
(
double
scaleFactor
)
{
scaleFactor_
=
scaleFactor
;
}
virtual
double
getScaleFactor
()
const
{
return
scaleFactor_
;
}
virtual
void
setNLevels
(
int
nlevels
)
{
nLevels_
=
nlevels
;
}
virtual
int
getNLevels
()
const
{
return
nLevels_
;
}
virtual
void
setEdgeThreshold
(
int
edgeThreshold
)
{
edgeThreshold_
=
edgeThreshold
;
}
virtual
int
getEdgeThreshold
()
const
{
return
edgeThreshold_
;
}
virtual
void
setFirstLevel
(
int
firstLevel
)
{
firstLevel_
=
firstLevel
;
}
virtual
int
getFirstLevel
()
const
{
return
firstLevel_
;
}
virtual
void
setWTA_K
(
int
wta_k
)
{
WTA_K_
=
wta_k
;
}
virtual
int
getWTA_K
()
const
{
return
WTA_K_
;
}
virtual
void
setScoreType
(
int
scoreType
)
{
scoreType_
=
scoreType
;
}
virtual
int
getScoreType
()
const
{
return
scoreType_
;
}
virtual
void
setPatchSize
(
int
patchSize
)
{
patchSize_
=
patchSize
;
}
virtual
int
getPatchSize
()
const
{
return
patchSize_
;
}
virtual
void
setFastThreshold
(
int
fastThreshold
)
{
fastThreshold_
=
fastThreshold
;
}
virtual
int
getFastThreshold
()
const
{
return
fastThreshold_
;
}
virtual
void
setBlurForDescriptor
(
bool
blurForDescriptor
)
{
blurForDescriptor_
=
blurForDescriptor
;
}
virtual
bool
getBlurForDescriptor
()
const
{
return
blurForDescriptor_
;
}
private
:
int
nFeatures_
;
float
scaleFactor_
;
int
nLevels_
;
int
edgeThreshold_
;
int
firstLevel_
;
int
WTA_K_
;
int
scoreType_
;
int
patchSize_
;
int
fastThreshold_
;
bool
blurForDescriptor_
;
private
:
void
buildScalePyramids
(
InputArray
_image
,
InputArray
_mask
);
void
computeKeyPointsPyramid
();
void
computeDescriptors
(
OutputArray
_descriptors
);
void
mergeKeyPoints
(
OutputArray
_keypoints
);
private
:
Ptr
<
cv
::
cuda
::
FastFeatureDetector
>
fastDetector_
;
//! The number of desired features per scale
std
::
vector
<
size_t
>
n_features_per_level_
;
//! Points to compute BRIEF descriptors from
GpuMat
pattern_
;
std
::
vector
<
GpuMat
>
imagePyr_
;
std
::
vector
<
GpuMat
>
maskPyr_
;
GpuMat
buf_
;
std
::
vector
<
GpuMat
>
keyPointsPyr_
;
std
::
vector
<
int
>
keyPointsCount_
;
Ptr
<
cuda
::
Filter
>
blurFilter_
;
GpuMat
d_keypoints_
;
};
static
void
initializeOrbPattern
(
const
Point
*
pattern0
,
Mat
&
pattern
,
int
ntuples
,
int
tupleSize
,
int
poolSize
)
{
RNG
rng
(
0x12345678
);
...
...
@@ -381,7 +463,7 @@ namespace
}
}
void
makeRandomPattern
(
int
patchSize
,
Point
*
pattern
,
int
npoints
)
static
void
makeRandomPattern
(
int
patchSize
,
Point
*
pattern
,
int
npoints
)
{
// we always start with a fixed seed,
// to make patterns the same on each run
...
...
@@ -393,14 +475,32 @@ namespace
pattern
[
i
].
y
=
rng
.
uniform
(
-
patchSize
/
2
,
patchSize
/
2
+
1
);
}
}
}
cv
::
cuda
::
ORB_CUDA
::
ORB_CUDA
(
int
nFeatures
,
float
scaleFactor
,
int
nLevels
,
int
edgeThreshold
,
int
firstLevel
,
int
WTA_K
,
int
scoreType
,
int
patchSize
)
:
nFeatures_
(
nFeatures
),
scaleFactor_
(
scaleFactor
),
nLevels_
(
nLevels
),
edgeThreshold_
(
edgeThreshold
),
firstLevel_
(
firstLevel
),
WTA_K_
(
WTA_K
),
scoreType_
(
scoreType
),
patchSize_
(
patchSize
),
fastDetector_
(
cuda
::
FastFeatureDetector
::
create
(
DEFAULT_FAST_THRESHOLD
))
{
CV_Assert
(
patchSize_
>=
2
);
ORB_Impl
::
ORB_Impl
(
int
nFeatures
,
float
scaleFactor
,
int
nLevels
,
int
edgeThreshold
,
int
firstLevel
,
int
WTA_K
,
int
scoreType
,
int
patchSize
,
int
fastThreshold
,
bool
blurForDescriptor
)
:
nFeatures_
(
nFeatures
),
scaleFactor_
(
scaleFactor
),
nLevels_
(
nLevels
),
edgeThreshold_
(
edgeThreshold
),
firstLevel_
(
firstLevel
),
WTA_K_
(
WTA_K
),
scoreType_
(
scoreType
),
patchSize_
(
patchSize
),
fastThreshold_
(
fastThreshold
),
blurForDescriptor_
(
blurForDescriptor
)
{
CV_Assert
(
patchSize_
>=
2
);
CV_Assert
(
WTA_K_
==
2
||
WTA_K_
==
3
||
WTA_K_
==
4
);
fastDetector_
=
cuda
::
FastFeatureDetector
::
create
(
fastThreshold_
);
// fill the extractors and descriptors for the corresponding scales
float
factor
=
1.0
f
/
scaleFactor_
;
...
...
@@ -420,7 +520,9 @@ cv::cuda::ORB_CUDA::ORB_CUDA(int nFeatures, float scaleFactor, int nLevels, int
int
half_patch_size
=
patchSize_
/
2
;
std
::
vector
<
int
>
u_max
(
half_patch_size
+
2
);
for
(
int
v
=
0
;
v
<=
half_patch_size
*
std
::
sqrt
(
2.
f
)
/
2
+
1
;
++
v
)
{
u_max
[
v
]
=
cvRound
(
std
::
sqrt
(
static_cast
<
float
>
(
half_patch_size
*
half_patch_size
-
v
*
v
)));
}
// Make sure we are symmetric
for
(
int
v
=
half_patch_size
,
v_0
=
0
;
v
>=
half_patch_size
*
std
::
sqrt
(
2.
f
)
/
2
;
--
v
)
...
...
@@ -430,7 +532,7 @@ cv::cuda::ORB_CUDA::ORB_CUDA(int nFeatures, float scaleFactor, int nLevels, int
u_max
[
v
]
=
v_0
;
++
v_0
;
}
CV_Assert
(
u_max
.
size
()
<
32
);
CV_Assert
(
u_max
.
size
()
<
32
);
cv
::
cuda
::
device
::
orb
::
loadUMax
(
&
u_max
[
0
],
static_cast
<
int
>
(
u_max
.
size
()));
// Calc pattern
...
...
@@ -443,10 +545,7 @@ cv::cuda::ORB_CUDA::ORB_CUDA(int nFeatures, float scaleFactor, int nLevels, int
makeRandomPattern
(
patchSize_
,
pattern_buf
,
npoints
);
}
CV_Assert
(
WTA_K_
==
2
||
WTA_K_
==
3
||
WTA_K_
==
4
);
Mat
h_pattern
;
if
(
WTA_K_
==
2
)
{
h_pattern
.
create
(
2
,
npoints
,
CV_32SC1
);
...
...
@@ -468,23 +567,42 @@ cv::cuda::ORB_CUDA::ORB_CUDA(int nFeatures, float scaleFactor, int nLevels, int
pattern_
.
upload
(
h_pattern
);
blurFilter
=
cuda
::
createGaussianFilter
(
CV_8UC1
,
-
1
,
Size
(
7
,
7
),
2
,
2
,
BORDER_REFLECT_101
);
blurFilter_
=
cuda
::
createGaussianFilter
(
CV_8UC1
,
-
1
,
Size
(
7
,
7
),
2
,
2
,
BORDER_REFLECT_101
);
}
blurForDescriptor
=
false
;
}
void
ORB_Impl
::
detectAndCompute
(
InputArray
_image
,
InputArray
_mask
,
std
::
vector
<
KeyPoint
>&
keypoints
,
OutputArray
_descriptors
,
bool
useProvidedKeypoints
)
{
CV_Assert
(
useProvidedKeypoints
==
false
);
namespace
{
inline
float
getScale
(
float
scaleFactor
,
int
firstLevel
,
int
level
)
detectAndComputeAsync
(
_image
,
_mask
,
d_keypoints_
,
_descriptors
,
false
,
Stream
::
Null
());
convert
(
d_keypoints_
,
keypoints
);
}
void
ORB_Impl
::
detectAndComputeAsync
(
InputArray
_image
,
InputArray
_mask
,
OutputArray
_keypoints
,
OutputArray
_descriptors
,
bool
useProvidedKeypoints
,
Stream
&
stream
)
{
CV_Assert
(
useProvidedKeypoints
==
false
);
buildScalePyramids
(
_image
,
_mask
);
computeKeyPointsPyramid
();
if
(
_descriptors
.
needed
())
{
computeDescriptors
(
_descriptors
);
}
mergeKeyPoints
(
_keypoints
);
}
static
float
getScale
(
float
scaleFactor
,
int
firstLevel
,
int
level
)
{
return
pow
(
scaleFactor
,
level
-
firstLevel
);
}
}
void
cv
::
cuda
::
ORB_CUDA
::
buildScalePyramids
(
const
GpuMat
&
image
,
const
GpuMat
&
mask
)
{
CV_Assert
(
image
.
type
()
==
CV_8UC1
);
CV_Assert
(
mask
.
empty
()
||
(
mask
.
type
()
==
CV_8UC1
&&
mask
.
size
()
==
image
.
size
()));
void
ORB_Impl
::
buildScalePyramids
(
InputArray
_image
,
InputArray
_mask
)
{
const
GpuMat
image
=
_image
.
getGpuMat
();
const
GpuMat
mask
=
_mask
.
getGpuMat
();
CV_Assert
(
image
.
type
()
==
CV_8UC1
);
CV_Assert
(
mask
.
empty
()
||
(
mask
.
type
()
==
CV_8UC1
&&
mask
.
size
()
==
image
.
size
())
);
imagePyr_
.
resize
(
nLevels_
);
maskPyr_
.
resize
(
nLevels_
);
...
...
@@ -536,12 +654,10 @@ void cv::cuda::ORB_CUDA::buildScalePyramids(const GpuMat& image, const GpuMat& m
cuda
::
bitwise_and
(
maskPyr_
[
level
],
buf_
,
maskPyr_
[
level
]);
}
}
}
namespace
{
//takes keypoints and culls them by the response
void
cull
(
GpuMat
&
keypoints
,
int
&
count
,
int
n_points
)
// takes keypoints and culls them by the response
static
void
cull
(
GpuMat
&
keypoints
,
int
&
count
,
int
n_points
)
{
using
namespace
cv
::
cuda
::
device
::
orb
;
...
...
@@ -557,10 +673,9 @@ namespace
count
=
cull_gpu
(
keypoints
.
ptr
<
int
>
(
cuda
::
FastFeatureDetector
::
LOCATION_ROW
),
keypoints
.
ptr
<
float
>
(
cuda
::
FastFeatureDetector
::
RESPONSE_ROW
),
count
,
n_points
);
}
}
}
void
cv
::
cuda
::
ORB_CUDA
::
computeKeyPointsPyramid
()
{
void
ORB_Impl
::
computeKeyPointsPyramid
()
{
using
namespace
cv
::
cuda
::
device
::
orb
;
int
half_patch_size
=
patchSize_
/
2
;
...
...
@@ -568,6 +683,8 @@ void cv::cuda::ORB_CUDA::computeKeyPointsPyramid()
keyPointsPyr_
.
resize
(
nLevels_
);
keyPointsCount_
.
resize
(
nLevels_
);
fastDetector_
->
setThreshold
(
fastThreshold_
);
for
(
int
level
=
0
;
level
<
nLevels_
;
++
level
)
{
fastDetector_
->
setMaxNumPoints
(
0.05
*
imagePyr_
[
level
].
size
().
area
());
...
...
@@ -600,10 +717,10 @@ void cv::cuda::ORB_CUDA::computeKeyPointsPyramid()
// Compute orientation
IC_Angle_gpu
(
imagePyr_
[
level
],
keyPointsPyr_
[
level
].
ptr
<
short2
>
(
0
),
keyPointsPyr_
[
level
].
ptr
<
float
>
(
2
),
keyPointsCount_
[
level
],
half_patch_size
,
0
);
}
}
}
void
cv
::
cuda
::
ORB_CUDA
::
computeDescriptors
(
GpuMat
&
descriptors
)
{
void
ORB_Impl
::
computeDescriptors
(
OutputArray
_
descriptors
)
{
using
namespace
cv
::
cuda
::
device
::
orb
;
int
nAllkeypoints
=
0
;
...
...
@@ -613,11 +730,12 @@ void cv::cuda::ORB_CUDA::computeDescriptors(GpuMat& descriptors)
if
(
nAllkeypoints
==
0
)
{
descriptors
.
release
();
_
descriptors
.
release
();
return
;
}
ensureSizeIsEnough
(
nAllkeypoints
,
descriptorSize
(),
CV_8UC1
,
descriptors
);
ensureSizeIsEnough
(
nAllkeypoints
,
descriptorSize
(),
CV_8UC1
,
_descriptors
);
GpuMat
descriptors
=
_descriptors
.
getGpuMat
();
int
offset
=
0
;
...
...
@@ -628,22 +746,22 @@ void cv::cuda::ORB_CUDA::computeDescriptors(GpuMat& descriptors)
GpuMat
descRange
=
descriptors
.
rowRange
(
offset
,
offset
+
keyPointsCount_
[
level
]);
if
(
blurForDescriptor
)
if
(
blurForDescriptor_
)
{
// preprocess the resized image
ensureSizeIsEnough
(
imagePyr_
[
level
].
size
(),
imagePyr_
[
level
].
type
(),
buf_
);
blurFilter
->
apply
(
imagePyr_
[
level
],
buf_
);
blurFilter_
->
apply
(
imagePyr_
[
level
],
buf_
);
}
computeOrbDescriptor_gpu
(
blurForDescriptor
?
buf_
:
imagePyr_
[
level
],
keyPointsPyr_
[
level
].
ptr
<
short2
>
(
0
),
keyPointsPyr_
[
level
].
ptr
<
float
>
(
2
),
computeOrbDescriptor_gpu
(
blurForDescriptor_
?
buf_
:
imagePyr_
[
level
],
keyPointsPyr_
[
level
].
ptr
<
short2
>
(
0
),
keyPointsPyr_
[
level
].
ptr
<
float
>
(
2
),
keyPointsCount_
[
level
],
pattern_
.
ptr
<
int
>
(
0
),
pattern_
.
ptr
<
int
>
(
1
),
descRange
,
descriptorSize
(),
WTA_K_
,
0
);
offset
+=
keyPointsCount_
[
level
];
}
}
}
void
cv
::
cuda
::
ORB_CUDA
::
mergeKeyPoints
(
GpuMat
&
keypoints
)
{
void
ORB_Impl
::
mergeKeyPoints
(
OutputArray
_
keypoints
)
{
using
namespace
cv
::
cuda
::
device
::
orb
;
int
nAllkeypoints
=
0
;
...
...
@@ -653,11 +771,12 @@ void cv::cuda::ORB_CUDA::mergeKeyPoints(GpuMat& keypoints)
if
(
nAllkeypoints
==
0
)
{
keypoints
.
release
();
_
keypoints
.
release
();
return
;
}
ensureSizeIsEnough
(
ROWS_COUNT
,
nAllkeypoints
,
CV_32FC1
,
keypoints
);
ensureSizeIsEnough
(
ROWS_COUNT
,
nAllkeypoints
,
CV_32FC1
,
_keypoints
);
GpuMat
&
keypoints
=
_keypoints
.
getGpuMatRef
();
int
offset
=
0
;
...
...
@@ -682,41 +801,41 @@ void cv::cuda::ORB_CUDA::mergeKeyPoints(GpuMat& keypoints)
offset
+=
keyPointsCount_
[
level
];
}
}
}
void
cv
::
cuda
::
ORB_CUDA
::
downloadKeyPoints
(
const
GpuMat
&
d
_keypoints
,
std
::
vector
<
KeyPoint
>&
keypoints
)
{
if
(
d
_keypoints
.
empty
())
void
ORB_Impl
::
convert
(
InputArray
_gpu
_keypoints
,
std
::
vector
<
KeyPoint
>&
keypoints
)
{
if
(
_gpu
_keypoints
.
empty
())
{
keypoints
.
clear
();
return
;
}
Mat
h_keypoints
(
d_keypoints
);
convertKeyPoints
(
h_keypoints
,
keypoints
);
}
void
cv
::
cuda
::
ORB_CUDA
::
convertKeyPoints
(
const
Mat
&
d_keypoints
,
std
::
vector
<
KeyPoint
>&
keypoints
)
{
if
(
d_keypoints
.
empty
())
Mat
h_keypoints
;
if
(
_gpu_keypoints
.
kind
()
==
_InputArray
::
CUDA_GPU_MAT
)
{
keypoints
.
clear
();
return
;
_gpu_keypoints
.
getGpuMat
().
download
(
h_keypoints
);
}
else
{
h_keypoints
=
_gpu_keypoints
.
getMat
();
}
CV_Assert
(
h_keypoints
.
rows
==
ROWS_COUNT
);
CV_Assert
(
h_keypoints
.
type
()
==
CV_32FC1
);
CV_Assert
(
d_keypoints
.
type
()
==
CV_32FC1
&&
d_keypoints
.
rows
==
ROWS_COUNT
)
;
const
int
npoints
=
h_keypoints
.
cols
;
const
float
*
x_ptr
=
d_keypoints
.
ptr
<
float
>
(
X_ROW
);
const
float
*
y_ptr
=
d_keypoints
.
ptr
<
float
>
(
Y_ROW
);
const
float
*
response_ptr
=
d_keypoints
.
ptr
<
float
>
(
RESPONSE_ROW
);
const
float
*
angle_ptr
=
d_keypoints
.
ptr
<
float
>
(
ANGLE_ROW
);
const
float
*
octave_ptr
=
d_keypoints
.
ptr
<
float
>
(
OCTAVE_ROW
);
const
float
*
size_ptr
=
d_keypoints
.
ptr
<
float
>
(
SIZE_ROW
);
keypoints
.
resize
(
npoints
);
keypoints
.
resize
(
d_keypoints
.
cols
);
const
float
*
x_ptr
=
h_keypoints
.
ptr
<
float
>
(
X_ROW
);
const
float
*
y_ptr
=
h_keypoints
.
ptr
<
float
>
(
Y_ROW
);
const
float
*
response_ptr
=
h_keypoints
.
ptr
<
float
>
(
RESPONSE_ROW
);
const
float
*
angle_ptr
=
h_keypoints
.
ptr
<
float
>
(
ANGLE_ROW
);
const
float
*
octave_ptr
=
h_keypoints
.
ptr
<
float
>
(
OCTAVE_ROW
);
const
float
*
size_ptr
=
h_keypoints
.
ptr
<
float
>
(
SIZE_ROW
);
for
(
int
i
=
0
;
i
<
d_keypoints
.
col
s
;
++
i
)
for
(
int
i
=
0
;
i
<
npoint
s
;
++
i
)
{
KeyPoint
kp
;
...
...
@@ -729,45 +848,21 @@ void cv::cuda::ORB_CUDA::convertKeyPoints(const Mat &d_keypoints, std::vector<Ke
keypoints
[
i
]
=
kp
;
}
}
}
void
cv
::
cuda
::
ORB_CUDA
::
operator
()(
const
GpuMat
&
image
,
const
GpuMat
&
mask
,
GpuMat
&
keypoints
)
{
buildScalePyramids
(
image
,
mask
);
computeKeyPointsPyramid
();
mergeKeyPoints
(
keypoints
);
}
void
cv
::
cuda
::
ORB_CUDA
::
operator
()(
const
GpuMat
&
image
,
const
GpuMat
&
mask
,
GpuMat
&
keypoints
,
GpuMat
&
descriptors
)
{
buildScalePyramids
(
image
,
mask
);
computeKeyPointsPyramid
();
computeDescriptors
(
descriptors
);
mergeKeyPoints
(
keypoints
);
}
void
cv
::
cuda
::
ORB_CUDA
::
operator
()(
const
GpuMat
&
image
,
const
GpuMat
&
mask
,
std
::
vector
<
KeyPoint
>&
keypoints
)
{
(
*
this
)(
image
,
mask
,
d_keypoints_
);
downloadKeyPoints
(
d_keypoints_
,
keypoints
);
}
void
cv
::
cuda
::
ORB_CUDA
::
operator
()(
const
GpuMat
&
image
,
const
GpuMat
&
mask
,
std
::
vector
<
KeyPoint
>&
keypoints
,
GpuMat
&
descriptors
)
{
(
*
this
)(
image
,
mask
,
d_keypoints_
,
descriptors
);
downloadKeyPoints
(
d_keypoints_
,
keypoints
);
}
void
cv
::
cuda
::
ORB_CUDA
::
release
()
Ptr
<
cv
::
cuda
::
ORB
>
cv
::
cuda
::
ORB
::
create
(
int
nfeatures
,
float
scaleFactor
,
int
nlevels
,
int
edgeThreshold
,
int
firstLevel
,
int
WTA_K
,
int
scoreType
,
int
patchSize
,
int
fastThreshold
,
bool
blurForDescriptor
)
{
imagePyr_
.
clear
();
maskPyr_
.
clear
();
buf_
.
release
();
keyPointsPyr_
.
clear
();
d_keypoints_
.
release
();
return
makePtr
<
ORB_Impl
>
(
nfeatures
,
scaleFactor
,
nlevels
,
edgeThreshold
,
firstLevel
,
WTA_K
,
scoreType
,
patchSize
,
fastThreshold
,
blurForDescriptor
);
}
#endif
/* !defined (HAVE_CUDA) */
modules/cudafeatures2d/test/test_features2d.cpp
View file @
f960a570
...
...
@@ -122,7 +122,7 @@ namespace
IMPLEMENT_PARAM_CLASS
(
ORB_BlurForDescriptor
,
bool
)
}
CV_ENUM
(
ORB_ScoreType
,
ORB
::
HARRIS_SCORE
,
ORB
::
FAST_SCORE
)
CV_ENUM
(
ORB_ScoreType
,
cv
::
ORB
::
HARRIS_SCORE
,
cv
::
ORB
::
FAST_SCORE
)
PARAM_TEST_CASE
(
ORB
,
cv
::
cuda
::
DeviceInfo
,
ORB_FeaturesCount
,
ORB_ScaleFactor
,
ORB_LevelsCount
,
ORB_EdgeThreshold
,
ORB_firstLevel
,
ORB_WTA_K
,
ORB_ScoreType
,
ORB_PatchSize
,
ORB_BlurForDescriptor
)
{
...
...
@@ -162,8 +162,9 @@ CUDA_TEST_P(ORB, Accuracy)
cv
::
Mat
mask
(
image
.
size
(),
CV_8UC1
,
cv
::
Scalar
::
all
(
1
));
mask
(
cv
::
Range
(
0
,
image
.
rows
/
2
),
cv
::
Range
(
0
,
image
.
cols
/
2
)).
setTo
(
cv
::
Scalar
::
all
(
0
));
cv
::
cuda
::
ORB_CUDA
orb
(
nFeatures
,
scaleFactor
,
nLevels
,
edgeThreshold
,
firstLevel
,
WTA_K
,
scoreType
,
patchSize
);
orb
.
blurForDescriptor
=
blurForDescriptor
;
cv
::
Ptr
<
cv
::
cuda
::
ORB
>
orb
=
cv
::
cuda
::
ORB
::
create
(
nFeatures
,
scaleFactor
,
nLevels
,
edgeThreshold
,
firstLevel
,
WTA_K
,
scoreType
,
patchSize
,
20
,
blurForDescriptor
);
if
(
!
supportFeature
(
devInfo
,
cv
::
cuda
::
GLOBAL_ATOMICS
))
{
...
...
@@ -171,7 +172,7 @@ CUDA_TEST_P(ORB, Accuracy)
{
std
::
vector
<
cv
::
KeyPoint
>
keypoints
;
cv
::
cuda
::
GpuMat
descriptors
;
orb
(
loadMat
(
image
),
loadMat
(
mask
),
keypoints
,
descriptors
);
orb
->
detectAndComputeAsync
(
loadMat
(
image
),
loadMat
(
mask
),
keypoints
,
descriptors
);
}
catch
(
const
cv
::
Exception
&
e
)
{
...
...
@@ -182,7 +183,7 @@ CUDA_TEST_P(ORB, Accuracy)
{
std
::
vector
<
cv
::
KeyPoint
>
keypoints
;
cv
::
cuda
::
GpuMat
descriptors
;
orb
(
loadMat
(
image
),
loadMat
(
mask
),
keypoints
,
descriptors
);
orb
->
detectAndCompute
(
loadMat
(
image
),
loadMat
(
mask
),
keypoints
,
descriptors
);
cv
::
Ptr
<
cv
::
ORB
>
orb_gold
=
cv
::
ORB
::
create
(
nFeatures
,
scaleFactor
,
nLevels
,
edgeThreshold
,
firstLevel
,
WTA_K
,
scoreType
,
patchSize
);
...
...
samples/gpu/performance/tests.cpp
View file @
f960a570
...
...
@@ -350,15 +350,15 @@ TEST(ORB)
orb
->
detectAndCompute
(
src
,
Mat
(),
keypoints
,
descriptors
);
CPU_OFF
;
cuda
::
ORB_CUDA
d_orb
;
Ptr
<
cuda
::
ORB
>
d_orb
=
cuda
::
ORB
::
create
()
;
cuda
::
GpuMat
d_src
(
src
);
cuda
::
GpuMat
d_keypoints
;
cuda
::
GpuMat
d_descriptors
;
d_orb
(
d_src
,
cuda
::
GpuMat
(),
d_keypoints
,
d_descriptors
);
d_orb
->
detectAndComputeAsync
(
d_src
,
cuda
::
GpuMat
(),
d_keypoints
,
d_descriptors
);
CUDA_ON
;
d_orb
(
d_src
,
cuda
::
GpuMat
(),
d_keypoints
,
d_descriptors
);
d_orb
->
detectAndComputeAsync
(
d_src
,
cuda
::
GpuMat
(),
d_keypoints
,
d_descriptors
);
CUDA_OFF
;
}
...
...
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