A Toolbox for Image Feature Matching and Evaluations

Overview

A Toolbox for Image Feature Matching and Evaluations

In this repository, we provide easy interfaces for several exisiting SotA methods to match image feature correspondences between image pairs. We provide scripts to evaluate their predicted correspondences on common benchmarks for the tasks of image matching, homography estimation and visual localization.

Notice

  • This repository is expected to be actively maintained (at least before I graduate 🤣 🤣 ) and gradually (slowly) grow for new features of interest.
  • Suggestions regarding how to improve this repo, such as adding new SotA image matching methods or new benchmark evaluations, are welcome 👏 .

Regarding Patch2Pix

With this reprository, one can reproduce the tables reported in our paper accepted at CVPR2021: Patch2Pix: Epipolar-Guided Pixel-Level Correspondences[pdf]. Check our patch2pix repository for its training code.

Disclaimer

  • All of the supported methods and evaluations are not implemented from scratch by us. Instead, we modularize their original code to define unified interfaces.
  • If you are using the results of a method, remember to cite the corresponding paper.
  • All credits of the implemetation of those methods belong to their authors .

Supported Methods & Evaluations

Keypoint-based Matching:

Keypoint/Detection-free Matching:

Supported Evaluations :

  • Image feature matching on HPatches
  • Homography estimation on HPatches
  • Visual localization benchmarks:
    • InLoc
    • Aachen (original + v1.1)

Repository Overview

The repository is structured as follows:

  • configs/: Each method has its own yaml (.yml) file to configure its testing parameters.
  • data/: All datasets should be placed under this folder following our instructions described in Data Preparation.
  • immatch/: It contains implementations of method wrappers and evaluation interfaces.
  • outputs/: All evaluation results are supposed to be saved here. One folder per benchmark.
  • pretrained/: It contains the pretrained models of the supported methods.
  • third_party/: The real implementation of the supported methods from their original repositories, as git submodules.
  • notebooks/: It contains jupyter notebooks that show example codes to quickly access the methods implemented in this repo.
  • docs/: It contains separate documentation about installation and evaluation. To keep a clean face of this repo :).

👉 Refer to install.md for details about installation.

👉 Refer to evaluation.md for details about evaluation on benchmarks.

Example Code for Quick Testing

To use a specific method to perform the matching task, you simply need to do:

  • Initialize a matcher using its config file. See examples of config yaml files under configs folder, eg., patch2pix.yml. Each config file contains multiple sections, each section corresponds to one setting. Here, we use the setting (tagged by 'example') for testing on example image pairs.
  • Perform matching
import immatch
import yaml
from immatch.utils import plot_matches

# Initialize model
with open('configs/patch2pix.yml, 'r') as f:
    args = yaml.load(f, Loader=yaml.FullLoader)['example']
model = immatch.__dict__[args['class']](args)
matcher = lambda im1, im2: model.match_pairs(im1, im2)

# Specify the image pair
im1 = 'third_party/patch2pix/examples/images/pair_2/1.jpg'
im2 = 'third_party/patch2pix/examples/images/pair_2/2.jpg'

# Match and visualize
matches, _, _, _ = matcher(im1, im2)    
plot_matches(im1, im2, matches, radius=2, lines=True)

example matches

👉 Try out the code using example notebook .

TODOs & Updates

- [x] Add LoFTR method (2021-7-8)
- [x] Add simple match visualization (2021-7-8)
- [ ] Localize on RobotCar 
Comments
  • Feature Request: Add homography AUC

    Feature Request: Add homography AUC

    In this toolbox, homographies on hpatches are evaluated with accuracy, while recent papers such as LoFTR and SuperGlue both use AUC, which makes comparisons difficult.

    It further complicates matters that pydegensac is used here, while the opencv version is used in most papers. Adding the option of calculating AUC and opencv would make comparison easier. See e.g. https://github.com/PruneTruong/DenseMatching/blob/40c29a6b5c35e86b9509e65ab0cd12553d998e5f/validation/utils.py#L209 for an AUC implementation.

    opened by Parskatt 19
  • aachen evaluation

    aachen evaluation

    Hi @GrumpyZhou Thanks for your great works!

    I use patch2pix + superglue as matcher for aachen evaluation, and use eval_aachen.py script. I can get keypoints.h5 and matches.h5, but an error was encountered while running triangulation, the error as follows: "Keypoint format not supported"

    I find the format slightly different from the hloc, any suggestion? Did you test patch2pix + superglue on aachen ? Thanks!

    opened by wolf943134497 14
  • Missing RobotCar/queries

    Missing RobotCar/queries

    Hi~ I'm trying to evaluate my method on robotcar with your amazing image-matching-toolbox. I notice that there should be a queries folder under RobotCar dataset, which is missing from the dataset download page https://data.ciirc.cvut.cz/public/projects/2020VisualLocalization/RobotCar-Seasons/ . Would you please provide the download link of this folder?

    opened by Merical 8
  • RuntimeError

    RuntimeError

    RuntimeError: Tried to access nonexistent attribute or method 'call' of type 'torch.kornia.geometry.boxes.Boxes3D'. Did you forget to initialize an attribute in init()?: File "/home/szw/anaconda3/envs/image-matching-toolbox-main/lib/python3.7/site-packages/kornia/geometry/boxes.py", line 601 # Due to some torch.jit.script bug (at least <= 1.9), you need to pass all arguments to init when # constructing the class from inside of a method. return cls(hexahedrons, raise_if_not_floating_point=False, mode=mode) ~~~ <--- HERE

    opened by zhubingerdai 8
  • git@github.com: Permission denied (publickey).

    [email protected]: Permission denied (publickey).

    Thanks for this great project. According to the installation doc the toolbox should be install using ssh, which is impossible for users interested to add ssh-key to this project. And offcourse, nonsense. and I have checked the .gitmodules file [submodule "third_party/SuperGluePretrainedNetwork"] path = third_party/superglue url = [email protected]:magicleap/SuperGluePretrainedNetwork.git [submodule "third_party/caps"] path = third_party/caps url = [email protected]:GrumpyZhou/caps.git [submodule "third_party/d2-net"] path = third_party/d2net url = [email protected]:mihaidusmanu/d2-net.git [submodule "third_party/r2d2"] path = third_party/r2d2 url = https://github.com/naver/r2d2 ignore = untracked [submodule "third_party/sparse-ncnet"] path = third_party/sparsencnet url = [email protected]:ignacio-rocco/sparse-ncnet.git [submodule "third_party/hloc"] path = third_party/hloc url = [email protected]:GrumpyZhou/Hierarchical-Localization.git branch = extend_base_dev would you change the url to https, so we can test and use this great project.

    opened by hhmaizi 6
  • How do I add my own methods to test?

    How do I add my own methods to test?

    I copied the loftr code to add the required files, but when running my code failed: KeyError: 'block_type' Self. block_type = config['block_type'], which is the argument in my code

    opened by zhubingerdai 5
  • Unable to execute Quick Testing code

    Unable to execute Quick Testing code

    I am unable to execute the quick testing code shown in readme.md I've imported all the files as a PyCharm project, then I installed all the required packages using Conda, I created the following file to execute the image-matching-toolbox, but I have this error... (in addition, there is NO file plot_matches.py inside immatch.utils) image

    Waiting your answer, thank you in advance

    opened by uly94 5
  • Could you please guide how to set the evaluation for Aachen Night Only?

    Could you please guide how to set the evaluation for Aachen Night Only?

    Thank you very much for this toolbox.

    Here I would like to ask the question of how to set the evaluation for Aachen Night only with the default retrieved image list? Could you please guide how to do this? I am very new to the system.

    opened by GabbySuwichaya 4
  • Prepare Image Pairs

    Prepare Image Pairs

    bash download.sh: requests.exceptions.ConnectionError: HTTPSConnectionPool(host='drive.google.com', port=443): Max retries exceeded with url: /uc?id=1T2c3DHJlTdRpo_Y3Ad4AH8p4tS7cOyjP (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f0d00812cd0>: Failed to establish a new connection: [Errno 101] Network is unreachable')) unzip: cannot find or open pairs.zip, pairs.zip.zip or pairs.zip.ZIP.

    opened by zhubingerdai 4
  • A request for help when testing Hpatch `ValueError: zero-size array to reduction operation minimum which has no identity`

    A request for help when testing Hpatch `ValueError: zero-size array to reduction operation minimum which has no identity`

    Hi!

    Thank you so much for releasing this toolbox and for the awesome paper on Patch2Pix. Here, I would like to kindly ask for your help.

    I have tried to run your example for Patch2Pix and another one of SuperPoint + NCNet ...

    The following code lines are in ./test_patch3pix.sh...

    python -m immatch.eval_hpatches --gpu 0 \
        --config 'patch2pix' --match_thres 0.25 0.5 0.9  \
        --task 'both' --save_npy \
        --root_dir . 
    
    

    However, I keep getting following error ValueError: zero-size array to reduction operation minimum which has no identity ... I am not sure how to fix it. So, please give the guidance...

    Below here is the full error report.

    Also, I have captured the screen to confirm at the bottom to confirm

    (immatch) gabby-suwichaya@gabby-suwichaya:/mnt/HDD4TB1/image-matching-toolbox$ ./test_patch3pix.sh Can not import sparsencnet
    
    >>>> Method=Patch2Pix Default config: {'class': 'Patch2Pix', 'ckpt': 'pretrained/patch2pix/patch2pix_pretrained.pth', 'ksize': 2, 'imsize': 1024, 'match_threshold': 0.25} Thres: [0.25, 0.5, 0.9]
    
    Load model method:patch2pix 
    Ckpt:pretrained/patch2pix/patch2pix_pretrained.pth
    Initialize Patch2Pix: backbone=ResNet34 cstride=True upsample=8
    Init regressor Namespace(conv_dims=[512, 512], conv_kers=[3, 3], conv_strs=[2, 1], fc_dims=[512, 256], feat_comb='pre', feat_dim=259, panc=1, pshift=8, psize=[16, 16], shared=False)
    FeatRegressNet:  feat_comb:pre psize:16 out:5 feat_dim:518 conv_kers:[3, 3] conv_dims:[512, 512] conv_str:[2, 1] 
    FeatRegressNet:  feat_comb:pre psize:16 out:5 feat_dim:518 conv_kers:[3, 3] conv_dims:[512, 512] conv_str:[2, 1] 
    Xavier initialize all model parameters
    Initialize ResNet using pretrained model from https://download.pytorch.org/models/resnet34-333f7ec4.pth
    Reload all model parameters from weights dict
    Initialize Patch2Pix
    Matching thres: 0.25  Save to: ./outputs/hpatches/cache/Patch2Pix.im1024.m0.25.npy
    
    >>Eval hpatches: method=Patch2Pix rthres=2 thres=[1, 3, 5, 10] 
    Save results to ./outputs/hpatches/cache/Patch2Pix.im1024.m0.25.npy
    /home/gabby-suwichaya/anaconda3/envs/immatch/lib/python3.7/site-packages/numpy/core/fromnumeric.py:3441: RuntimeWarning: Mean of empty slice.
      out=out, **kwargs)
    /home/gabby-suwichaya/anaconda3/envs/immatch/lib/python3.7/site-packages/numpy/core/_methods.py:189: RuntimeWarning: invalid value encountered in double_scalars
      ret = ret.dtype.type(ret / rcount)
    Traceback (most recent call last):
      File "/home/gabby-suwichaya/anaconda3/envs/immatch/lib/python3.7/runpy.py", line 193, in _run_module_as_main
        "__main__", mod_spec)
      File "/home/gabby-suwichaya/anaconda3/envs/immatch/lib/python3.7/runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "/mnt/HDD4TB1/image-matching-toolbox/immatch/eval_hpatches.py", line 98, in <module>
        print_out=args.print_out
      File "/mnt/HDD4TB1/image-matching-toolbox/immatch/eval_hpatches.py", line 74, in eval_hpatches
        save_npy=result_npy
      File "/mnt/HDD4TB1/image-matching-toolbox/immatch/utils/hpatches_helper.py", line 323, in eval_hpatches
        lprint_(eval_summary(results, thres, save_npy=save_npy))
      File "/mnt/HDD4TB1/image-matching-toolbox/immatch/utils/hpatches_helper.py", line 28, in eval_summary
        summary += '# Features: mean={:.0f} min={:d} max={:d}\n'.format(np.mean(n_feats), np.min(n_feats), np.max(n_feats))
      File "<__array_function__ internals>", line 6, in amin
      File "/home/gabby-suwichaya/anaconda3/envs/immatch/lib/python3.7/site-packages/numpy/core/fromnumeric.py", line 2880, in amin
        keepdims=keepdims, initial=initial, where=where)
      File "/home/gabby-suwichaya/anaconda3/envs/immatch/lib/python3.7/site-packages/numpy/core/fromnumeric.py", line 86, in _wrapreduction
        return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
    ValueError: zero-size array to reduction operation minimum which has no identity
    

    demo_problem

    opened by GabbySuwichaya 4
  • COTR no matches found in hpatches test

    COTR no matches found in hpatches test

    exec the command according to the evaulation.md

    python -m immatch.eval_hpatches --gpu 0 \ 
        --config  'cotr' \
        --task 'both' --save_npy \
        --root_dir .
    

    and output:

    >>>> Method=COTR Default config: {'class': 'COTR', 'ckpt': 'pretrained/cotr/cotr_default.pth.tar', 'backbone': 'resnet50', 'hidden_dim': 256, 'dilation': False, 'dropout': 0.1, 'nheads': 8, 'layer': 'layer3', 'backbone_layer_dims': {'layer1': 256, 'layer2': 512, 'layer3': 1024, 'layer4': 2048}, 'enc_layers': 6, 'dec_layers': 6, 'position_embedding': 'lin_sine', 'max_corrs': 100, 'match_threshold': 0.0, 'imsize': -1, 'batch_size': 32} Thres: [0.0]
    Matching thres: 0.0  Save to: ./outputs/hpatches/cache/COTR.npy
    
    >>>>Eval hpatches: task=matching+homography method=COTR scale_H=False rthres=2 thres=[1, 3, 5, 10] 
    >>Finished, pairs=0 match_failed=580 matches=0.0 match_time=nans
    ==== Image Matching ====
    #Features: mean=0 min=0 max=0
    #(Old)Matches: a=0, i=0, v=0
    #Matches: a=0, i=0, v=0
    MMA@[ 1  3  5 10] px:
    a=[0. 0. 0. 0.]
    i=[0. 0. 0. 0.]
    v=[0. 0. 0. 0.]
    
    ==== Homography Estimation ====
    Hest solver=degensac est_failed=580 ransac_thres=2 inlier_rate=0.00
    Hest Correct: a=[0. 0. 0. 0.]
    i=[0. 0. 0. 0.]
    v=[0. 0. 0. 0.]
    Hest AUC: a=[0. 0. 0. 0.]
    i=[0. 0. 0. 0.]
    v=[0. 0. 0. 0.]
    

    and i set print function in match_pairs function but no infomation output

    def match_pairs(self, im1_path, im2_path, queries_im1=None):
            im1 = imageio.imread(im1_path, pilmode='RGB')
            im2 = imageio.imread(im2_path, pilmode='RGB')
            engine = SparseEngine(self.model, self.batch_size, mode='tile')
            matches = engine.cotr_corr_multiscale(
                im1, im2, np.linspace(0.5, 0.0625, 4), 1,
                max_corrs=self.max_corrs, queries_a=queries_im1,
                force=True
            )
    
            print(matches.shape) # add print
    
            # Fake scores as not output by the model
            scores = np.ones(len(matches))
            kpts1 = matches[:, :2]
            kpts2 = matches[:, 2:4]
            return matches, kpts1, kpts2, scores
    
    opened by miRemid 3
  • Test loftr in inloc

    Test loftr in inloc

    hi,i used image-matching-toolbox to eval loftr for inloc, config: default: &default class: 'LoFTR' ckpt: 'pretrained/loftr/outdoor_ds.ckpt' match_threshold: 0.2 imsize: 1024 no_match_upscale: False example: <<: *default match_threshold: 0.5 imsize: -1 hpatch: <<: *default imsize: 480 no_match_upscale: True inloc: <<: *default pairs: 'pairs-query-netvlad40-temporal.txt' rthres: 48 skip_matches: 20

    and then get result as below: image

    opened by xunfeng2zkj 10
  • Pillow is spewing some deprecation warnings Resampling.BICUBIC

    Pillow is spewing some deprecation warnings Resampling.BICUBIC

    image-matching-toolbox/immatch/utils/data_io.py:31: DeprecationWarning: BICUBIC is deprecated and will be removed in Pillow 10 (2023-07-01). Use Resampling.BICUBIC instead.

    Here is the offending line https://github.com/GrumpyZhou/image-matching-toolbox/blob/main/immatch/utils/data_io.py#L31

    The Resampling enum was added in Pillow 9.1.0. Prior to this, to resided as a constant at top level.

    opened by SergioRAgostinho 0
  • Further efforts to reproduce loftr hpatches

    Further efforts to reproduce loftr hpatches

    More changes related to #20 .

    Running python -m immatch.eval_hpatches --config 'loftr' --task 'both' --rot_dir . --ransac_thres=3 --h_solver cv now yields

    >>>>Eval hpatches: task=matching+homography method=LoFTR_outdoor_ds_noms scale_H=True rthres=3.0 thres=[1, 3, 5, 10] 
    >>Finished, pairs=540 match_failed=0 matches=913.1 match_time=0.12s
    ==== Image Matching ====
    #Features: mean=913 min=7 max=1000
    #(Old)Matches: a=913, i=975, v=856
    #Matches: a=913, i=975, v=856
    MMA@[ 1  3  5 10] px:
    a=[0.73 0.95 0.96 0.97]
    i=[0.8  0.99 0.99 1.  ]
    v=[0.66 0.91 0.94 0.95]
    
    ==== Homography Estimation ====
    Hest solver=cv est_failed=0 ransac_thres=3.0 inlier_rate=0.93
    Hest Correct: a=[0.65 0.88 0.92 0.95]
    i=[0.82 0.98 0.99 1.  ]
    v=[0.49 0.79 0.86 0.9 ]
    Hest AUC: a=[0.4  0.67 0.76 0.85]
    i=[0.56 0.81 0.88 0.94]
    v=[0.25 0.53 0.65 0.77]
    

    These numbers (at 3px) are actually higher than in the LoFTR paper. Take what you find useful from this pull request. I suppose you might want to wait with merging this until there is a reply here: https://github.com/zju3dv/LoFTR/issues/136

    opened by georg-bn 0
  • Eval on IMC - I may help

    Eval on IMC - I may help

    Hi,

    There is a sample repository for the submission to IMC https://github.com/ducha-aiki/imc2021-sample-kornia-submission

    If you want, I can adapt it for your toolbox. Caveat - it would be quite hard to do for the methods, not based on keypoints now.

    opened by ducha-aiki 12
Owner
Qunjie Zhou
PhD Candidate at the Dynamic Vision and Learning Group.
Qunjie Zhou
Seaborn-image is a Python image visualization library based on matplotlib and provides a high-level API to draw attractive and informative images quickly and effectively.

seaborn-image: image data visualization Description Seaborn-image is a Python image visualization library based on matplotlib and provides a high-leve

null 48 Jan 5, 2023
Simplest QRGenerator with a cool feature (-sh=True :D)

Simple QR-Codes Generator :D Generates QR-codes, nothing more and nothing less >.< How to use Just run ./install.sh to set all the dependencies up, th

RENNAARENATA 1 Dec 11, 2021
Easily turn large sets of image urls to an image dataset. Can download, resize and package 100M urls in 20h on one machine.

img2dataset Easily turn large sets of image urls to an image dataset. Can download, resize and package 100M urls in 20h on one machine. Also supports

Romain Beaumont 1.4k Jan 1, 2023
Image Reading, Metadata Conversion, and Image Writing for Microscopy Images in Python

AICSImageIO Image Reading, Metadata Conversion, and Image Writing for Microscopy Images in Pure Python Features Supports reading metadata and imaging

Allen Institute for Cell Science - Modeling 137 Dec 14, 2022
An open source image editor which can manipulate an image in many ways!

Image Editor - An open source image editor which can manipulate an image in many ways! If you need any more modes in repo or I

TroJanzHEX 44 Nov 17, 2022
Image enhancing model for making a blurred image to be somehow clearer than before

This is a very small prject which helps in enhancing the images by taking a Input images. This project has many features like detcting the faces and enhaning the faces itself and also a feature which enhances the whole image

null 3 Dec 3, 2021
Nanosensor Image Processor (NanoImgPro), a python-based image analysis tool for dopamine nanosensors

NanoImgPro Nanosensor Image Processor (NanoImgPro), a python-based image analysis tool for dopamine nanosensors NanoImgPro.py contains the main class

null 1 Mar 2, 2022
A pure python implementation of the GIMP XCF image format. Use this to interact with GIMP image formats

Pure Python implementation of the GIMP image formats (.xcf projects as well as brushes, patterns, etc)

FHPyhtonUtils 8 Dec 30, 2022
Image-Viewer is a Windows image viewer based on Python 3.

Image-Viewer Hi! Image-Viewer is a Windows image viewer based on Python 3. Using You must download Image-Viewer.exe from the root of the repository. T

null 2 Apr 18, 2022
This app finds duplicate to near duplicate images by generating a hash value for each image stored with a specialized data structure called VP-Tree which makes searching an image on a dataset of 100Ks almost instantanious

Offline Reverse Image Search Overview This app finds duplicate to near duplicate images by generating a hash value for each image stored with a specia

null 53 Nov 15, 2022
Quickly 'anonymize' all people in an image. This script will put a black bar over all eye-pairs in an image

Face-Detacher Quickly 'anonymize' all people in an image. This script will put a black bar over all eye-pairs in an image This is a small python scrip

Don Cato 1 Oct 29, 2021
Fast Image Retrieval is an open source image retrieval framework

Fast Image Retrieval is an open source image retrieval framework release by Center of Image and Signal Processing Lab (CISiP Lab), Universiti Malaya. This framework implements most of the major binary hashing methods, together with both popular backbone networks and public datasets.

CISiP Lab 39 Nov 25, 2022
Fast Image Retrieval (FIRe) is an open source image retrieval project

Fast Image Retrieval (FIRe) is an open source image retrieval project release by Center of Image and Signal Processing Lab (CISiP Lab), Universiti Malaya. This project implements most of the major binary hashing methods to date, together with different popular backbone networks and public datasets.

CISiP Lab 39 Nov 25, 2022
A Python Script to convert Normal PNG Image to Apple iDOT PNG Image.

idot-png-encoder A Python Script to convert Normal PNG Image to Apple iDOT PNG Image (Multi-threaded Decoding PNG). Usage idotpngencoder.py -i <inputf

Lrdcq 2 Feb 17, 2022
Anaglyph 3D Converter - A python script that adds a 3D anaglyph style effect to an image using the Pillow image processing package.

Anaglyph 3D Converter - A python script that adds a 3D anaglyph style effect to an image using the Pillow image processing package.

Kizdude 2 Jan 22, 2022
Pyconvert is a python script that you can use to convert image files to another image format! (eg. PNG to ICO)

Pyconvert is a python script that you can use to convert image files to another image format! (eg. PNG to ICO)

null 1 Jan 16, 2022
Simple Python package to convert an image into a quantized image using a customizable palette

Simple Python package to convert an image into a quantized image using a customizable palette. Resulting image can be displayed by ePaper displays such as Waveshare displays.

Luis Obis 3 Apr 13, 2022
Fast batch image resizer and rotator for JPEG and PNG images.

imgp is a command line image resizer and rotator for JPEG and PNG images.

Terminator X 921 Dec 25, 2022
Snowfall - helpful image handling utils - abstracts various file and opencv and pil features into result oriented functions

snowfall helpful image handling utils - abstracts various file and opencv and pil features into result oriented functions usage examples: from image_h

Less Wright 2 Jan 9, 2022