Registry / ai-ml / imagehash

imagehash

JSON →
library4.3.2pypypi✓ verified 23d ago

ImageHash is a Python library that provides tools for generating perceptual hash values for images. These hashes can be used to compare images based on their visual content, making it useful for finding similar or duplicate images. It supports various hashing algorithms like aHash, pHash, dHash, wHash, colorhash, and crop-resistant hashing. The current version is 4.3.2, and it receives updates periodically to add features, improve performance, and address bugs. [1, 3, 8]

pip install Pillow imagehash
INSTALL
IMPORT
SIG · IMAGEHASH
I
imagehash
ai-mlpythonv4.3.2
Install
8.3s avg
Import
66ms
Disk
259MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v4.3.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.068s · 259.3MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 8.3s · import 0.064s · 251MB
259MB installed
● package 259MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Image
from PIL import Image
imagehash
import imagehash

This quickstart demonstrates how to load an image using Pillow, generate an average perceptual hash using `imagehash.average_hash`, and compare it to another hash by calculating their Hamming distance. A smaller difference typically indicates greater visual similarity. [1, 3, 8, 14]

from PIL import Image import imagehash import os # Create a dummy image for demonstration if not available dummy_image_path = 'dummy_image.png' if not os.path.exists(dummy_image_path): try: from PIL import ImageDraw img = Image.new('RGB', (200, 200), color = 'red') d = ImageDraw.Draw(img) d.text((10,10), "Hello", fill=(0,0,0)) img.save(dummy_image_path) print(f"Created dummy image: {dummy_image_path}") except ImportError: print("Pillow is needed to create a dummy image. Please install it.") exit() try: # Load an image image = Image.open(dummy_image_path) # Generate a perceptual hash (e.g., average hash) hash_value = imagehash.average_hash(image) print(f"Hash for '{dummy_image_path}': {hash_value}") # You can also generate other types of hashes: # phash_value = imagehash.phash(image) # dhash_value = imagehash.dhash(image) # whash_value = imagehash.whash(image) # colorhash_value = imagehash.colorhash(image) # To compare with another image: # For demonstration, let's pretend to load a slightly different image # In a real scenario, this would be another actual image file slightly_different_image = Image.new('RGB', (200, 200), color = 'red') d = ImageDraw.Draw(slightly_different_image) d.text((15,15), "Hello", fill=(0,0,0)) # slight shift other_hash_value = imagehash.average_hash(slightly_different_image) print(f"Hash for a slightly different image: {other_hash_value}") # Calculate the Hamming distance (difference) between hashes difference = hash_value - other_hash_value print(f"Difference between hashes: {difference}") # A smaller difference indicates greater similarity if difference < 5: print("The images are considered similar (difference < 5).") else: print("The images are considered different (difference >= 5).") except FileNotFoundError: print(f"Error: Image file not found at {dummy_image_path}") except Exception as e: print(f"An error occurred: {e}")
Debug
Known issues
breakingVersion 4.0 introduced a change in the binary to hex implementation for hashes, breaking compatibility with hashes generated by previous versions. [3, 6]
fix
To convert hashes from the old encoding to the new format, use the `imagehash.old_hex_to_hash` function.
affects: >=4.0
breakingVersion 3.0 fixed a bug in the `dhash` algorithm where it computed pixel differences vertically instead of horizontally. The corrected `dhash` behavior now follows the standard. [3, 6, 16]
fix
If you relied on the previous (buggy) vertical difference calculation, use `imagehash.dhash_vertical` which retains the old behavior. Otherwise, `dhash` now works as intended.
affects: >=3.0
gotchaImageHash functions expect a `PIL.Image.Image` object as input. Passing a NumPy array directly (e.g., from OpenCV) will result in an `AttributeError` because NumPy arrays do not have `convert` or `resize` methods expected by the library. [19]
fix
Convert NumPy arrays to PIL Image objects before passing them to ImageHash functions using `Image.fromarray(numpy_array)`.
affects: All
gotchaWhen loading images from URLs using libraries like `requests`, directly passing `resp.raw` to `Image.open()` can fail if the URL does not return raw image bytes (e.g., an HTML error page instead of an image). [21]
fix
Always verify the `requests` response's status code (`resp.status_code`) and content type before attempting to open it as an image. You might also need to read `resp.content` into a `BytesIO` object for `Image.open()`.
affects: All
gotchaDetermining an appropriate 'similarity threshold' (Hamming distance) for comparing hashes is empirical and highly dependent on the use case. A smaller difference indicates more similarity. Common recommendations range from 1 to 10 for 'similar' images. [1, 14]
fix
Experiment with different threshold values on your specific dataset to find what best defines 'similar' for your application. There's no one-size-fits-all value.
affects: All
gotchaSignificant image transformations like extensive cropping, rotations beyond 15 degrees, or substantial color adjustments can drastically alter perceptual hashes, potentially making perceptually similar images appear completely different. [14, 22]
fix
For robust matching against such transformations, consider preprocessing images to normalize them (e.g., consistent sizing, minor rotations corrected) or use more advanced techniques like crop-resistant hashing if available and suitable for your specific deformation types.
affects: All
Upgrade
Version history
4.3.2latest on PyPI · released Feb 1, 2025
Audit
Dependencies
PillowrequiredRequired for image loading and manipulation. ImageHash operates on PIL/Pillow Image objects. [1, 2, 3, 5]
numpyrequiredRequired for numerical operations underlying various hashing algorithms. [2, 3, 5]
scipyrequiredRequired for `fftpack` (used by pHash) and other scientific computing functions. [2, 3, 5]
PyWaveletsrequiredRequired specifically for the Wavelet Hashing (whash) algorithm. [5]
Agent activity
13 hits · last 30 days
node
12
Resources