Commit 7cc41464 authored by Julia Garriga Ferrer's avatar Julia Garriga Ferrer
Browse files

[core][components matching] Improve check for similar vectors between linked components

parent 32c236d6
......@@ -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,14 +133,31 @@ 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():
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:
......@@ -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,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment