Skip to content

Instantly share code, notes, and snippets.

@JorenSix
Created February 19, 2024 14:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JorenSix/7a2914a18548c3b71f5c2434dde6d3bb to your computer and use it in GitHub Desktop.
Save JorenSix/7a2914a18548c3b71f5c2434dde6d3bb to your computer and use it in GitHub Desktop.
Image matching using the lightglue library for keypoint detection in images and matching of keypoints.
from pathlib import Path
import torch
import glob
from lightglue import LightGlue, SuperPoint, DISK, SIFT, ALIKED, DoGHardNet
from lightglue.utils import load_image, rbd
from lightglue import viz2d
torch.set_grad_enabled(False)
class ImageMatcher:
def __init__(self, device):
self.device = device
self.extractor = SuperPoint(max_num_keypoints=2048).eval().to(self.device)
self.matcher = LightGlue(features="superpoint").eval().to(self.device)
# or DISK+LightGlue, ALIKED+LightGlue or SIFT+LightGlue
# extractor = DISK(max_num_keypoints=2048).eval() # load the extractor
# matcher = LightGlue(features='disk').eval() # load the matcher
def compare_images(self, image_path1, image_path2):
image0 = load_image(image_path1).to(self.device)
image1 = load_image(image_path2).to(self.device)
feats0 = self.extractor.extract(image0.to(self.device))
feats1 = self.extractor.extract(image1.to(self.device))
matches01 = self.matcher({"image0": feats0, "image1": feats1})
feats0, feats1, matches01 = [
rbd(x) for x in [feats0, feats1, matches01]
] # remove batch dimension
kpts0, kpts1, matches = feats0["keypoints"], feats1["keypoints"], matches01["matches"]
m_kpts0, m_kpts1 = kpts0[matches[..., 0]], kpts1[matches[..., 1]]
print(f"Number of matches; {len(matches)}; {image_path1} ; {image_path2} ")
axes = viz2d.plot_images([image0, image1])
viz2d.plot_matches(m_kpts0, m_kpts1, color="lime", lw=0.2)
viz2d.add_text(0, f'Stop after {matches01["stop"]} layers', fs=20)
kpc0, kpc1 = viz2d.cm_prune(matches01["prune0"]), viz2d.cm_prune(matches01["prune1"])
viz2d.plot_images([image0, image1])
viz2d.plot_keypoints([kpts0, kpts1], colors=[kpc0, kpc1], ps=10)
return axes
matcher = ImageMatcher("cpu")
image_files = ['./' + f for f in glob.glob('*.jpg')]
for one in image_files:
for two in image_files:
if one != two:
print(f"Comparing {one} and {two}")
matcher.compare_images(Path(one), Path(two))
@JorenSix
Copy link
Author

JorenSix commented Feb 19, 2024

See here for installation instructions: https://github.com/cvg/LightGlue

Once dependencies are installed, run with python image_matcher.py in a folder with several *.jpg files. The jpg files do not need to be scaled beforehand. Execution on cpu is reasonably fast.

Both the matcher as the keypoint detector can be modified by using the following code:

self.extractor = SuperPoint(max_num_keypoints=2048).eval().to(self.device)
self.matcher = LightGlue(features="superpoint").eval().to(self.device)

# or DISK+LightGlue, ALIKED+LightGlue or SIFT+LightGlue
# self.extractor = DISK(max_num_keypoints=2048).eval()  # load the extractor
# self.matcher = LightGlue(features='disk').eval()  # load the matcher

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment