Skip to content

Perceptual Image Hashing (pHash)

PrimeStamp's perceptual hashing module generates fingerprints for images that are robust to minor visual modifications such as resizing, compression, and color shifts while still detecting meaningful content changes. This allows you to stamp and verify images even after routine transformations.

Supported Methods

Method Algorithm Best For
phash DCT-based perceptual hash General-purpose image similarity
dhash Horizontal gradient difference hash Fast comparison, rotation-sensitive
ahash Average-based hash Baseline comparison, very fast

Quick Start

from primestamp.fingerprint.phash import PHashGenerator, HashMethod

gen = PHashGenerator(hash_size=8, method=HashMethod.PHASH)

# Generate fingerprints from image bytes
with open("photo_original.jpg", "rb") as f:
    fp1 = gen.generate_from_bytes(f.read())

with open("photo_resized.jpg", "rb") as f:
    fp2 = gen.generate_from_bytes(f.read())

# Compare
print(f"Hamming distance: {fp1.hamming_distance(fp2)}")
print(f"Similarity: {fp1.similarity(fp2):.4f}")
print(f"Visually similar: {fp1.is_similar(fp2, threshold=10)}")

Configuration

Parameter Type Default Description
hash_size int 8 Dimension of the hash grid. Produces hash_size * hash_size bits.
method HashMethod PHASH Hash method: PHASH, DHASH, or AHASH.
highfreq_factor int 4 Scaling factor for DCT input size (pHash only).

Hash Size and Precision

  • hash_size=8 produces a 64-bit fingerprint -- good for most use cases.
  • hash_size=16 produces a 256-bit fingerprint -- higher discrimination for large image databases.

Batch Comparison

Compute a pairwise distance matrix for a set of images.

gen = PHashGenerator(hash_size=8)

fingerprints = []
for path in image_paths:
    with open(path, "rb") as f:
        fingerprints.append(gen.generate_from_bytes(f.read()))

# NxN distance matrix
matrix = gen.batch_compare(fingerprints)
for i, row in enumerate(matrix):
    print(f"Image {i}: {row}")

Similarity Thresholds

Distance (64-bit) Interpretation
0 Identical or near-identical images
1--10 Visually similar (resized, recompressed, minor edits)
11--20 Some visual similarity, likely different images
> 20 Unrelated images

Dependencies

The module uses Pillow for image processing when available. If Pillow is not installed, a deterministic hash-based fallback is used.

pip install Pillow  # recommended for production use

Serialization

data = fp1.to_dict()
# {"value_hex": "a1b2c3...", "hash_bits": 64, "method": "phash", ...}

from primestamp.fingerprint.phash import PHashFingerprint
fp_restored = PHashFingerprint.from_dict(data)

Factory Function

from primestamp.fingerprint.phash import create_phash_generator

gen = create_phash_generator(hash_size=16, method="dhash")

Choosing a Method

  • Use pHash (DCT) for the most robust general-purpose similarity detection.
  • Use dHash for fast screening when rotation invariance is not needed.
  • Use aHash as a quick baseline or pre-filter before more expensive comparisons.