Skip to main content

GraDupe Icon
GraDupe

Sobel Gradient Image Deduplication

Usage

Get the CLI tool with pip install -U gradupe, or retrieve from PyPI manually. It is recommended to run the CLI with admin privilege.

gradupe init initializes cache in the current directory for long-term management.
gradupe scan scans the current directory for duplicates, utilizing cache if available.

For further information and options, refer to gradupe and gradupe [command] --help. Cache is stored in the .gradupe SQLite database in the current directory if enabled.

Motive

Classical algorithms based on image hashes can be inaccurate. Innovative ones based on RNNs can be inefficient. As the demand for image storage increases rapidly over the decade, we need a prompt solution that combines the benefits of both.

At one point, Sobel gradients occurred to me as a decent fingerprint for an image. Similar to finite differences and derivatives, two distinct images bear the same gradient only if they differ by a constant. By reading an image in grayscale, we obtain a 2D matrix suitable for Sobel operators.

Images of different dimensions are downscaled into a square grid. Although convolutions are blazingly fast on modern hardware, this is done to unify dimensions and speed up diffing. After downscaling, there remains a sufficient amount of informative bits for diffing in the next step.

Sobel operators are traditionally used for edge detection, but their nature lies in differentiating an image. Computing the Sobel gradient of an image in both the x and y directions yields two matrices, which we flatten and concatenate into a contiguous array.

The gradients are thresholded into bitmasks since Hamming distance can be optimized using SIMD XOR instructions, making it magnitudes faster than Euclidean norm. By mapping sub-indices of pairs into combinatorial indices, a densely packed array can be used as a distance matrix, saving memory and enabling parallel computation.

The single flat distance array can be thresholded into a boolean mask with SIMD instructions. All that remains is to compress the image combinations with the mask (combinatorial indexing ensures correct correspondence), resulting in a list of duplicate pairs which is then merged into groups via union find.

Credits

Library
OpenCV, NumPy, Numba

Cache
SQLite

CLI
Typer, Rich

Metadata

Release files for gradupe 3.0.5

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

Source distribution (sdist)

Source distribution for gradupe 3.0.5
File Size Uploaded
gradupe-3.0.5.tar.gz 6.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gradupe 3.0.5
File Interpreter ABI Platform
gradupe-3.0.5-py3-none-any.whl Python 3 none any Details

Total release size: 13.1 kB

Release files / gradupe-3.0.5.tar.gz

Download URL gradupe-3.0.5.tar.gz
Size 6.0 kB
Tags Source
SHA-256 checksum
How to use checksums
48c9f813ac7fde5feb26f72bb855e5df305910cad35996d0675ab85d66f79c68
BLAKE2b-256 checksum
How to use checksums
e351fd1dd7de168622367c31514ac67290cceb2de219534e57ed4b3e451f7748
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 18, 2026.

Transparency log

Release files / gradupe-3.0.5-py3-none-any.whl

Download URL gradupe-3.0.5-py3-none-any.whl
Size 7.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
899ca3f524feadd11d5e1bb4b06366f6b9e3ceaa7259506c99e43c3d10fe6c37
BLAKE2b-256 checksum
How to use checksums
55ca60979effb5f834353bbb01c71013ca8eec1293c8b79c9c70ad490a899031
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Jan 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

3.0.5 This release

2 release files

3.0.4

2 release files

3.0.3

2 release files

3.0.2

2 release files

3.0.1

2 release files

3.0.0

2 release files

2.2.9

2 release files

2.2.8

2 release files

2.2.3

2 release files

2.2.2

2 release files

2.2.1

2 release files

2.1.1

2 release files

2.1.0

2 release files

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