Perceptual hashes explained: PDQ, pHash and dHash
A plain, step-by-step look at how three common perceptual hashes turn a picture into a few dozen bytes, and how two of those fingerprints are compared.
A normal file hash answers one question: are these two files exactly the same? Change one byte and the answer is no. That is useless when you want to know whether two pictures look the same, because resizing, re-saving as JPEG or converting to PNG changes almost every byte while the picture stays the same to your eye.
Perceptual hashes answer the second question. They turn an image into a short fingerprint, usually 64 or 256 bits, computed from what the picture looks like rather than from its bytes. Similar-looking pictures get similar fingerprints. This guide walks through three widely used ones, dHash, pHash and Meta's PDQ, step by step, and then explains how two fingerprints are compared.
Where perceptual hashes are used
- Near-duplicate search. Finding the same photo at different sizes or qualities in a large collection, without comparing every pixel of every pair.
- Photo libraries. Grouping burst shots and re-saved copies, or flagging that you already imported a picture.
- Platform matching. Large platforms hash uploads and compare them against lists of known content. When Meta open-sourced PDQ (photos) and TMK+PDQF (videos) in 2019, it described them as tools for finding identical and nearly identical copies of harmful content, such as child exploitation imagery and terrorist propaganda, and said the resulting hashes are shared with industry partners through the Global Internet Forum to Counter Terrorism [1].
That last use is why perceptual hashing matters beyond photo apps: a hash can be shared and checked without anyone passing around the original image [1].
dHash: the difference hash
dHash is the simplest of the three. Neal Krawetz described it in 2013 as a fast, accurate alternative to the average hash [4]:
- Shrink the image to 9 × 8 pixels, ignoring the aspect ratio.
- Drop colour, keeping only brightness (greyscale).
- Compare neighbours. In each row, compare every pixel with the one to its right. Nine pixels give eight comparisons, and eight rows give 64 results.
- Write the bits. Each comparison becomes a 1 or a 0 depending on which neighbour is brighter, scanned left to right, top to bottom. The result is a 64-bit number, often written as 16 hex characters.
dHash records the direction of brightness changes across the picture, which is why it survives re-saving and brightness shifts well. Krawetz found it nearly as fast as the average hash with very few false positives, and suggested using it as a quick first filter before a more careful check [4].
pHash: the DCT hash
pHash looks at frequencies instead of neighbouring pixels. The version Krawetz describes works like this [5]:
- Shrink to 32 × 32 pixels and convert to greyscale.
- Run a discrete cosine transform (DCT), the same kind of transform JPEG uses. It splits the image into patterns of coarse and fine detail.
- Keep the top-left 8 × 8 block of the result. These are the lowest frequencies: the broad structure of the picture, not its fine texture.
- Compute an average of those 64 values, leaving out the very first one (the DC term, the overall brightness), because it can be far from the others and skew the average.
- Write the bits. Each value above the average becomes 1, the rest 0. That gives 64 bits.
Some implementations use the median instead of the mean in step 4; a reader comment on the article notes that the pHash library itself does [5]. Because pHash keeps only the broad structure, it tolerates small edits well. In Krawetz's test it was the most accurate of the hashes he tried, and also the slowest [4].
PDQ: Meta's 256-bit hash
PDQ is Meta's open-source image hash. Meta says it was inspired by pHash but built from the ground up as a distinct algorithm [1]. Its documentation lists these steps [2]:
- Convert to luminance (a weighted mix of red, green and blue) rather than a plain greyscale.
- Downsample to 64 × 64 using two-pass Jarosz filters (tent convolutions), so every output pixel is a weighted average of its whole block rather than a single picked pixel. For large photos, Meta recommends resizing to about 512 × 512 first for speed.
- Score quality. From the 64 × 64 image, sum the horizontal and vertical gradients and rescale to 0–100. Solid or nearly featureless images score near 0.
- Run a 2D DCT and keep a 16 × 16 block of low-to-medium frequencies.
- Threshold at the median. Each of the 256 values becomes 1 if it is above the median, otherwise 0.
The result is 256 bits, which Meta calls "appropriate for web-scale" [2]. Because the threshold is the median, a normal PDQ hash always has 128 ones and 128 zeros [2]. Meta's README recommends discarding hashes with a quality score of 49 or below, because featureless images produce unreliable fingerprints [3]. PDQ can also compute, at little extra cost, the hashes the picture would have if it were rotated by 90-degree steps or mirrored, so a matching system can check those orientations too [2].
How similarity is measured: Hamming distance
All three hashes are compared the same way: line up the two bit strings and count the positions where they differ. That count is the Hamming distance.
| Hash | Bits | Identical | Typical "same picture" range | Unrelated pictures |
|---|---|---|---|---|
| dHash | 64 | 0 | 1–10 suggested as a likely variation [4] | above 10 [4] |
| pHash | 64 | 0 | around 5 or less, 10+ probably different (guidance given for the related average hash) [5] | 10 and up [5] |
| PDQ | 256 | 0 | 31 or less as a starting threshold [3]; Meta has also found 30, 20 or less works well on its evaluation data [2] | averages about 128, roughly 90–160 [2] |
These numbers are starting points, not laws. Meta's README says to tune the threshold on your own data [3], and small differences between implementations (how an image is decoded and resized) can shift a hash by a few bits [3][5].
The trade-off is always the same: a looser threshold catches more real copies but also more unrelated look-alikes; a tighter one does the reverse.
Why a crop or warp changes the hash
Each of these hashes summarises the whole frame on a fixed grid: 9 × 8 cells for dHash, 32 × 32 for pHash, 64 × 64 for PDQ. That design is what makes them robust to resizing and re-compression, because those changes leave each cell's average brightness roughly where it was.
Geometry is different:
- A crop removes part of the picture and stretches what is left over the same grid, so different content lands in each cell. Meta's documentation says plainly that PDQ, like many global-descriptor algorithms, "does not do well at pairing photos one of which is a crop of another" [2].
- A rotation by a small angle, or a warp, shifts edges across cell boundaries. The low-frequency summary moves with them. Rotations by 90-degree steps and mirror images are a special case PDQ handles by computing all eight orientations [2].
- Re-encoding, format changes and light watermarks mostly leave the hash alone. Meta reports PDQ does well with JPEG-to-PNG conversion and JPEG quality reduction and tolerates light watermarking or logo placement [2].
Original
0 / 64
Re-saved as JPEG
—
Warped, cropped, turned
—
Computing the hashes in your browser.
Meta also places PDQ in a family of "syntactic" hashes, alongside dHash, aHash and pHash, built for content shared without deliberate tampering; detecting heavily altered copies is the job of semantic, machine-learning methods [2]. In other words, a perceptual hash is one layer of a matching system, not the whole system. Researchers have tested PDQ against transformations seen in real law-enforcement case data [6].
Where FluidGhost fits
FluidGhost makes fresh copies of photos and videos, and it measures what it changes. Two places on our site let you see perceptual hashes at work:
- The homepage pipeline runs the default one-click edits (warp, crop, a slight turn and grain) on a sample photo in your browser, then computes a 64-bit dHash of the original and of the copy and shows both grids and the Hamming distance between them.
- The free check has a Compare to original option: upload two pictures and it reports the PDQ distance between them, next to Meta's suggested match radius of 31. Those two files go to our server for the scan, are measured and are not stored, up to 25 MB each.
If you just want to know what a perceptual hash says about two of your own pictures, the free check is the quickest way to find out.
FAQ
What is the difference between a perceptual hash and a cryptographic hash?
A cryptographic hash such as SHA-256 changes completely when a single bit of the file changes, so it only finds exact copies. A perceptual hash is computed from what the picture looks like, so a resized or re-saved copy of the same photo gets the same or a very similar hash.
How is the similarity of two perceptual hashes measured?
With Hamming distance: the number of bit positions where the two hashes differ. 0 means identical fingerprints. For a 64-bit dHash, the author of the method treats 1 to 10 as a likely variation of the same picture; for 256-bit PDQ, Meta suggests 31 or less as a starting match threshold.
Is PDQ better than pHash?
They are related: Meta says PDQ was inspired by pHash but built as its own algorithm. PDQ produces 256 bits instead of 64, uses a smoother downsampling filter, and adds a quality score that flags featureless images, which Meta describes as more appropriate for web-scale matching.
Why does cropping a photo change its perceptual hash?
dHash, pHash and PDQ all summarise the whole frame on a fixed grid. A crop moves content into different grid cells and removes some of it, so the summary changes. Meta's own PDQ documentation says it does not do well at pairing a photo with a crop of itself.
Where can I compare two images with PDQ for free?
The free check at ghost.fluidvip.com/inspect.html has a Compare to original option: upload two pictures and it reports the PDQ distance between them. The files are sent to the server for that scan, measured and not stored.
Sources
- Meta (Facebook), Open-Sourcing Photo- and Video-Matching Technology to Make the Internet Safer (2019). ↩
- Meta ThreatExchange, The TMK+PDQF Video-Hashing Algorithm and the PDQ Image Similarity Algorithm (hashing.pdf). ↩
- Meta ThreatExchange, PDQ README. ↩
- Neal Krawetz, Kind of Like That (Hacker Factor blog, dHash). ↩
- Neal Krawetz, Looks Like It (Hacker Factor blog, aHash and pHash). ↩
- Dalins, Wilson, Boudry, PDQ & TMK + PDQF: A Test Drive of Facebook's Perceptual Hashing Algorithms (arXiv:1912.07745). ↩