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
267eb99a
Commit
267eb99a
authored
Jun 04, 2013
by
Vadim Pisarevsky
Committed by
OpenCV Buildbot
Jun 04, 2013
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #938 from pengx17:2.4_surf_sample
parents
37953b7c
cdb16f11
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
284 additions
and
127 deletions
+284
-127
surf_matcher.cpp
samples/ocl/surf_matcher.cpp
+284
-127
No files found.
samples/ocl/surf_matcher.cpp
View file @
267eb99a
...
...
@@ -46,156 +46,101 @@
#include <iostream>
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/ocl/ocl.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/nonfree/ocl.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
using
namespace
std
;
using
namespace
cv
;
using
namespace
cv
::
ocl
;
//#define USE_CPU_DESCRIPTOR // use cpu descriptor extractor until ocl descriptor extractor is fixed
//#define USE_CPU_BFMATCHER
const
int
LOOP_NUM
=
10
;
const
int
GOOD_PTS_MAX
=
50
;
const
float
GOOD_PORTION
=
0.15
f
;
namespace
{
void
help
();
void
help
()
{
cout
<<
"
\n
This program demonstrates using SURF_OCL features detector and descriptor extractor"
<<
endl
;
cout
<<
"
\n
Usage:
\n\t
surf_matcher --left <image1> --right <image2>"
<<
endl
;
std
::
cout
<<
"
\n
This program demonstrates using SURF_OCL features detector and descriptor extractor"
<<
std
::
endl
;
std
::
cout
<<
"
\n
Usage:
\n\t
surf_matcher --left <image1> --right <image2> [-c]"
<<
std
::
endl
;
std
::
cout
<<
"
\n
Example:
\n\t
surf_matcher --left box.png --right box_in_scene.png"
<<
std
::
endl
;
}
int64
work_begin
=
0
;
int64
work_end
=
0
;
////////////////////////////////////////////////////
// This program demonstrates the usage of SURF_OCL.
// use cpu findHomography interface to calculate the transformation matrix
int
main
(
int
argc
,
char
*
argv
[])
void
workBegin
()
{
work_begin
=
getTickCount
();
}
void
workEnd
()
{
if
(
argc
!=
5
&&
argc
!=
1
)
{
help
();
return
-
1
;
}
vector
<
cv
::
ocl
::
Info
>
info
;
if
(
!
cv
::
ocl
::
getDevice
(
info
))
{
cout
<<
"Error: Did not find a valid OpenCL device!"
<<
endl
;
return
-
1
;
}
Mat
cpu_img1
,
cpu_img2
,
cpu_img1_grey
,
cpu_img2_grey
;
oclMat
img1
,
img2
;
if
(
argc
!=
5
)
work_end
=
getTickCount
()
-
work_begin
;
}
double
getTime
(){
return
work_end
/
((
double
)
cvGetTickFrequency
()
*
1000.
);
}
template
<
class
KPDetector
>
struct
SURFDetector
{
KPDetector
surf
;
SURFDetector
(
double
hessian
=
800.0
)
:
surf
(
hessian
)
{
cpu_img1
=
imread
(
"o.png"
);
cvtColor
(
cpu_img1
,
cpu_img1_grey
,
CV_BGR2GRAY
);
img1
=
cpu_img1_grey
;
CV_Assert
(
!
img1
.
empty
());
cpu_img2
=
imread
(
"r2.png"
);
cvtColor
(
cpu_img2
,
cpu_img2_grey
,
CV_BGR2GRAY
);
img2
=
cpu_img2_grey
;
}
else
template
<
class
T
>
void
operator
()(
const
T
&
in
,
const
T
&
mask
,
vector
<
cv
::
KeyPoint
>&
pts
,
T
&
descriptors
,
bool
useProvided
=
false
)
{
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
{
if
(
string
(
argv
[
i
])
==
"--left"
)
{
cpu_img1
=
imread
(
argv
[
++
i
]);
cvtColor
(
cpu_img1
,
cpu_img1_grey
,
CV_BGR2GRAY
);
img1
=
cpu_img1_grey
;
CV_Assert
(
!
img1
.
empty
());
}
else
if
(
string
(
argv
[
i
])
==
"--right"
)
{
cpu_img2
=
imread
(
argv
[
++
i
]);
cvtColor
(
cpu_img2
,
cpu_img2_grey
,
CV_BGR2GRAY
);
img2
=
cpu_img2_grey
;
}
else
if
(
string
(
argv
[
i
])
==
"--help"
)
{
help
();
return
-
1
;
}
}
surf
(
in
,
mask
,
pts
,
descriptors
,
useProvided
);
}
};
SURF_OCL
surf
;
//surf.hessianThreshold = 400.f;
//surf.extended = false;
// detecting keypoints & computing descriptors
oclMat
keypoints1GPU
,
keypoints2GPU
;
oclMat
descriptors1GPU
,
descriptors2GPU
;
// downloading results
vector
<
KeyPoint
>
keypoints1
,
keypoints2
;
vector
<
DMatch
>
matches
;
#ifndef USE_CPU_DESCRIPTOR
surf
(
img1
,
oclMat
(),
keypoints1GPU
,
descriptors1GPU
);
surf
(
img2
,
oclMat
(),
keypoints2GPU
,
descriptors2GPU
);
surf
.
downloadKeypoints
(
keypoints1GPU
,
keypoints1
);
surf
.
downloadKeypoints
(
keypoints2GPU
,
keypoints2
);
#ifdef USE_CPU_BFMATCHER
//BFMatcher
BFMatcher
matcher
(
cv
::
NORM_L2
);
matcher
.
match
(
Mat
(
descriptors1GPU
),
Mat
(
descriptors2GPU
),
matches
);
#else
BruteForceMatcher_OCL_base
matcher
(
BruteForceMatcher_OCL_base
::
L2Dist
);
matcher
.
match
(
descriptors1GPU
,
descriptors2GPU
,
matches
);
#endif
#else
surf
(
img1
,
oclMat
(),
keypoints1GPU
);
surf
(
img2
,
oclMat
(),
keypoints2GPU
);
surf
.
downloadKeypoints
(
keypoints1GPU
,
keypoints1
);
surf
.
downloadKeypoints
(
keypoints2GPU
,
keypoints2
);
// use SURF_OCL to detect keypoints and use SURF to extract descriptors
SURF
surf_cpu
;
Mat
descriptors1
,
descriptors2
;
surf_cpu
(
cpu_img1
,
Mat
(),
keypoints1
,
descriptors1
,
true
);
surf_cpu
(
cpu_img2
,
Mat
(),
keypoints2
,
descriptors2
,
true
);
matcher
.
match
(
descriptors1
,
descriptors2
,
matches
);
#endif
cout
<<
"OCL: FOUND "
<<
keypoints1GPU
.
cols
<<
" keypoints on first image"
<<
endl
;
cout
<<
"OCL: FOUND "
<<
keypoints2GPU
.
cols
<<
" keypoints on second image"
<<
endl
;
double
max_dist
=
0
;
double
min_dist
=
100
;
//-- Quick calculation of max and min distances between keypoints
for
(
size_t
i
=
0
;
i
<
keypoints1
.
size
();
i
++
)
template
<
class
KPMatcher
>
struct
SURFMatcher
{
KPMatcher
matcher
;
template
<
class
T
>
void
match
(
const
T
&
in1
,
const
T
&
in2
,
vector
<
cv
::
DMatch
>&
matches
)
{
double
dist
=
matches
[
i
].
distance
;
if
(
dist
<
min_dist
)
min_dist
=
dist
;
if
(
dist
>
max_dist
)
max_dist
=
dist
;
matcher
.
match
(
in1
,
in2
,
matches
);
}
};
printf
(
"-- Max dist : %f
\n
"
,
max_dist
);
printf
(
"-- Min dist : %f
\n
"
,
min_dist
);
//-- Draw only "good" matches (i.e. whose distance is less than 2.5*min_dist )
Mat
drawGoodMatches
(
const
Mat
&
cpu_img1
,
const
Mat
&
cpu_img2
,
const
vector
<
KeyPoint
>&
keypoints1
,
const
vector
<
KeyPoint
>&
keypoints2
,
vector
<
DMatch
>&
matches
,
vector
<
Point2f
>&
scene_corners_
)
{
//-- Sort matches and preserve top 10% matches
std
::
sort
(
matches
.
begin
(),
matches
.
end
());
std
::
vector
<
DMatch
>
good_matches
;
double
minDist
=
matches
.
front
().
distance
,
maxDist
=
matches
.
back
().
distance
;
for
(
size_t
i
=
0
;
i
<
keypoints1
.
size
();
i
++
)
const
int
ptsPairs
=
std
::
min
(
GOOD_PTS_MAX
,
(
int
)(
matches
.
size
()
*
GOOD_PORTION
));
for
(
int
i
=
0
;
i
<
ptsPairs
;
i
++
)
{
if
(
matches
[
i
].
distance
<
3
*
min_dist
)
{
good_matches
.
push_back
(
matches
[
i
]);
}
good_matches
.
push_back
(
matches
[
i
]
);
}
std
::
cout
<<
"
\n
Max distance: "
<<
maxDist
<<
std
::
endl
;
std
::
cout
<<
"Min distance: "
<<
minDist
<<
std
::
endl
;
std
::
cout
<<
"Calculating homography using "
<<
ptsPairs
<<
" point pairs."
<<
std
::
endl
;
// drawing the results
Mat
img_matches
;
drawMatches
(
cpu_img1
,
keypoints1
,
cpu_img2
,
keypoints2
,
good_matches
,
img_matches
,
Scalar
::
all
(
-
1
),
Scalar
::
all
(
-
1
),
vector
<
char
>
(),
DrawMatchesFlags
::
NOT_DRAW_SINGLE_POINTS
);
vector
<
char
>
(),
DrawMatchesFlags
::
NOT_DRAW_SINGLE_POINTS
);
//-- Localize the object
std
::
vector
<
Point2f
>
obj
;
...
...
@@ -207,26 +152,238 @@ int main(int argc, char* argv[])
obj
.
push_back
(
keypoints1
[
good_matches
[
i
].
queryIdx
].
pt
);
scene
.
push_back
(
keypoints2
[
good_matches
[
i
].
trainIdx
].
pt
);
}
Mat
H
=
findHomography
(
obj
,
scene
,
CV_RANSAC
);
//-- Get the corners from the image_1 ( the object to be "detected" )
std
::
vector
<
Point2f
>
obj_corners
(
4
);
obj_corners
[
0
]
=
cvPoint
(
0
,
0
);
obj_corners
[
1
]
=
cvPoint
(
cpu_img1
.
cols
,
0
);
obj_corners
[
2
]
=
cvPoint
(
cpu_img1
.
cols
,
cpu_img1
.
rows
);
obj_corners
[
3
]
=
cvPoint
(
0
,
cpu_img1
.
rows
);
std
::
vector
<
Point2f
>
scene_corners
(
4
);
Mat
H
=
findHomography
(
obj
,
scene
,
CV_RANSAC
);
perspectiveTransform
(
obj_corners
,
scene_corners
,
H
);
scene_corners_
=
scene_corners
;
//-- Draw lines between the corners (the mapped object in the scene - image_2 )
line
(
img_matches
,
scene_corners
[
0
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
scene_corners
[
1
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
Scalar
(
0
,
255
,
0
),
4
);
line
(
img_matches
,
scene_corners
[
1
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
scene_corners
[
2
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
Scalar
(
0
,
255
,
0
),
4
);
line
(
img_matches
,
scene_corners
[
2
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
scene_corners
[
3
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
Scalar
(
0
,
255
,
0
),
4
);
line
(
img_matches
,
scene_corners
[
3
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
scene_corners
[
0
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
Scalar
(
0
,
255
,
0
),
4
);
line
(
img_matches
,
scene_corners
[
0
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
scene_corners
[
1
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
Scalar
(
0
,
255
,
0
),
2
,
CV_AA
);
line
(
img_matches
,
scene_corners
[
1
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
scene_corners
[
2
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
Scalar
(
0
,
255
,
0
),
2
,
CV_AA
);
line
(
img_matches
,
scene_corners
[
2
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
scene_corners
[
3
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
Scalar
(
0
,
255
,
0
),
2
,
CV_AA
);
line
(
img_matches
,
scene_corners
[
3
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
scene_corners
[
0
]
+
Point2f
(
(
float
)
cpu_img1
.
cols
,
0
),
Scalar
(
0
,
255
,
0
),
2
,
CV_AA
);
return
img_matches
;
}
}
////////////////////////////////////////////////////
// This program demonstrates the usage of SURF_OCL.
// use cpu findHomography interface to calculate the transformation matrix
int
main
(
int
argc
,
char
*
argv
[])
{
vector
<
cv
::
ocl
::
Info
>
info
;
if
(
cv
::
ocl
::
getDevice
(
info
)
==
0
)
{
std
::
cout
<<
"Error: Did not find a valid OpenCL device!"
<<
std
::
endl
;
return
-
1
;
}
ocl
::
setDevice
(
info
[
0
]);
Mat
cpu_img1
,
cpu_img2
,
cpu_img1_grey
,
cpu_img2_grey
;
oclMat
img1
,
img2
;
bool
useCPU
=
false
;
bool
useGPU
=
false
;
bool
useALL
=
false
;
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
{
if
(
string
(
argv
[
i
])
==
"--left"
)
{
cpu_img1
=
imread
(
argv
[
++
i
]);
CV_Assert
(
!
cpu_img1
.
empty
());
cvtColor
(
cpu_img1
,
cpu_img1_grey
,
CV_BGR2GRAY
);
img1
=
cpu_img1_grey
;
}
else
if
(
string
(
argv
[
i
])
==
"--right"
)
{
cpu_img2
=
imread
(
argv
[
++
i
]);
CV_Assert
(
!
cpu_img2
.
empty
());
cvtColor
(
cpu_img2
,
cpu_img2_grey
,
CV_BGR2GRAY
);
img2
=
cpu_img2_grey
;
}
else
if
(
string
(
argv
[
i
])
==
"-c"
)
{
useCPU
=
true
;
useGPU
=
false
;
useALL
=
false
;
}
else
if
(
string
(
argv
[
i
])
==
"-g"
)
{
useGPU
=
true
;
useCPU
=
false
;
useALL
=
false
;
}
else
if
(
string
(
argv
[
i
])
==
"-a"
)
{
useALL
=
true
;
useCPU
=
false
;
useGPU
=
false
;
}
else
if
(
string
(
argv
[
i
])
==
"--help"
)
{
help
();
return
-
1
;
}
}
if
(
!
useCPU
)
{
std
::
cout
<<
"Device name:"
<<
info
[
0
].
DeviceName
[
0
]
<<
std
::
endl
;
}
double
surf_time
=
0.
;
//declare input/output
vector
<
KeyPoint
>
keypoints1
,
keypoints2
;
vector
<
DMatch
>
matches
;
vector
<
KeyPoint
>
gpu_keypoints1
;
vector
<
KeyPoint
>
gpu_keypoints2
;
vector
<
DMatch
>
gpu_matches
;
Mat
descriptors1CPU
,
descriptors2CPU
;
oclMat
keypoints1GPU
,
keypoints2GPU
;
oclMat
descriptors1GPU
,
descriptors2GPU
;
//instantiate detectors/matchers
SURFDetector
<
SURF
>
cpp_surf
;
SURFDetector
<
SURF_OCL
>
ocl_surf
;
SURFMatcher
<
BFMatcher
>
cpp_matcher
;
SURFMatcher
<
BFMatcher_OCL
>
ocl_matcher
;
//-- start of timing section
if
(
useCPU
)
{
for
(
int
i
=
0
;
i
<=
LOOP_NUM
;
i
++
)
{
if
(
i
==
1
)
workBegin
();
cpp_surf
(
cpu_img1_grey
,
Mat
(),
keypoints1
,
descriptors1CPU
);
cpp_surf
(
cpu_img2_grey
,
Mat
(),
keypoints2
,
descriptors2CPU
);
cpp_matcher
.
match
(
descriptors1CPU
,
descriptors2CPU
,
matches
);
}
workEnd
();
std
::
cout
<<
"CPP: FOUND "
<<
keypoints1
.
size
()
<<
" keypoints on first image"
<<
std
::
endl
;
std
::
cout
<<
"CPP: FOUND "
<<
keypoints2
.
size
()
<<
" keypoints on second image"
<<
std
::
endl
;
surf_time
=
getTime
();
std
::
cout
<<
"SURF run time: "
<<
surf_time
/
LOOP_NUM
<<
" ms"
<<
std
::
endl
<<
"
\n
"
;
}
else
if
(
useGPU
)
{
for
(
int
i
=
0
;
i
<=
LOOP_NUM
;
i
++
)
{
if
(
i
==
1
)
workBegin
();
ocl_surf
(
img1
,
oclMat
(),
keypoints1
,
descriptors1GPU
);
ocl_surf
(
img2
,
oclMat
(),
keypoints2
,
descriptors2GPU
);
ocl_matcher
.
match
(
descriptors1GPU
,
descriptors2GPU
,
matches
);
}
workEnd
();
std
::
cout
<<
"OCL: FOUND "
<<
keypoints1
.
size
()
<<
" keypoints on first image"
<<
std
::
endl
;
std
::
cout
<<
"OCL: FOUND "
<<
keypoints2
.
size
()
<<
" keypoints on second image"
<<
std
::
endl
;
surf_time
=
getTime
();
std
::
cout
<<
"SURF run time: "
<<
surf_time
/
LOOP_NUM
<<
" ms"
<<
std
::
endl
<<
"
\n
"
;
}
else
{
//cpu runs
for
(
int
i
=
0
;
i
<=
LOOP_NUM
;
i
++
)
{
if
(
i
==
1
)
workBegin
();
cpp_surf
(
cpu_img1_grey
,
Mat
(),
keypoints1
,
descriptors1CPU
);
cpp_surf
(
cpu_img2_grey
,
Mat
(),
keypoints2
,
descriptors2CPU
);
cpp_matcher
.
match
(
descriptors1CPU
,
descriptors2CPU
,
matches
);
}
workEnd
();
std
::
cout
<<
"
\n
CPP: FOUND "
<<
keypoints1
.
size
()
<<
" keypoints on first image"
<<
std
::
endl
;
std
::
cout
<<
"CPP: FOUND "
<<
keypoints2
.
size
()
<<
" keypoints on second image"
<<
std
::
endl
;
surf_time
=
getTime
();
std
::
cout
<<
"(CPP)SURF run time: "
<<
surf_time
/
LOOP_NUM
<<
" ms"
<<
std
::
endl
;
//gpu runs
for
(
int
i
=
0
;
i
<=
LOOP_NUM
;
i
++
)
{
if
(
i
==
1
)
workBegin
();
ocl_surf
(
img1
,
oclMat
(),
gpu_keypoints1
,
descriptors1GPU
);
ocl_surf
(
img2
,
oclMat
(),
gpu_keypoints2
,
descriptors2GPU
);
ocl_matcher
.
match
(
descriptors1GPU
,
descriptors2GPU
,
gpu_matches
);
}
workEnd
();
std
::
cout
<<
"
\n
OCL: FOUND "
<<
keypoints1
.
size
()
<<
" keypoints on first image"
<<
std
::
endl
;
std
::
cout
<<
"OCL: FOUND "
<<
keypoints2
.
size
()
<<
" keypoints on second image"
<<
std
::
endl
;
surf_time
=
getTime
();
std
::
cout
<<
"(OCL)SURF run time: "
<<
surf_time
/
LOOP_NUM
<<
" ms"
<<
std
::
endl
<<
"
\n
"
;
}
//--------------------------------------------------------------------------
std
::
vector
<
Point2f
>
cpu_corner
;
Mat
img_matches
=
drawGoodMatches
(
cpu_img1
,
cpu_img2
,
keypoints1
,
keypoints2
,
matches
,
cpu_corner
);
std
::
vector
<
Point2f
>
gpu_corner
;
Mat
ocl_img_matches
;
if
(
useALL
||
(
!
useCPU
&&!
useGPU
))
{
ocl_img_matches
=
drawGoodMatches
(
cpu_img1
,
cpu_img2
,
gpu_keypoints1
,
gpu_keypoints2
,
gpu_matches
,
gpu_corner
);
//check accuracy
std
::
cout
<<
"
\n
Check accuracy:
\n
"
;
if
(
cpu_corner
.
size
()
!=
gpu_corner
.
size
())
std
::
cout
<<
"Failed
\n
"
;
else
{
bool
result
=
false
;
for
(
size_t
i
=
0
;
i
<
cpu_corner
.
size
();
i
++
)
{
if
((
std
::
abs
(
cpu_corner
[
i
].
x
-
gpu_corner
[
i
].
x
)
>
10
)
||
(
std
::
abs
(
cpu_corner
[
i
].
y
-
gpu_corner
[
i
].
y
)
>
10
))
{
std
::
cout
<<
"Failed
\n
"
;
result
=
false
;
break
;
}
result
=
true
;
}
if
(
result
)
std
::
cout
<<
"Passed
\n
"
;
}
}
//-- Show detected matches
namedWindow
(
"ocl surf matches"
,
0
);
imshow
(
"ocl surf matches"
,
img_matches
);
waitKey
(
0
);
if
(
useCPU
)
{
namedWindow
(
"cpu surf matches"
,
0
);
imshow
(
"cpu surf matches"
,
img_matches
);
}
else
if
(
useGPU
)
{
namedWindow
(
"ocl surf matches"
,
0
);
imshow
(
"ocl surf matches"
,
img_matches
);
}
else
{
namedWindow
(
"cpu surf matches"
,
0
);
imshow
(
"cpu surf matches"
,
img_matches
);
namedWindow
(
"ocl surf matches"
,
0
);
imshow
(
"ocl surf matches"
,
ocl_img_matches
);
}
waitKey
(
0
);
return
0
;
}
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