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
58f69197
Commit
58f69197
authored
Mar 10, 2011
by
Vladislav Vinogradov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
made GPU version of SURF more consistent with CPU one
parent
c067c633
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
91 additions
and
152 deletions
+91
-152
gpu.hpp
modules/gpu/include/opencv2/gpu/gpu.hpp
+20
-48
internal_shared.hpp
modules/gpu/src/cuda/internal_shared.hpp
+6
-6
surf.cu
modules/gpu/src/cuda/surf.cu
+0
-0
surf.cpp
modules/gpu/src/surf.cpp
+0
-0
test_features2d.cpp
modules/gpu/test/test_features2d.cpp
+56
-90
tests.cpp
samples/gpu/performance/tests.cpp
+5
-4
surf_keypoint_matcher.cpp
samples/gpu/surf_keypoint_matcher.cpp
+4
-4
No files found.
modules/gpu/include/opencv2/gpu/gpu.hpp
View file @
58f69197
...
...
@@ -1537,83 +1537,55 @@ namespace cv
};
////////////////////////////////// SURF //////////////////////////////////////////
struct
CV_EXPORTS
SURFParams_GPU
{
SURFParams_GPU
()
:
threshold
(
0.1
f
),
nOctaves
(
4
),
nIntervals
(
4
),
initialScale
(
2.
f
),
l1
(
3.
f
/
1.5
f
),
l2
(
5.
f
/
1.5
f
),
l3
(
3.
f
/
1.5
f
),
l4
(
1.
f
/
1.5
f
),
edgeScale
(
0.81
f
),
initialStep
(
1
),
extended
(
true
),
featuresRatio
(
0.01
f
)
{}
//! The interest operator threshold
float
threshold
;
//! The number of octaves to process
int
nOctaves
;
//! The number of intervals in each octave
int
nIntervals
;
//! The scale associated with the first interval of the first octave
float
initialScale
;
//! mask parameter l_1
float
l1
;
//! mask parameter l_2
float
l2
;
//! mask parameter l_3
float
l3
;
//! mask parameter l_4
float
l4
;
//! The amount to scale the edge rejection mask
float
edgeScale
;
//! The initial sampling step in pixels.
int
initialStep
;
//! True, if generate 128-len descriptors, false - 64-len descriptors
bool
extended
;
//! max features = featuresRatio * img.size().srea()
float
featuresRatio
;
};
class
CV_EXPORTS
SURF_GPU
:
public
SURFParams_GPU
class
CV_EXPORTS
SURF_GPU
:
public
CvSURFParams
{
public
:
//! the default constructor
SURF_GPU
();
//! the full constructor taking all the necessary parameters
explicit
SURF_GPU
(
double
_hessianThreshold
,
int
_nOctaves
=
4
,
int
_nOctaveLayers
=
2
,
bool
_extended
=
false
,
float
_keypointsRatio
=
0.01
f
);
//! returns the descriptor size in float's (64 or 128)
int
descriptorSize
()
const
;
//! upload host keypoints to device memory
static
void
uploadKeypoints
(
const
vector
<
KeyPoint
>&
keypoints
,
GpuMat
&
keypointsGPU
);
void
uploadKeypoints
(
const
vector
<
KeyPoint
>&
keypoints
,
GpuMat
&
keypointsGPU
);
//! download keypoints from device to host memory
static
void
downloadKeypoints
(
const
GpuMat
&
keypointsGPU
,
vector
<
KeyPoint
>&
keypoints
);
void
downloadKeypoints
(
const
GpuMat
&
keypointsGPU
,
vector
<
KeyPoint
>&
keypoints
);
//! download descriptors from device to host memory
static
void
downloadDescriptors
(
const
GpuMat
&
descriptorsGPU
,
vector
<
float
>&
descriptors
);
void
downloadDescriptors
(
const
GpuMat
&
descriptorsGPU
,
vector
<
float
>&
descriptors
);
//! finds the keypoints using fast hessian detector used in SURF
//! supports CV_8UC1 images
//! keypoints will have 1 row and type CV_32FC(6)
//! keypoints.at<float[6]>(1, i) contains i'th keypoint
//! format: (x, y,
size, response, angle, octave
)
//! format: (x, y,
laplacian, size, dir, hessian
)
void
operator
()(
const
GpuMat
&
img
,
const
GpuMat
&
mask
,
GpuMat
&
keypoints
);
//! finds the keypoints and computes their descriptors.
//! Optionally it can compute descriptors for the user-provided keypoints and recompute keypoints direction
void
operator
()(
const
GpuMat
&
img
,
const
GpuMat
&
mask
,
GpuMat
&
keypoints
,
GpuMat
&
descriptors
,
bool
useProvidedKeypoints
=
false
,
bool
calcOrientation
=
true
);
bool
useProvidedKeypoints
=
false
);
void
operator
()(
const
GpuMat
&
img
,
const
GpuMat
&
mask
,
std
::
vector
<
KeyPoint
>&
keypoints
);
void
operator
()(
const
GpuMat
&
img
,
const
GpuMat
&
mask
,
std
::
vector
<
KeyPoint
>&
keypoints
,
GpuMat
&
descriptors
,
bool
useProvidedKeypoints
=
false
,
bool
calcOrientation
=
true
);
bool
useProvidedKeypoints
=
false
);
void
operator
()(
const
GpuMat
&
img
,
const
GpuMat
&
mask
,
std
::
vector
<
KeyPoint
>&
keypoints
,
std
::
vector
<
float
>&
descriptors
,
bool
useProvidedKeypoints
=
false
,
bool
calcOrientation
=
true
);
bool
useProvidedKeypoints
=
false
);
//! max keypoints = keypointsRatio * img.size().area()
float
keypointsRatio
;
GpuMat
sum
;
GpuMat
sumf
;
GpuMat
sum
,
mask1
,
maskSum
,
intBuffer
;
GpuMat
mask1
;
GpuMat
maskSum
;
GpuMat
det
,
trace
;
GpuMat
hessianBuffer
;
GpuMat
maxPosBuffer
;
GpuMat
featuresBuffer
;
GpuMat
keypointsBuffer
;
};
}
...
...
modules/gpu/src/cuda/internal_shared.hpp
View file @
58f69197
...
...
@@ -111,20 +111,20 @@ namespace cv
{
float
x
;
float
y
;
float
laplacian
;
float
size
;
float
response
;
float
angle
;
float
octave
;
float
dir
;
float
hessian
;
};
enum
KeypointLayout
{
SF_X
,
SF_Y
,
SF_LAPLACIAN
,
SF_SIZE
,
SF_RESPONSE
,
SF_ANGLE
,
SF_OCTAVE
,
SF_DIR
,
SF_HESSIAN
,
SF_FEATURE_STRIDE
};
}
...
...
modules/gpu/src/cuda/surf.cu
View file @
58f69197
This diff is collapsed.
Click to expand it.
modules/gpu/src/surf.cpp
View file @
58f69197
This diff is collapsed.
Click to expand it.
modules/gpu/test/test_features2d.cpp
View file @
58f69197
...
...
@@ -48,7 +48,6 @@ using namespace std;
const
string
FEATURES2D_DIR
=
"features2d"
;
const
string
IMAGE_FILENAME
=
"aloe.png"
;
const
string
VALID_FILE_NAME
=
"surf.xml.gz"
;
class
CV_GPU_SURFTest
:
public
cvtest
::
BaseTest
{
...
...
@@ -59,17 +58,20 @@ public:
protected
:
bool
isSimilarKeypoints
(
const
KeyPoint
&
p1
,
const
KeyPoint
&
p2
);
int
getValidCount
(
const
vector
<
KeyPoint
>&
keypoints1
,
const
vector
<
KeyPoint
>&
keypoints2
,
const
vector
<
DMatch
>&
matches
);
void
compareKeypointSets
(
const
vector
<
KeyPoint
>&
validKeypoints
,
const
vector
<
KeyPoint
>&
calcKeypoints
,
const
Mat
&
validDescriptors
,
const
Mat
&
calcDescriptors
);
void
emptyDataTest
(
SURF_GPU
&
fdetector
);
void
regressionTest
(
SURF_GPU
&
fdetector
);
void
emptyDataTest
();
void
accuracyTest
(
);
virtual
void
run
(
int
);
};
void
CV_GPU_SURFTest
::
emptyDataTest
(
SURF_GPU
&
fdetector
)
void
CV_GPU_SURFTest
::
emptyDataTest
()
{
SURF_GPU
fdetector
;
GpuMat
image
;
vector
<
KeyPoint
>
keypoints
;
vector
<
float
>
descriptors
;
...
...
@@ -114,116 +116,80 @@ bool CV_GPU_SURFTest::isSimilarKeypoints(const KeyPoint& p1, const KeyPoint& p2)
p1
.
class_id
==
p2
.
class_id
);
}
void
CV_GPU_SURFTest
::
compareKeypointSets
(
const
vector
<
KeyPoint
>&
validKeypoints
,
const
vector
<
KeyPoint
>&
calcKeypoints
,
const
Mat
&
validDescriptors
,
const
Mat
&
calcDescriptor
s
)
int
CV_GPU_SURFTest
::
getValidCount
(
const
vector
<
KeyPoint
>&
keypoints1
,
const
vector
<
KeyPoint
>&
keypoints2
,
const
vector
<
DMatch
>&
matche
s
)
{
if
(
validKeypoints
.
size
()
!=
calcKeypoints
.
size
())
int
count
=
0
;
for
(
size_t
i
=
0
;
i
<
matches
.
size
();
++
i
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Keypoints sizes doesn't equal (validCount = %d, calcCount = %d).
\n
"
,
validKeypoints
.
size
(),
calcKeypoints
.
size
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_OUTPUT
);
return
;
const
DMatch
&
m
=
matches
[
i
];
const
KeyPoint
&
kp1
=
keypoints1
[
m
.
queryIdx
];
const
KeyPoint
&
kp2
=
keypoints2
[
m
.
trainIdx
];
if
(
isSimilarKeypoints
(
kp1
,
kp2
))
++
count
;
}
if
(
validDescriptors
.
size
()
!=
calcDescriptors
.
size
())
return
count
;
}
void
CV_GPU_SURFTest
::
compareKeypointSets
(
const
vector
<
KeyPoint
>&
validKeypoints
,
const
vector
<
KeyPoint
>&
calcKeypoints
,
const
Mat
&
validDescriptors
,
const
Mat
&
calcDescriptors
)
{
BruteForceMatcher
<
L2
<
float
>
>
matcher
;
vector
<
DMatch
>
matches
;
matcher
.
match
(
validDescriptors
,
calcDescriptors
,
matches
);
int
validCount
=
getValidCount
(
validKeypoints
,
calcKeypoints
,
matches
);
float
validRatio
=
(
float
)
validCount
/
matches
.
size
();
if
(
validRatio
<
0.5
f
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"
Descriptors sizes doesn't equal.
\n
"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_OUTPUT
);
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"
Bad accuracy - %f.
\n
"
,
validRatio
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
for
(
size_t
v
=
0
;
v
<
validKeypoints
.
size
();
v
++
)
{
int
nearestIdx
=
-
1
;
float
minDist
=
std
::
numeric_limits
<
float
>::
max
();
for
(
size_t
c
=
0
;
c
<
calcKeypoints
.
size
();
c
++
)
{
float
curDist
=
(
float
)
norm
(
calcKeypoints
[
c
].
pt
-
validKeypoints
[
v
].
pt
);
if
(
curDist
<
minDist
)
{
minDist
=
curDist
;
nearestIdx
=
c
;
}
}
assert
(
minDist
>=
0
);
if
(
!
isSimilarKeypoints
(
validKeypoints
[
v
],
calcKeypoints
[
nearestIdx
]))
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Bad keypoints accuracy.
\n
"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
if
(
norm
(
validDescriptors
.
row
(
v
),
calcDescriptors
.
row
(
nearestIdx
),
NORM_L2
)
>
1.5
f
)
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Bad descriptors accuracy.
\n
"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_BAD_ACCURACY
);
return
;
}
}
}
void
CV_GPU_SURFTest
::
regressionTest
(
SURF_GPU
&
fdetector
)
void
CV_GPU_SURFTest
::
accuracyTest
(
)
{
string
imgFilename
=
string
(
ts
->
get_data_path
())
+
FEATURES2D_DIR
+
"/"
+
IMAGE_FILENAME
;
string
resFilename
=
string
(
ts
->
get_data_path
())
+
FEATURES2D_DIR
+
"/"
+
VALID_FILE_NAME
;
// Read the test image.
GpuMat
image
(
imread
(
imgFilename
,
0
)
);
Mat
image
=
imread
(
imgFilename
,
0
);
if
(
image
.
empty
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Image %s can not be read.
\n
"
,
imgFilename
.
c_str
()
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_TEST_DATA
);
return
;
}
FileStorage
fs
(
resFilename
,
FileStorage
::
READ
);
Mat
mask
(
image
.
size
(),
CV_8UC1
,
Scalar
::
all
(
1
));
mask
(
Range
(
0
,
image
.
rows
/
2
),
Range
(
0
,
image
.
cols
/
2
)).
setTo
(
Scalar
::
all
(
0
));
// Compute keypoints.
GpuMat
mask
(
image
.
size
(),
CV_8UC1
,
Scalar
::
all
(
1
));
mask
(
Range
(
0
,
image
.
rows
/
2
),
Range
(
0
,
image
.
cols
/
2
)).
setTo
(
Scalar
::
all
(
0
));
vector
<
KeyPoint
>
calcKeypoints
;
GpuMat
calcDespcriptors
;
fdetector
(
image
,
mask
,
calcKeypoints
,
calcDespcriptors
);
if
(
fs
.
isOpened
())
// Compare computed and valid keypoints.
{
// Read validation keypoints set.
vector
<
KeyPoint
>
validKeypoints
;
Mat
validDespcriptors
;
read
(
fs
[
"keypoints"
],
validKeypoints
);
read
(
fs
[
"descriptors"
],
validDespcriptors
);
if
(
validKeypoints
.
empty
()
||
validDespcriptors
.
empty
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"Validation file can not be read.
\n
"
);
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_TEST_DATA
);
return
;
}
compareKeypointSets
(
validKeypoints
,
calcKeypoints
,
validDespcriptors
,
calcDespcriptors
);
}
else
// Write detector parameters and computed keypoints as validation data.
{
fs
.
open
(
resFilename
,
FileStorage
::
WRITE
);
if
(
!
fs
.
isOpened
())
{
ts
->
printf
(
cvtest
::
TS
::
LOG
,
"File %s can not be opened to write.
\n
"
,
resFilename
.
c_str
());
ts
->
set_failed_test_info
(
cvtest
::
TS
::
FAIL_INVALID_TEST_DATA
);
return
;
}
else
{
write
(
fs
,
"keypoints"
,
calcKeypoints
);
write
(
fs
,
"descriptors"
,
(
Mat
)
calcDespcriptors
);
}
}
GpuMat
calcDescriptors
;
SURF_GPU
fdetector
;
fdetector
.
extended
=
false
;
fdetector
(
GpuMat
(
image
),
GpuMat
(
mask
),
calcKeypoints
,
calcDescriptors
);
// Calc validation keypoints set.
vector
<
KeyPoint
>
validKeypoints
;
vector
<
float
>
validDescriptors
;
SURF
fdetector_gold
;
fdetector_gold
.
extended
=
false
;
fdetector_gold
(
image
,
mask
,
validKeypoints
,
validDescriptors
);
compareKeypointSets
(
validKeypoints
,
calcKeypoints
,
Mat
(
validKeypoints
.
size
(),
fdetector_gold
.
descriptorSize
(),
CV_32F
,
&
validDescriptors
[
0
]),
calcDescriptors
);
}
void
CV_GPU_SURFTest
::
run
(
int
/*start_from*/
)
{
SURF_GPU
fdetector
;
emptyDataTest
(
fdetector
);
regressionTest
(
fdetector
);
emptyDataTest
();
accuracyTest
();
}
TEST
(
SURF
,
empty_data_and_
regression
)
{
CV_GPU_SURFTest
test
;
test
.
safe_run
();
}
TEST
(
SURF
,
empty_data_and_
accuracy
)
{
CV_GPU_SURFTest
test
;
test
.
safe_run
();
}
samples/gpu/performance/tests.cpp
View file @
58f69197
...
...
@@ -264,10 +264,11 @@ TEST(SURF)
SURF
surf
;
vector
<
KeyPoint
>
keypoints1
,
keypoints2
;
vector
<
float
>
descriptors1
,
descriptors2
;
CPU_ON
;
surf
(
src1
,
Mat
(),
keypoints1
);
surf
(
src2
,
Mat
(),
keypoints2
);
surf
(
src1
,
Mat
(),
keypoints1
,
descriptors1
);
surf
(
src2
,
Mat
(),
keypoints2
,
descriptors2
);
CPU_OFF
;
gpu
::
SURF_GPU
d_surf
;
...
...
@@ -275,8 +276,8 @@ TEST(SURF)
gpu
::
GpuMat
d_descriptors1
,
d_descriptors2
;
GPU_ON
;
d_surf
(
d_src1
,
gpu
::
GpuMat
(),
d_keypoints1
);
d_surf
(
d_src2
,
gpu
::
GpuMat
(),
d_keypoints2
);
d_surf
(
d_src1
,
gpu
::
GpuMat
(),
d_keypoints1
,
d_descriptors1
);
d_surf
(
d_src2
,
gpu
::
GpuMat
(),
d_keypoints2
,
d_descriptors2
);
GPU_OFF
;
}
...
...
samples/gpu/surf_keypoint_matcher.cpp
View file @
58f69197
...
...
@@ -51,10 +51,10 @@ int main(int argc, char* argv[])
vector
<
KeyPoint
>
keypoints1
,
keypoints2
;
vector
<
float
>
descriptors1
,
descriptors2
;
vector
<
DMatch
>
matches
;
SURF_GPU
::
downloadKeypoints
(
keypoints1GPU
,
keypoints1
);
SURF_GPU
::
downloadKeypoints
(
keypoints2GPU
,
keypoints2
);
SURF_GPU
::
downloadDescriptors
(
descriptors1GPU
,
descriptors1
);
SURF_GPU
::
downloadDescriptors
(
descriptors2GPU
,
descriptors2
);
surf
.
downloadKeypoints
(
keypoints1GPU
,
keypoints1
);
surf
.
downloadKeypoints
(
keypoints2GPU
,
keypoints2
);
surf
.
downloadDescriptors
(
descriptors1GPU
,
descriptors1
);
surf
.
downloadDescriptors
(
descriptors2GPU
,
descriptors2
);
BruteForceMatcher_GPU
<
L2
<
float
>
>::
matchDownload
(
trainIdx
,
distance
,
matches
);
// drawing the results
...
...
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