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
8610ff1b
Commit
8610ff1b
authored
Jul 16, 2012
by
Alexander Mordvintsev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
find_obj.py allows to select detector and matcher and explore matching pairs
parent
63d8eedc
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
106 additions
and
37 deletions
+106
-37
find_obj.py
samples/python2/find_obj.py
+106
-37
No files found.
samples/python2/find_obj.py
View file @
8610ff1b
...
...
@@ -2,18 +2,62 @@
Feature-based image matching sample.
USAGE
find_obj.py [ <image1> <image2> ]
find_obj.py [--feature=<sift|surf|orb>[-flann]] [ <image1> <image2> ]
--feature - Feature to use. Can be sift, surf of orb. Append '-flann' to feature name
to use Flann-based matcher instead bruteforce.
Press left mouse button on a feature point to see its mathcing point.
'''
import
numpy
as
np
import
cv2
from
common
import
anorm
,
getsize
FLANN_INDEX_KDTREE
=
1
# bug: flann enums are missing
FLANN_INDEX_LSH
=
6
flann_params
=
dict
(
algorithm
=
FLANN_INDEX_KDTREE
,
trees
=
5
)
def
init_feature
(
name
):
detector
,
matcher
=
None
,
None
chunks
=
name
.
split
(
'-'
)
if
chunks
[
0
]
==
'sift'
:
detector
=
cv2
.
SIFT
()
norm
=
cv2
.
NORM_L2
elif
chunks
[
0
]
==
'surf'
:
detector
=
cv2
.
SURF
(
1000
)
norm
=
cv2
.
NORM_L2
elif
chunks
[
0
]
==
'orb'
:
detector
=
cv2
.
ORB
(
500
)
norm
=
cv2
.
NORM_HAMMING
if
'flann'
in
chunks
:
if
norm
==
cv2
.
NORM_L2
:
flann_params
=
dict
(
algorithm
=
FLANN_INDEX_KDTREE
,
trees
=
5
)
else
:
flann_params
=
dict
(
algorithm
=
FLANN_INDEX_LSH
,
table_number
=
6
,
# 12
key_size
=
12
,
# 20
multi_probe_level
=
1
)
#2
matcher
=
cv2
.
FlannBasedMatcher
(
flann_params
,
{})
# bug : need to pass empty dict (#1329)
else
:
matcher
=
cv2
.
BFMatcher
(
norm
)
return
detector
,
matcher
def
draw_match
(
img1
,
img2
,
p1
,
p2
,
status
=
None
,
H
=
None
):
def
filter_matches
(
kp1
,
kp2
,
matches
,
ratio
=
0.75
):
mkp1
,
mkp2
=
[],
[]
for
m
in
matches
:
if
len
(
m
)
==
2
and
m
[
0
]
.
distance
<
m
[
1
]
.
distance
*
ratio
:
m
=
m
[
0
]
mkp1
.
append
(
kp1
[
m
.
queryIdx
]
)
mkp2
.
append
(
kp2
[
m
.
trainIdx
]
)
p1
=
np
.
float32
([
kp
.
pt
for
kp
in
mkp1
])
p2
=
np
.
float32
([
kp
.
pt
for
kp
in
mkp2
])
kp_pairs
=
zip
(
mkp1
,
mkp2
)
return
p1
,
p2
,
kp_pairs
def
explore_match
(
win
,
img1
,
img2
,
kp_pairs
,
status
=
None
,
H
=
None
):
h1
,
w1
=
img1
.
shape
[:
2
]
h2
,
w2
=
img2
.
shape
[:
2
]
vis
=
np
.
zeros
((
max
(
h1
,
h2
),
w1
+
w2
),
np
.
uint8
)
...
...
@@ -25,71 +69,96 @@ def draw_match(img1, img2, p1, p2, status = None, H = None):
corners
=
np
.
float32
([[
0
,
0
],
[
w1
,
0
],
[
w1
,
h1
],
[
0
,
h1
]])
corners
=
np
.
int32
(
cv2
.
perspectiveTransform
(
corners
.
reshape
(
1
,
-
1
,
2
),
H
)
.
reshape
(
-
1
,
2
)
+
(
w1
,
0
)
)
cv2
.
polylines
(
vis
,
[
corners
],
True
,
(
255
,
255
,
255
))
if
status
is
None
:
status
=
np
.
ones
(
len
(
p1
),
np
.
bool_
)
p1
=
np
.
int32
([
kpp
[
0
]
.
pt
for
kpp
in
kp_pairs
])
p2
=
np
.
int32
([
kpp
[
1
]
.
pt
for
kpp
in
kp_pairs
])
+
(
w1
,
0
)
green
=
(
0
,
255
,
0
)
red
=
(
0
,
0
,
255
)
for
(
x1
,
y1
),
(
x2
,
y2
),
inlier
in
zip
(
np
.
int32
(
p1
),
np
.
int32
(
p2
),
status
):
col
=
[
red
,
green
][
inlier
]
white
=
(
255
,
255
,
255
)
kp_color
=
(
51
,
103
,
236
)
for
(
x1
,
y1
),
(
x2
,
y2
),
inlier
in
zip
(
p1
,
p2
,
status
):
if
inlier
:
c
v2
.
line
(
vis
,
(
x1
,
y1
),
(
x2
+
w1
,
y2
),
col
)
c
ol
=
green
cv2
.
circle
(
vis
,
(
x1
,
y1
),
2
,
col
,
-
1
)
cv2
.
circle
(
vis
,
(
x2
+
w1
,
y2
),
2
,
col
,
-
1
)
cv2
.
circle
(
vis
,
(
x2
,
y2
),
2
,
col
,
-
1
)
else
:
col
=
red
r
=
2
thickness
=
3
cv2
.
line
(
vis
,
(
x1
-
r
,
y1
-
r
),
(
x1
+
r
,
y1
+
r
),
col
,
thickness
)
cv2
.
line
(
vis
,
(
x1
-
r
,
y1
+
r
),
(
x1
+
r
,
y1
-
r
),
col
,
thickness
)
cv2
.
line
(
vis
,
(
x2
+
w1
-
r
,
y2
-
r
),
(
x2
+
w1
+
r
,
y2
+
r
),
col
,
thickness
)
cv2
.
line
(
vis
,
(
x2
+
w1
-
r
,
y2
+
r
),
(
x2
+
w1
+
r
,
y2
-
r
),
col
,
thickness
)
return
vis
cv2
.
line
(
vis
,
(
x2
-
r
,
y2
-
r
),
(
x2
+
r
,
y2
+
r
),
col
,
thickness
)
cv2
.
line
(
vis
,
(
x2
-
r
,
y2
+
r
),
(
x2
+
r
,
y2
-
r
),
col
,
thickness
)
vis0
=
vis
.
copy
()
for
(
x1
,
y1
),
(
x2
,
y2
),
inlier
in
zip
(
p1
,
p2
,
status
):
if
inlier
:
cv2
.
line
(
vis
,
(
x1
,
y1
),
(
x2
,
y2
),
green
)
cv2
.
imshow
(
win
,
vis
)
def
onmouse
(
event
,
x
,
y
,
flags
,
param
):
cur_vis
=
vis
if
flags
&
cv2
.
EVENT_FLAG_LBUTTON
:
cur_vis
=
vis0
.
copy
()
r
=
8
m
=
(
anorm
(
p1
-
(
x
,
y
))
<
r
)
|
(
anorm
(
p2
-
(
x
,
y
))
<
r
)
idxs
=
np
.
where
(
m
)[
0
]
kp1s
,
kp2s
=
[],
[]
for
i
in
idxs
:
(
x1
,
y1
),
(
x2
,
y2
)
=
p1
[
i
],
p2
[
i
]
col
=
(
red
,
green
)[
status
[
i
]]
cv2
.
line
(
cur_vis
,
(
x1
,
y1
),
(
x2
,
y2
),
col
)
kp1
,
kp2
=
kp_pairs
[
i
]
kp1s
.
append
(
kp1
)
kp2s
.
append
(
kp2
)
cur_vis
=
cv2
.
drawKeypoints
(
cur_vis
,
kp1s
,
flags
=
4
,
color
=
kp_color
)
cur_vis
[:,
w1
:]
=
cv2
.
drawKeypoints
(
cur_vis
[:,
w1
:],
kp2s
,
flags
=
4
,
color
=
kp_color
)
cv2
.
imshow
(
win
,
cur_vis
)
cv2
.
setMouseCallback
(
win
,
onmouse
)
if
__name__
==
'__main__'
:
print
__doc__
import
sys
try
:
fn1
,
fn2
=
sys
.
argv
[
1
:
3
]
import
sys
,
getopt
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
''
,
[
'feature='
])
opts
=
dict
(
opts
)
feature_name
=
opts
.
get
(
'--feature'
,
'sift'
)
try
:
fn1
,
fn2
=
args
except
:
fn1
=
'../c/box.png'
fn2
=
'../c/box_in_scene.png'
img1
=
cv2
.
imread
(
fn1
,
0
)
img2
=
cv2
.
imread
(
fn2
,
0
)
detector
,
matcher
=
init_feature
(
feature_name
)
if
detector
!=
None
:
print
'using'
,
feature_name
else
:
print
'unknown feature:'
,
feature_name
sys
.
exit
(
1
)
detector
=
cv2
.
SIFT
()
kp1
,
desc1
=
detector
.
detectAndCompute
(
img1
,
None
)
kp2
,
desc2
=
detector
.
detectAndCompute
(
img2
,
None
)
print
'img1 -
%
d features, img2 -
%
d features'
%
(
len
(
kp1
),
len
(
kp2
))
bf_matcher
=
cv2
.
BFMatcher
(
cv2
.
NORM_L2
)
flann_matcher
=
cv2
.
FlannBasedMatcher
(
flann_params
,
{})
# bug : need to pass empty dict (#1329)
def
match_and_draw
(
matcher
,
r_threshold
=
0.75
):
raw_matches
=
matcher
.
knnMatch
(
desc1
,
trainDescriptors
=
desc2
,
k
=
2
)
p1
,
p2
=
[],
[]
for
m
in
raw_matches
:
if
len
(
m
)
==
2
and
m
[
0
]
.
distance
<
m
[
1
]
.
distance
*
r_threshold
:
m
=
m
[
0
]
p1
.
append
(
kp1
[
m
.
queryIdx
]
.
pt
)
p2
.
append
(
kp2
[
m
.
trainIdx
]
.
pt
)
p1
,
p2
=
np
.
float32
((
p1
,
p2
))
def
match_and_draw
(
win
):
print
'matching...'
raw_matches
=
matcher
.
knnMatch
(
desc1
,
trainDescriptors
=
desc2
,
k
=
2
)
#2
p1
,
p2
,
kp_pairs
=
filter_matches
(
kp1
,
kp2
,
raw_matches
)
if
len
(
p1
)
>=
4
:
H
,
status
=
cv2
.
findHomography
(
p1
,
p2
,
cv2
.
RANSAC
,
2
.0
)
H
,
status
=
cv2
.
findHomography
(
p1
,
p2
,
cv2
.
RANSAC
,
5
.0
)
print
'
%
d /
%
d inliers/matched'
%
(
np
.
sum
(
status
),
len
(
status
))
else
:
H
,
status
=
None
,
None
print
'
%
d matches found, not enough for homography estimation'
%
len
(
p1
)
vis
=
draw_match
(
img1
,
img2
,
p1
,
p2
,
status
,
H
)
return
vis
vis
=
explore_match
(
win
,
img1
,
img2
,
kp_pairs
,
status
,
H
)
print
'bruteforce match:'
,
vis_brute
=
match_and_draw
(
bf_matcher
)
print
'flann match:'
,
vis_flann
=
match_and_draw
(
flann_matcher
)
cv2
.
imshow
(
'find_obj'
,
vis_brute
)
cv2
.
imshow
(
'find_obj flann'
,
vis_flann
)
0xFF
&
cv2
.
waitKey
()
match_and_draw
(
'find_obj'
)
cv2
.
waitKey
()
cv2
.
destroyAllWindows
()
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