pHash - the open source perceptual hash library
pHash is a C++ library for computing perceptual hashes of images, video, audio, and text. Unlike cryptographic hashes (which change completely with a single bit flip), perceptual hashes change gradually as the input changes — two files that look or sound the same to a human produce hash values that are close to each other in Hamming distance, even after lossy re-encoding, resizing, mild noise, or other content-preserving transformations.
This makes pHash suitable for:
| Function | What it hashes | Output | Robust to |
|---|---|---|---|
ph_dct_imagehash |
Image (DCT) | 64-bit ulong64 |
Resize, compression, mild brightness/contrast |
ph_image_digest / ph_compare_images |
Image (Radon transform + DCT, "Radish") | 40-byte digest + cross-correlation | Rotation, resize |
ph_mh_imagehash |
Image (Marr-Hildreth wavelet) | 72-byte (576-bit) | Resize, slight crop, JPEG noise |
ph_dct_videohash |
Video (keyframe DCT hashes + LCS) | array of 64-bit hashes | Re-encoding, frame-rate change |
ph_audiohash |
Audio (Bark-scale spectral, Haitsma-Kalker style) | array of 32-bit frames | Re-encoding, mild EQ |
ph_texthash |
Text (k-gram winnowing) | array of (hash, offset) |
Insertion, deletion, edits |
Distances are computed with companion functions: ph_hamming_distance,
ph_hammingdistance2, ph_crosscorr, ph_dct_videohash_dist, and
ph_audio_distance_ber for the appropriate hash family. See
src/pHash.h and src/audiophash.h
for the full API.
git clone https://github.com/aetilius/pHash.git
cd pHash
mkdir build && cd build
cmake -DPHASH_EXAMPLES=ON -DWITH_AUDIO_HASH=ON -DWITH_VIDEO_HASH=ON ..
make -j
sudo make installThis produces libpHash.so (or .dylib on macOS) plus a set of
demonstration binaries in build/Release/:
TestDCT # ph_dct_imagehash on two directories of images
TestRadish # ph_image_digest (radon-based) on one image
TestMH # ph_mh_imagehash distance between two images
TestAudio # ph_audiohash + ph_audio_distance_ber on two audio files
TestVideoHash # ph_dct_videohash on two video files#include
#include "pHash.h"
int main(int argc, char **argv) {
if (argc Hamming distance %d / 64\n",
(unsigned long long)hashA,
(unsigned long long)hashB,
distance);
return 0;
}Build with:
c++ -std=c++14 -O2 example.cpp -lpHash -lpng -ljpeg -ltiff -lz -o exampleRule of thumb for the DCT image hash: a Hamming distance of 0 means
the images are essentially identical; ≤ 10 means very similar; ≥ 20
typically means unrelated. Tune the threshold against your own data.
#include
#include "audiophash.h"
int main(int argc, char **argv) {
if (argc best) best = C[i];
std::printf("confidence: %.3f (1.0 = identical, 0.5 = unrelated)\n", best);
free(a); free(b); free(ha); free(hb); free(C);
return 0;
}| Component | Required when | Debian/Ubuntu | macOS (Homebrew) |
|---|---|---|---|
| Image hash | Always (HAVE_IMAGE_HASH=ON by default) | libpng-dev libjpeg-dev libtiff-dev |
libpng libtiff libjpeg |
| Video hash | -DWITH_VIDEO_HASH=ON |
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev |
ffmpeg |
| Audio hash | -DWITH_AUDIO_HASH=ON |
libsndfile1-dev libsamplerate0-dev libmpg123-dev |
libsndfile libsamplerate mpg123 |
| HEIF/HEIC/AVIF | -DWITH_HEIF=ON |
libheif-dev |
libheif |
| Threads | Always | pthreads from the standard libc | — (built-in) |
Note: pHash bundles CImg in third-party/CImg/ — no separate install needed.
FFmpeg 5, 6, 7, and 8 are all supported.
| CMake option | Default | Purpose |
|---|---|---|
PHASH_DYNAMIC |
ON |
Build the shared library |
PHASH_STATIC |
OFF |
Build the static library |
WITH_AUDIO_HASH |
OFF |
Compile audiophash.cpp and the audio hash API |
WITH_VIDEO_HASH |
OFF |
Compile cimgffmpeg.cpp and the video hash API |
WITH_HEIF |
OFF |
Decode .heic / .heif / .avif via libheif (issue #18) |
PHASH_EXAMPLES |
OFF |
Build the TestDCT / TestRadish / etc. demos |
PHASH_BINDINGS |
OFF |
Build language bindings (Java/C#/PHP) |
Example: image hash only, no examples:
cmake ..Everything on:
cmake -DWITH_AUDIO_HASH=ON -DWITH_VIDEO_HASH=ON \
-DPHASH_EXAMPLES=ON -DPHASH_BINDINGS=ON ..The bindings/ directory ships wrappers for:
bindings/java/) — JNI bindings, see bindings/java/README for the JDK requirements.bindings/c_sharp/) — P/Invoke wrapper for the C ABI.bindings/php/) — built against the PHP extension API.Enable with -DPHASH_BINDINGS=ON.
For the academic context behind each method, see the papers cited in
src/pHash.h header comments and in the
ChangeLog.
…Project home:
GNU General Public License v3 or later. See COPYING for
the full text.
No open issues yet, or sync has not completed.