Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
XRD
darfix
Commits
7cc41464
Commit
7cc41464
authored
Feb 24, 2020
by
Julia Garriga Ferrer
Browse files
[core][components matching] Improve check for similar vectors between linked components
parent
32c236d6
Changes
1
Hide whitespace changes
Inline
Side-by-side
darfix/core/componentsMatching.py
View file @
7cc41464
...
...
@@ -28,7 +28,6 @@ __authors__ = ["J. Garriga"]
__license__
=
"MIT"
__date__
=
"21/01/2020"
import
cv2
import
numpy
...
...
@@ -101,7 +100,8 @@ class ComponentsMatching():
dst
=
numpy
.
linalg
.
norm
(
X
-
Y
)
# their euclidean distances
return
dst
def
match_components
(
self
,
id1
=
None
,
id2
=
None
,
method
=
Method
.
orb_feature_matching
):
def
match_components
(
self
,
id1
=
None
,
id2
=
None
,
method
=
Method
.
orb_feature_matching
,
tol
=
8
):
"""
Match components. Given the components x1,...,xn of dataset 1 and the
components y1,...,ym of dataset 2, this function computes the pairs
...
...
@@ -122,7 +122,7 @@ class ComponentsMatching():
id1
=
0
id2
=
1
matches
=
{}
good
=
{}
final_matches
=
{}
if
method
==
Method
.
orb_feature_matching
:
self
.
descriptors
=
self
.
_create_descriptors
()
...
...
@@ -133,15 +133,32 @@ class ComponentsMatching():
if
component1
.
descriptor
is
not
None
:
for
j
,
component2
in
enumerate
(
self
.
descriptors
[
id2
]):
if
component2
.
descriptor
is
not
None
:
# Match descriptors
matches
[(
i
,
j
)]
=
bf
.
match
(
component1
.
descriptor
,
component2
.
descriptor
)
good
[(
i
,
j
)]
=
numpy
.
array
(
bf
.
match
(
component1
.
descriptor
,
component2
.
descriptor
))
best_v
=
[]
# Add matches sorted by number of matches found.
for
x
,
y
in
sorted
(
matches
,
key
=
lambda
match
:
len
(
matches
[
match
]),
for
x
,
y
in
sorted
(
good
,
key
=
lambda
match
:
len
(
good
[
match
]),
reverse
=
True
):
# Only add match if neither x nor y are already in the list.
if
x
not
in
final_matches
.
keys
()
and
y
not
in
final_matches
.
values
():
final_matches
[
x
]
=
y
kp1
=
[]
kp2
=
[]
for
match
in
good
[(
x
,
y
)]:
kp1
+=
[
self
.
descriptors
[
id1
][
x
].
keypoints
[
match
.
queryIdx
].
pt
]
kp2
+=
[
self
.
descriptors
[
id2
][
y
].
keypoints
[
match
.
trainIdx
].
pt
]
if
len
(
kp1
)
>
1
and
len
(
kp2
)
>
1
:
v
=
numpy
.
mean
(
numpy
.
array
(
kp2
)
-
numpy
.
array
(
kp1
),
axis
=
0
)
else
:
v
=
numpy
.
array
(
kp2
)
-
numpy
.
array
(
kp1
)
if
not
numpy
.
any
(
best_v
):
best_v
=
v
final_matches
[
x
]
=
y
elif
numpy
.
linalg
.
norm
(
best_v
-
v
)
<
tol
:
final_matches
[
x
]
=
y
elif
method
==
Method
.
sift_feature_matching
:
keypoints
=
self
.
_create_sift_keypoints
()
...
...
@@ -151,9 +168,9 @@ class ComponentsMatching():
for
i
,
kp1
in
enumerate
(
keypoints
[
id1
]):
for
j
,
kp2
in
enumerate
(
keypoints
[
id2
]):
# Match descriptors
matches
[(
i
,
j
)]
=
mp
.
match
(
kp1
,
kp2
)
good
[(
i
,
j
)]
=
mp
.
match
(
kp1
,
kp2
)
# Add matches sorted by number of matches found.
for
x
,
y
in
sorted
(
matches
,
key
=
lambda
match
:
matches
[
match
].
shape
[
0
],
for
x
,
y
in
sorted
(
good
,
key
=
lambda
match
:
good
[
match
].
shape
[
0
],
reverse
=
True
):
# Only add match if neither x nor y are already in the list.
if
x
not
in
final_matches
.
keys
()
and
y
not
in
final_matches
.
values
():
...
...
@@ -162,13 +179,13 @@ class ComponentsMatching():
elif
method
==
Method
.
euclidean_distance
:
for
i
,
X
in
enumerate
(
self
.
components
[
id1
]):
for
j
,
Y
in
enumerate
(
self
.
components
[
id2
]):
matches
[(
i
,
j
)]
=
self
.
euclidean_distance
(
X
,
Y
)
good
[(
i
,
j
)]
=
self
.
euclidean_distance
(
X
,
Y
)
# Add matches sorted by distance.
for
x
,
y
in
sorted
(
matches
,
key
=
lambda
match
:
matches
[
match
]):
for
x
,
y
in
sorted
(
good
,
key
=
lambda
match
:
good
[
match
]):
# Only add match if neither x nor y are already in the list.
if
x
not
in
final_matches
.
keys
()
and
y
not
in
final_matches
.
values
():
final_matches
[
x
]
=
y
return
final_matches
,
matches
return
final_matches
,
good
def
draw_matches
(
self
,
final_matches
,
matches
,
id1
=
None
,
id2
=
None
,
displayMatches
=
False
):
...
...
@@ -201,6 +218,30 @@ class ComponentsMatching():
assert
all
((
isinstance
(
match
,
cv2
.
DMatch
)
for
match
in
values
)
for
values
in
matches
.
values
()),
\
"Dictionary `matches` has to contain values of type `cv2.DMatch`"
"""
if len(matches[(i, j)])>MIN_MATCH_COUNT:
kp2 = self.components[id2][j].keypoints
src_pts = numpy.float32([kp1[m.queryIdx].pt for m in matches[(i, j)]]).reshape(-1,1,2)
dst_pts = numpy.float32([kp2[m.trainIdx].pt for m in matches[(i, j)]]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
matchesMask = mask.ravel().tolist()
h,w = component.image.shape
pts = numpy.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
dst = cv2.perspectiveTransform(pts,M)
img2 = cv2.polylines(img2,[numpy.int32(dst)],True,255,3, cv2.LINE_AA)
else:
print("Not enough matches are found - %d/%d" % (len(matches[(i,j)]),MIN_MATCH_COUNT))
matchesMask = None
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
singlePointColor = None,
matchesMask = matchesMask, # draw only inliers
flags = 2)"""
img
=
cv2
.
drawMatches
(
self
.
descriptors
[
id1
][
i
].
image
,
self
.
descriptors
[
id1
][
i
].
keypoints
,
self
.
descriptors
[
id2
][
j
].
image
,
...
...
Write
Preview
Supports
Markdown
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