Shiaoming / Python-VO

A simple python implemented frame-by-frame visual odometry with SuperPoint feature detector and SuperGlue feature matcher.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

how to visualize Superpoint+FLANN Matches?

lisaring opened this issue · comments

image
how to get this visualization in the code? Thank you.

check this function:

Python-VO/utils/tools.py

Lines 38 to 91 in c03e88f

def plot_matches(image0, image1, kpts0, kpts1, scores=None, layout="lr"):
"""
plot matches between two images. If score is nor None, then red: bad match, green: good match
:param image0: reference image
:param image1: current image
:param kpts0: keypoints in reference image
:param kpts1: keypoints in current image
:param scores: matching score for each keypoint pair, range [0~1], 0: worst match, 1: best match
:param layout: 'lr': left right; 'ud': up down
:return:
"""
H0, W0 = image0.shape[0], image0.shape[1]
H1, W1 = image1.shape[0], image1.shape[1]
if layout == "lr":
H, W = max(H0, H1), W0 + W1
out = 255 * np.ones((H, W, 3), np.uint8)
out[:H0, :W0, :] = image0
out[:H1, W0:, :] = image1
elif layout == "ud":
H, W = H0 + H1, max(W0, W1)
out = 255 * np.ones((H, W, 3), np.uint8)
out[:H0, :W0, :] = image0
out[H0:, :W1, :] = image1
else:
raise ValueError("The layout must be 'lr' or 'ud'!")
kpts0, kpts1 = np.round(kpts0).astype(int), np.round(kpts1).astype(int)
# get color
if scores is not None:
smin, smax = scores.min(), scores.max()
assert (0 <= smin <= 1 and 0 <= smax <= 1)
color = cm.gist_rainbow(scores * 0.4)
color = (np.array(color[:, :3]) * 255).astype(int)[:, ::-1]
else:
color = np.zeros((kpts0.shape[0], 3), dtype=int)
color[:, 1] = 255
for (x0, y0), (x1, y1), c in zip(kpts0, kpts1, color):
c = c.tolist()
if layout == "lr":
cv2.line(out, (x0, y0), (x1 + W0, y1), color=c, thickness=1, lineType=cv2.LINE_AA)
# display line end-points as circles
cv2.circle(out, (x0, y0), 2, c, -1, lineType=cv2.LINE_AA)
cv2.circle(out, (x1 + W0, y1), 2, c, -1, lineType=cv2.LINE_AA)
elif layout == "ud":
cv2.line(out, (x0, y0), (x1, y1 + H0), color=c, thickness=1, lineType=cv2.LINE_AA)
# display line end-points as circles
cv2.circle(out, (x0, y0), 2, c, -1, lineType=cv2.LINE_AA)
cv2.circle(out, (x1, y1 + H0), 2, c, -1, lineType=cv2.LINE_AA)
return out

check this function:

Python-VO/utils/tools.py

Lines 38 to 91 in c03e88f

def plot_matches(image0, image1, kpts0, kpts1, scores=None, layout="lr"):
"""
plot matches between two images. If score is nor None, then red: bad match, green: good match
:param image0: reference image
:param image1: current image
:param kpts0: keypoints in reference image
:param kpts1: keypoints in current image
:param scores: matching score for each keypoint pair, range [0~1], 0: worst match, 1: best match
:param layout: 'lr': left right; 'ud': up down
:return:
"""
H0, W0 = image0.shape[0], image0.shape[1]
H1, W1 = image1.shape[0], image1.shape[1]
if layout == "lr":
H, W = max(H0, H1), W0 + W1
out = 255 * np.ones((H, W, 3), np.uint8)
out[:H0, :W0, :] = image0
out[:H1, W0:, :] = image1
elif layout == "ud":
H, W = H0 + H1, max(W0, W1)
out = 255 * np.ones((H, W, 3), np.uint8)
out[:H0, :W0, :] = image0
out[H0:, :W1, :] = image1
else:
raise ValueError("The layout must be 'lr' or 'ud'!")
kpts0, kpts1 = np.round(kpts0).astype(int), np.round(kpts1).astype(int)
# get color
if scores is not None:
smin, smax = scores.min(), scores.max()
assert (0 <= smin <= 1 and 0 <= smax <= 1)
color = cm.gist_rainbow(scores * 0.4)
color = (np.array(color[:, :3]) * 255).astype(int)[:, ::-1]
else:
color = np.zeros((kpts0.shape[0], 3), dtype=int)
color[:, 1] = 255
for (x0, y0), (x1, y1), c in zip(kpts0, kpts1, color):
c = c.tolist()
if layout == "lr":
cv2.line(out, (x0, y0), (x1 + W0, y1), color=c, thickness=1, lineType=cv2.LINE_AA)
# display line end-points as circles
cv2.circle(out, (x0, y0), 2, c, -1, lineType=cv2.LINE_AA)
cv2.circle(out, (x1 + W0, y1), 2, c, -1, lineType=cv2.LINE_AA)
elif layout == "ud":
cv2.line(out, (x0, y0), (x1, y1 + H0), color=c, thickness=1, lineType=cv2.LINE_AA)
# display line end-points as circles
cv2.circle(out, (x0, y0), 2, c, -1, lineType=cv2.LINE_AA)
cv2.circle(out, (x1, y1 + H0), 2, c, -1, lineType=cv2.LINE_AA)
return out

check this function:

Python-VO/utils/tools.py

Lines 38 to 91 in c03e88f

def plot_matches(image0, image1, kpts0, kpts1, scores=None, layout="lr"):
"""
plot matches between two images. If score is nor None, then red: bad match, green: good match
:param image0: reference image
:param image1: current image
:param kpts0: keypoints in reference image
:param kpts1: keypoints in current image
:param scores: matching score for each keypoint pair, range [0~1], 0: worst match, 1: best match
:param layout: 'lr': left right; 'ud': up down
:return:
"""
H0, W0 = image0.shape[0], image0.shape[1]
H1, W1 = image1.shape[0], image1.shape[1]
if layout == "lr":
H, W = max(H0, H1), W0 + W1
out = 255 * np.ones((H, W, 3), np.uint8)
out[:H0, :W0, :] = image0
out[:H1, W0:, :] = image1
elif layout == "ud":
H, W = H0 + H1, max(W0, W1)
out = 255 * np.ones((H, W, 3), np.uint8)
out[:H0, :W0, :] = image0
out[H0:, :W1, :] = image1
else:
raise ValueError("The layout must be 'lr' or 'ud'!")
kpts0, kpts1 = np.round(kpts0).astype(int), np.round(kpts1).astype(int)
# get color
if scores is not None:
smin, smax = scores.min(), scores.max()
assert (0 <= smin <= 1 and 0 <= smax <= 1)
color = cm.gist_rainbow(scores * 0.4)
color = (np.array(color[:, :3]) * 255).astype(int)[:, ::-1]
else:
color = np.zeros((kpts0.shape[0], 3), dtype=int)
color[:, 1] = 255
for (x0, y0), (x1, y1), c in zip(kpts0, kpts1, color):
c = c.tolist()
if layout == "lr":
cv2.line(out, (x0, y0), (x1 + W0, y1), color=c, thickness=1, lineType=cv2.LINE_AA)
# display line end-points as circles
cv2.circle(out, (x0, y0), 2, c, -1, lineType=cv2.LINE_AA)
cv2.circle(out, (x1 + W0, y1), 2, c, -1, lineType=cv2.LINE_AA)
elif layout == "ud":
cv2.line(out, (x0, y0), (x1, y1 + H0), color=c, thickness=1, lineType=cv2.LINE_AA)
# display line end-points as circles
cv2.circle(out, (x0, y0), 2, c, -1, lineType=cv2.LINE_AA)
cv2.circle(out, (x1, y1 + H0), 2, c, -1, lineType=cv2.LINE_AA)
return out

Thank you.