Skip to main content

imret

imret is a C++ image retrieval library. Given a query image, it finds the closest matching image from a previously ingested collection. It uses ORB binary feature descriptors and a FAISS inverted-file index (IVF) for approximate nearest-neighbour search, with a two-tier search strategy and per-keypoint voting to produce a confidence score.

How it works

  1. Feature extraction — ORB extracts up to max_features keypoints per image, each producing a 256-bit (32-byte) binary descriptor.
  2. Indexing — build() runs k-means on all accumulated descriptors to partition them into Voronoi cells (IndexBinaryIVF). The number of cells scales with the total feature count.
  3. Search — A query image is described with ORB. Each descriptor votes for the image it matches (filtered by Hamming distance). Tier 1 searches fast_cells cells; if the top vote fraction falls below confidence_threshold, Tier 2 searches deep_cells cells.
  4. Result — The image with the most votes wins, returning its label and a confidence value in [0, 1].

Dependencies

  • CMake >= 3.15
  • C++17 compiler
  • OpenCV 4.x
  • FAISS
  • OpenMP (macOS: brew install libomp)

Building (C++)

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel

This produces build/imret_cli and build/libimret_core.a.

Running the tests

C++ tests:

ctest --test-dir build --output-on-failure

Python binding tests (requires imret installed and pytest):

pip install pytest
python -m pytest bindings/python/tests/ -v

C++ API

Include vault.hpp and link against libimret_core.a and its dependencies (OpenCV, faiss, omp).

OrbConfig

#include "imret.hpp"

OrbConfig cfg;
cfg.max_features         = 500;   // ORB keypoints per image
cfg.resize_dim           = 0;     // 0 = no resize; >0 = resize to (N x N) before extraction
cfg.fast_cells           = 8;     // IVF cells probed in tier-1 search
cfg.deep_cells           = 64;    // IVF cells probed in tier-2 fallback
cfg.max_hamming_distance = 45;    // maximum Hamming distance for a keypoint to count as a match
cfg.confidence_threshold = 0.15f; // confidence below this triggers the tier-2 fallback
#include "vault.hpp"

OrbConfig cfg;
Vault vault(cfg);

// Ingest images (grayscale cv::Mat)
vault.add(image_a, "label_a");
vault.add(image_b, "label_b");

// Bulk ingest with OpenMP parallelism — preferred for large collections
vault.add_batch({image_a, image_b, image_c}, {"label_a", "label_b", "label_c"});

// Build the index — required before searching
vault.build();

// Query
MatchResult result = vault.search(query_image);
// result.label        — label of the best match, or "Unknown"
// result.confidence   — fraction of keypoints that voted for the winner [0, 1]
// result.fallback_used — true if the tier-2 search was triggered

add() and add_batch() can be called after build(). Call build() again afterwards to retrain the index over all accumulated data.

Stats

Vault::Stats s = vault.stats();
// s.n_images    — number of unique images in the vault
// s.n_features  — total feature vectors accumulated
// s.nlist       — number of IVF clusters (0 if not yet built)
// s.is_built    — whether the index has been trained

All fields are O(1) reads from in-memory structures.

Persistence

vault.save("/path/to/prefix");   // writes prefix.faiss and prefix.meta
vault.load("/path/to/prefix");   // restores the index and label map; no rebuild needed

The .meta file stores the OrbConfig alongside the label map, so a loaded vault always uses the config it was originally built with.

Python

Install

pip install imret

Pre-built binary wheels are available for Linux x86_64 and macOS arm64, covering Python 3.9–3.13. Google Colab is supported without any additional setup.

The Linux wheel needs an x86-64-v2 CPU (SSE4.2 + POPCNT, any x86 CPU from roughly 2009 on). Its bundled FAISS is built with runtime SIMD dispatch, so AVX2/AVX-512 are used when present. 0.1.1's Linux wheel shipped a generic FAISS without hardware popcount, which made search ~20x slower; upgrade to 0.1.4 or later.

Usage

import cv2
import imret

cfg = imret.OrbConfig()
cfg.max_features         = 500
cfg.resize_dim           = 800   # resize images to 800x800 before extraction
cfg.fast_cells           = 8
cfg.deep_cells           = 64
cfg.max_hamming_distance = 45
cfg.confidence_threshold = 0.15

vault = imret.Vault(cfg)

# Ingest — images must be grayscale uint8 numpy arrays
gray = cv2.imread("painting.jpg", cv2.IMREAD_GRAYSCALE)
vault.add(gray, "my_label")

# Bulk ingest (parallel via OpenMP)
vault.add_batch([gray_a, gray_b, gray_c], ["label_a", "label_b", "label_c"])

# Build the index
vault.build()

# Search
result = vault.search(query_gray)
print(result.label, result.confidence, result.fallback_used)

# Vault stats (all O(1))
s = vault.stats()
print(s["n_images"])    # images in the vault
print(s["n_features"])  # total ORB descriptor vectors stored
print(s["nlist"])       # IVF Voronoi clusters (0 before build)
print(s["is_built"])    # whether the index has been trained

# Save and load
vault.save("/tmp/my_vault")
vault2 = imret.Vault.load_from_disk("/tmp/my_vault", cfg)

add() expects a 2-D numpy.ndarray with dtype uint8. If resize_dim > 0, resizing is applied internally before extraction.

Building from source

Requirements: Python >= 3.9, pybind11, scikit-build-core, OpenCV, FAISS, OpenMP.

On macOS, install OpenMP first:

brew install libomp

Then build and install the Python package:

cd bindings/python
pip install scikit-build-core pybind11
pip install .

The CMakeLists detects the Homebrew libomp prefix automatically.

CLI

./build/imret_cli <vault_prefix> <path_to_image>

Loads the vault at <vault_prefix>.faiss / <vault_prefix>.meta, searches with the given image, and prints the matched label to stdout. Exits with code 1 and prints UNKNOWN if confidence is below confidence_threshold.

OrbConfig reference

Field Default Description
max_features 500 Maximum ORB keypoints extracted per image
resize_dim 0 If > 0, resize each image to resize_dim x resize_dim before extraction
fast_cells 8 IVF cells probed during tier-1 search
deep_cells 64 IVF cells probed during tier-2 fallback
max_hamming_distance 45 Keypoints with Hamming distance above this threshold are excluded from voting
confidence_threshold 0.15 Vote fraction below this triggers the tier-2 fallback

Benchmarks

Generated by benchmark.py on macOS arm64, max_features=500, 20 queries per size.

imret and imret-batch differ only at ingest: the batch variant uses add_batch() which extracts ORB features in parallel via OpenMP, reducing build time by up to 37% at large N. Search latency is identical.

Speed comparison — synthetic images, no transform

All methods score 100% accuracy on structurally distinct synthetic images, so this measures speed only.

Search latency p50 (ms)

N imret imret-batch bfmatcher imagehash
100 3.19 3.11 8.60 0.20
500 3.26 3.27 39.97 0.52
1,000 3.30 3.33 85.14 0.90
2,000 3.36 3.33 166.58 1.67

Build time (s)

N imret imret-batch bfmatcher imagehash
100 1.11 0.98 0.11 0.44
500 15.64 15.12 0.56 0.07
1,000 31.19 30.18 1.11 0.17
2,000 62.20 60.27 2.25 0.33

imret search latency is nearly flat (3.19ms → 3.36ms across 20× more images). BFMatcher grows linearly. Build time is higher because imret trains a FAISS IVF index upfront — a one-time cost at index time.

Accuracy comparison — WikiArt paintings, wall-photo transform

The wall transform adds a grey background border and light Gaussian blur, simulating a gallery photo. This is where the methods diverge. Perceptual hashing (imagehash) is designed for near-duplicate detection; adding a border shifts the global DCT hash enough to confuse it with unrelated paintings. imret's ORB keypoints are local to the painting interior and are unaffected.

Accuracy (%)

N imret imret-batch bfmatcher imagehash
100 100.0 100.0 100.0 15.0
500 100.0 100.0 100.0 15.0
1,000 100.0 100.0 100.0 10.0

Search latency p50 (ms)

N imret imret-batch bfmatcher imagehash
100 21.64 21.54 29.74 1.69
500 22.53 22.27 71.64 2.07
1,000 22.21 22.33 130.68 2.42

imagehash is fast but effectively random on real images under this transform (10–15% ≈ 1-in-10 chance). imret maintains 100% accuracy. BFMatcher matches imret accuracy but latency grows linearly.

To reproduce:

python benchmark.py --dataset wikiart --transform wall --sizes 100,500,1000 --plot
python benchmark.py --sizes 100,500,1000,2000 --plot   # synthetic speed comparison

Publishing a release

Wheels for Linux x86_64 and macOS arm64 are built automatically via GitHub Actions using cibuildwheel. To publish a new version to PyPI:

  1. Update version in pyproject.toml.
  2. Push a version tag:
    git tag v0.1.0
    git push origin v0.1.0
    
  3. The workflow builds wheels for all supported platforms and Python versions, then uploads to PyPI using trusted publishing (no API token required — configure the PyPI project to trust this repository's Actions environment named pypi).

Metadata

Release files for imret 0.1.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for imret 0.1.4
File Actions
imret-0.1.4-cp313-cp313-manylinux_2_39_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.39+ x86-64 Details for imret-0.1.4-cp313-cp313-manylinux_2_39_x86_64.whl
imret-0.1.4-cp313-cp313-macosx_15_0_arm64.whl CPython 3.13 CPython 3.13 macOS 15.0+ ARM64 Details for imret-0.1.4-cp313-cp313-macosx_15_0_arm64.whl
imret-0.1.4-cp312-cp312-manylinux_2_39_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.39+ x86-64 Details for imret-0.1.4-cp312-cp312-manylinux_2_39_x86_64.whl
imret-0.1.4-cp312-cp312-macosx_15_0_arm64.whl CPython 3.12 CPython 3.12 macOS 15.0+ ARM64 Details for imret-0.1.4-cp312-cp312-macosx_15_0_arm64.whl
imret-0.1.4-cp311-cp311-manylinux_2_39_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.39+ x86-64 Details for imret-0.1.4-cp311-cp311-manylinux_2_39_x86_64.whl
imret-0.1.4-cp311-cp311-macosx_15_0_arm64.whl CPython 3.11 CPython 3.11 macOS 15.0+ ARM64 Details for imret-0.1.4-cp311-cp311-macosx_15_0_arm64.whl
imret-0.1.4-cp310-cp310-manylinux_2_39_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.39+ x86-64 Details for imret-0.1.4-cp310-cp310-manylinux_2_39_x86_64.whl
imret-0.1.4-cp310-cp310-macosx_15_0_arm64.whl CPython 3.10 CPython 3.10 macOS 15.0+ ARM64 Details for imret-0.1.4-cp310-cp310-macosx_15_0_arm64.whl
imret-0.1.4-cp39-cp39-manylinux_2_39_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.39+ x86-64 Details for imret-0.1.4-cp39-cp39-manylinux_2_39_x86_64.whl
imret-0.1.4-cp39-cp39-macosx_15_0_arm64.whl CPython 3.9 CPython 3.9 macOS 15.0+ ARM64 Details for imret-0.1.4-cp39-cp39-macosx_15_0_arm64.whl

Total release size: 280.6 MB

Release files / imret-0.1.4-cp313-cp313-manylinux_2_39_x86_64.whl

Download URL imret-0.1.4-cp313-cp313-manylinux_2_39_x86_64.whl
Size 42.9 MB
Tags CPython 3.13 Linux glibc 2.39+ x86-64
SHA-256 checksum
How to use checksums
8beb5a74338ee44c6d6f3525917ac25db853efc414bfa47a2f133d7fa161e827
BLAKE2b-256 checksum
How to use checksums
1299e942bf91ee355759f2019df928e5b87cfa5605d1482472fb1ce33ee54853
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp313-cp313-macosx_15_0_arm64.whl

Download URL imret-0.1.4-cp313-cp313-macosx_15_0_arm64.whl
Size 13.2 MB
Tags CPython 3.13 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
f512a6d2a416272306e1392ca209923ac904a080701c20f8235ce55f4772ce8c
BLAKE2b-256 checksum
How to use checksums
a35a614e6ca5b6ccdc407c689a78c43633d6bc16ac6babc0b9908eb674cd27ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp312-cp312-manylinux_2_39_x86_64.whl

Download URL imret-0.1.4-cp312-cp312-manylinux_2_39_x86_64.whl
Size 42.9 MB
Tags CPython 3.12 Linux glibc 2.39+ x86-64
SHA-256 checksum
How to use checksums
3288c49a8db3d4449fe0aa1e9a69cc1765fff3bb5a7f0d3f02efc57a551bd18b
BLAKE2b-256 checksum
How to use checksums
054a7b1274e45fb5cc64c3bfd4d8ab2c13789a23b2ad0070adc4db2bc1ea7172
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp312-cp312-macosx_15_0_arm64.whl

Download URL imret-0.1.4-cp312-cp312-macosx_15_0_arm64.whl
Size 13.2 MB
Tags CPython 3.12 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
85aefeab915a450530d4001fe042819e608360b19006c9684fcbfc1e05dc1f45
BLAKE2b-256 checksum
How to use checksums
557956afb4882ec2c1618f755ee586c8fe5bf9fd22a9d6c4dd853a2d9c6b28b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp311-cp311-manylinux_2_39_x86_64.whl

Download URL imret-0.1.4-cp311-cp311-manylinux_2_39_x86_64.whl
Size 42.9 MB
Tags CPython 3.11 Linux glibc 2.39+ x86-64
SHA-256 checksum
How to use checksums
2db21ba63e194f09f04e3af6d7cb622ff7c7a6844a3f8820fac7808ae189ca33
BLAKE2b-256 checksum
How to use checksums
26e69314c3f04a8aaacaffdcbc72f26cfbbdb20e7da42ee39d96f5e6894a43b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp311-cp311-macosx_15_0_arm64.whl

Download URL imret-0.1.4-cp311-cp311-macosx_15_0_arm64.whl
Size 13.2 MB
Tags CPython 3.11 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
0c9a2780912f6136a5d9e558e134f82c5e5645ef4f3b5ccb7e2a5c7d359ef261
BLAKE2b-256 checksum
How to use checksums
67c66498a6953ad1d617925ee46b6fa90134a7a39982c7de6ebdb3340dd0ecb1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp310-cp310-manylinux_2_39_x86_64.whl

Download URL imret-0.1.4-cp310-cp310-manylinux_2_39_x86_64.whl
Size 42.9 MB
Tags CPython 3.10 Linux glibc 2.39+ x86-64
SHA-256 checksum
How to use checksums
496d3c8a2143e6d143c63f21276e09d3d30b43934dc2adbbe3040c8f23920682
BLAKE2b-256 checksum
How to use checksums
f47801336d6f27015391c8fdea2476beb01acebf306d9cdbac04cb2b77070fb3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp310-cp310-macosx_15_0_arm64.whl

Download URL imret-0.1.4-cp310-cp310-macosx_15_0_arm64.whl
Size 13.2 MB
Tags CPython 3.10 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
cd5d4ee9f7aa0f1e6c01cc4aaad2242a82c86a0781ad8d36d41739f9d9bf7b86
BLAKE2b-256 checksum
How to use checksums
e76763f6500c5863e0703d4ee5ff50aea3da34b776d0de6d5cffa8fde6eb485a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp39-cp39-manylinux_2_39_x86_64.whl

Download URL imret-0.1.4-cp39-cp39-manylinux_2_39_x86_64.whl
Size 42.9 MB
Tags CPython 3.9 Linux glibc 2.39+ x86-64
SHA-256 checksum
How to use checksums
e313ad25bb377b331594aa2ad78a25be9e0ace3ab77ace1a2ce2b4301728509e
BLAKE2b-256 checksum
How to use checksums
eb780fcfad00e01c4cc3bfae0d593efd38786685eaae67292b393a4c6b089024
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / imret-0.1.4-cp39-cp39-macosx_15_0_arm64.whl

Download URL imret-0.1.4-cp39-cp39-macosx_15_0_arm64.whl
Size 13.2 MB
Tags CPython 3.9 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
e8cba8afae93d0a493792b0256e13d7b4eaf6c42776cde4efb6ea4425a86f1c0
BLAKE2b-256 checksum
How to use checksums
8c455e1f06ccc57778a958bf3cd4b4d2a7b4babfd29fcae19fb11b5fbe34f0b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Security for imret 0.1.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 10 files in this release have been uploaded with provenance metadata.

Select from 10 files

Attestation for imret-0.1.4-cp313-cp313-manylinux_2_39_x86_64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page