← Back to blog

pHash: The Frequency‑Domain Duplicate Finder for Edited Image Collections

Sakarto's pHash (Perceptual Hash) algorithm finds duplicate photos and videos using the same Discrete Cosine Transform as JPEG compression. Perfect for re‑compressed, watermarked, and lightly edited copies. Free, browser‑based, and 100% private.

Sakarto pHash duplicate finder interface showing frequency-domain grouping of edited images

When you save a JPEG at 90% quality, then again at 70%, the pixel values change. When you apply a mild colour grade, the pixel values change. When you add a watermark, the pixel values change. To algorithms that compare pixels directly—like aHash or dHash—these edited versions look like different images. The hash changes, and the duplicate is missed.

That’s where pHash (Perceptual Hash) comes in. Instead of comparing pixels, pHash analyses the frequency content of each image using a Discrete Cosine Transform—the same mathematical operation that underpins JPEG compression. It captures the low‑frequency “essence” of an image: the broad shapes, major contrasts, and dominant structural content. Re‑compression, mild colour grading, watermarking, and sharpening all affect high‑frequency detail while leaving the low‑frequency structure intact.

This makes pHash the most stable and reliable hash algorithm in Sakarto’s toolkit—the one you reach for when you need to find duplicates across different formats, quality levels, and minor edits.


What makes pHash different from aHash, dHash, BlockHash, and wHash?

All five algorithms produce a binary hash and compare using Hamming distance. But they capture fundamentally different properties:

AlgorithmEncodesSensitive toBest for
aHashPixel brightness vs. meanOverall brightness levelSpeed, exact copies
dHashDirection of brightness changeExposure, brightness shiftsExposure‑adjusted copies
BlockHashBlock‑averaged brightnessCompression artifactsNoisy, heavily compressed images
wHashWavelet‑based multi‑scale structureMulti‑scale structural editsSpeed/quality balance
pHashLow‑frequency DCT coefficientsRe‑compression, watermarking, mild editsAll‑round reliability, edited copies

The key insight: pHash uses the same mathematics as JPEG compression—the Discrete Cosine Transform—to extract the image’s low‑frequency “essence.” JPEG compression works by applying a DCT and discarding small high‑frequency coefficients. Re‑compressing a JPEG barely changes the low‑frequency coefficients that pHash reads, while it does affect the pixel values that aHash or dHash read. This is why pHash is so stable across re‑compression.


How the algorithm works: a deep dive

Let’s walk through exactly what happens when you scan a folder with pHash.

Step 1: Resize to 32×32 pixels

Each image is drawn onto a 32×32 canvas. This normalises all images to the same size and gives the DCT a square input of manageable dimensions.

Fast Mode (enabled by default for JPEGs): Instead of decoding the full image, Sakarto reads the embedded EXIF thumbnail (typically 160×120 pixels). This makes JPEG scans 5–10× faster with essentially identical hash results—the DCT operates on low‑frequency content that survives thumbnail compression intact.

Step 2: Convert to grayscale

Each of the 32×32 = 1024 pixels is converted to a single brightness value using the standard luminance formula: Gray = 0.299 × Red + 0.587 × Green + 0.114 × Blue

Colour information is discarded at this stage—pHash, like all other hash algorithms in Sakarto, is colour‑blind.

Step 3: Apply a 2D Discrete Cosine Transform

A separable 2D DCT is applied to the 32×32 grayscale matrix: first row‑wise, then column‑wise. This transforms the image from the spatial domain (pixel positions) into the frequency domain. The result is a 32×32 matrix of DCT coefficients where:

  • Top‑left region = low‑frequency (coarse structure) information
  • Bottom‑right region = high‑frequency (fine detail) information

The DCT is the same mathematical operation used in JPEG compression. When JPEG saves an image, it applies a DCT and discards small high‑frequency coefficients. So pHash is essentially reading the coefficients that JPEG works hardest to preserve.

Step 4: Extract the top‑left 8×8 low‑frequency coefficients

Only the top‑left 8×8 = 64 DCT coefficients are kept. These represent the lowest spatial frequencies in the image—the broad shapes, major contrasts, and dominant structural content. High‑frequency detail (fine textures, sharp edges, noise, watermarks, and compression artifacts) is discarded.

This is what makes pHash robust to:

  • Re‑compression: JPEG discards high frequencies; pHash ignores them anyway.
  • Mild colour grading: Colour changes affect luminance structure, but low‑frequency structure is largely preserved.
  • Watermarking: A watermark adds high‑frequency detail; pHash ignores high frequencies.
  • Sharpening: Sharpening amplifies high frequencies; pHash ignores them.

Step 5: Compute the mean of the 64 coefficients

The mean (average) of the 64 low‑frequency DCT coefficients is calculated. The DC component at position (0,0)—which represents the overall average brightness—is excluded from this calculation. This makes the hash invariant to global brightness differences (though pHash is less robust to brightness shifts than dHash, it is still reasonably stable).

Step 6: Produce the 64‑bit hash

Each of the 64 DCT coefficients is compared to the mean. If a coefficient is above the mean, its bit is 1; if at or below, its bit is 0. The resulting 64‑bit binary string is the pHash fingerprint—a compact encoding of the image’s dominant perceptual structure.

Step 7: Compare using Hamming distance

To compare two files, their 64‑bit hashes are XOR’d bit by bit. The number of positions where the bits differ is the Hamming distance. A distance of 0 means identical frequency patterns. The threshold slider controls the maximum Hamming distance allowed for two files to be grouped as duplicates. Lower = stricter.

Step 8: Aspect‑ratio pre‑check and video processing

Before comparing hashes, Sakarto checks whether the two files have similar aspect ratios—pairs differing by more than 10% are skipped. For videos, 3 frames are extracted at 1.5‑second intervals, each hashed separately, and the 3 hashes are combined by majority vote to produce a single representative hash.


What pHash finds well

Type of duplicateHow well it worksWhy
Exact byte‑for‑byte copies✅ ExcellentThe hash will be identical.
Same photo at different resolutions✅ ExcellentResizing to 32×32 removes resolution differences.
Re‑saved copies in different formats (JPEG → PNG → WebP)✅ ExcellentFormat conversions affect pixels but not low‑frequency DCT coefficients.
Re‑compressed JPEGs at different quality levels✅ ExcellentpHash reads the coefficients JPEG preserves most carefully.
Watermarked copies (logos, text overlays)✅ Very GoodWatermarks are high‑frequency detail; pHash ignores them.
Mild colour‑graded versions✅ Very GoodLow‑frequency luminance structure is largely preserved.
Lightly sharpened or noise‑reduced copies✅ GoodSharpening amplifies high frequencies; pHash ignores them.
Screenshots of the same image✅ Very GoodScreenshots preserve structural content.
Videos with similar key‑frame frequency content✅ GoodMultiple frames averaged together.
Heavily cropped images (over 30% removed)⚠️ May missStructural content shifts too much.
Rotated or mirrored images❌ Won’t findDCT is not rotation‑invariant. Use ORB.
Dramatic colour transformations⚠️ May missLuminance structure can change significantly. Try dHash or Color Signature.
Stylised versions (watercolour, posterise, extreme filters)⚠️ May missExtreme filters change structural content.

Understanding the Hamming threshold slider

The threshold slider is the most important control in pHash. It determines how many of the 64 hash bits two images can differ on and still be grouped as duplicates.

Threshold rangeWhat it doesWhen to use
0–5 (Very strict)Only near‑identical frequency patterns match. Very few false positives.Finding exact copies and direct re‑exports.
6–15 (Balanced)Catches resized, re‑compressed, watermarked, and lightly edited copies.Default and recommended. The default of 10 is well‑calibrated for pHash’s 64‑bit hash space.
16–25 (Loose)Includes more approximate structural matches. More false positives.If you’re missing duplicates with significant edits or compressions.
30+ (Very loose)Groups images with broadly similar frequency patterns.Only use for exploration. Expect false positives.

Tip: Because pHash is a 64‑bit hash (unlike aHash and dHash which are 256‑bit), the threshold numbers map differently. A value of 10 on pHash is stricter than 10 on aHash. Start at 8–10 and adjust from there.


How to use pHash: step by step

Step 1: Open the tool and select a folder

Go to the pHash duplicate finder page. Click 📁 Select Folder to Scan to open a native folder picker (Chrome/Edge). Or drag and drop a folder onto the page.

Tip: Make sure Fast Mode is checked. For JPEGs, this reads the embedded thumbnail instead of the full image—5–10× faster with near‑identical accuracy.

Step 2: Wait for the scan to run

A progress bar shows how many files have been processed. pHash involves a DCT computation per image, which is slightly slower than simple pixel hashing but remains fast enough for most collections. Duplicate groups appear live as they’re found—you don’t need to wait for the full scan to finish before reviewing results.

Step 3: Adjust the threshold

After the scan completes, use the Hamming Threshold slider (0–50) to tune matching strictness. Release the slider to re‑cluster all results instantly using the new value—no re‑scanning needed. A background Web Worker handles the re‑comparison.

Step 4: Review the duplicate groups

Results are shown in numbered groups. Each group contains files with similar frequency structure.

  • Click a card to select it (blue border)
  • Ctrl+Click (Cmd on Mac) to add to the compare list (purple border)
  • Click the 🔍 icon on hover to preview full size
  • Right‑click any card for the context menu
  • Click & drag on empty space to box‑select multiple cards

Step 5: Use the Compare modal

Ctrl+Click two or more cards, then click ⚖️ Compare in the toolbar. A modal shows each file with:

  • Full metadata (dimensions, file size, format)
  • A similarity percentage
  • Copy, Move, and Delete buttons for each file
  • A pairwise similarity matrix for 3+ files

The pHash similarity percentage is a meaningful indicator of how perceptually close two images really are—more meaningful than the percentage from aHash or dHash, because pHash encodes actual perceptual structure.

Step 6: Take action—Move, Delete, or Copy

Select files and use the toolbar buttons. With Queue Mode on (recommended), files are staged for review first:

  • 📋 Copy — copy filename(s) to clipboard
  • 📂 Move — stage for move to a named folder
  • 🗑️ Delete — stage for permanent deletion
  • ⚖️ Compare — view selected files side‑by‑side

Warning: Deletions are permanent. The File System Access API bypasses the recycle bin. Always use Queue Mode to review before executing.

Step 7: Execute queued actions

Switch to the Move Queue or Delete Queue tab in the sidebar to review staged files, remove any you changed your mind about, then execute when ready.


When to use pHash vs. the other 6 algorithms

Sakarto gives you seven visual algorithms for a reason—each one handles a different type of duplication problem. Here’s when to pick pHash over the others:

Color Signature — colour accuracy

Color Signature is the only algorithm that compares actual colour. Use it when colour accuracy matters.

Use pHash instead: Your copies have been lightly edited, re‑compressed, or watermarked in ways that preserve colour but change pixel values. pHash is colour‑blind and stable across these edits—Color Signature would see the colour changes as mismatches.

aHash (Average Hash) — speed above all else

aHash is the fastest algorithm—it reads individual pixels and compares them to the overall mean.

Use pHash instead: You need better accuracy than aHash. pHash finds re‑compressed, watermarked, and lightly edited copies that aHash misses. The speed difference is usually acceptable for most collections.

BlockHash — noise tolerance

BlockHash averages brightness over blocks, making it tolerant of compression noise.

Use pHash instead: You want fewer false positives. BlockHash is a coarse descriptor and can over‑match; pHash’s frequency‑domain encoding is more discriminating.

dHash (Difference Hash) — brightness and exposure-adjusted copies

dHash encodes gradient directions and handles exposure shifts well.

Use pHash instead: Your copies have been edited in ways beyond just brightness changes—watermarking, re‑compression, format conversions. pHash is more broadly stable across a wider range of edits.

wHash (Wavelet Hash) — speed and quality balance

wHash uses the Haar Wavelet Transform—similar quality to pHash at lower CPU cost.

Use pHash instead: You want the most stable hash for a mixed collection. pHash’s DCT basis is the same as JPEG compression, making it uniquely robust to the most common image edits.

ORB (Feature Matching) — rotation, cropping, and perspective

ORB is the only algorithm that handles rotation, cropping, and perspective warping.

Use pHash instead: Your copies are not rotated or heavily cropped. pHash is 100× faster than ORB and handles a wider range of edits that don’t involve geometric transformations.


Algorithm quick reference

AlgorithmBest forColour‑aware?Handles rotation?Handles re‑compression?Handles watermarks?Speed
Color SignatureSame colour palette, social media re‑uploads✅ Yes❌ No⚠️ Moderate⚠️ ModerateFast
aHashLarge folders, speed priority❌ No❌ No⚠️ Moderate⚠️ ModerateFastest
BlockHashHeavily compressed JPEGs, noisy images❌ No❌ No✅ Good⚠️ ModerateVery Fast
dHashBrightness/exposure‑adjusted copies❌ No❌ No⚠️ Moderate❌ NoVery Fast
pHashFormat conversions, re‑compression, watermarks❌ No❌ NoExcellentExcellentFast
wHashSpeed + quality balance❌ No❌ No✅ Good✅ GoodFast
ORBRotated, cropped, perspective‑warped❌ No✅ Yes✅ Good✅ GoodSlower

Privacy: your files never leave your device

Like every Sakarto tool, the pHash duplicate finder runs entirely in your browser:

  • Zero network activity after page load. Open DevTools → Network tab and verify: no outbound requests during any scan or file operation.
  • No accounts, no cookies, no analytics. The only localStorage data is your OS detection and checkbox preferences. No file names or scan results are ever saved.
  • Folder access is scoped and session‑only. Permission expires when you close the tab.
  • Purely static—no backend. Sakarto is HTML, CSS, and JavaScript. There is no server, no database, and no API receiving your data.

Frequently asked questions (pHash specific)

“How is pHash different from aHash, dHash, BlockHash, and wHash?”

All five produce a binary hash compared with Hamming distance, but they capture different image properties. aHash compares pixels to the mean—fast but coarse brightness layout. dHash compares adjacent pixels to encode brightness gradient directions—good for exposure‑adjusted copies. BlockHash averages blocks and compares to the median—noise‑tolerant but coarse. wHash applies a Haar Wavelet Transform—similar quality to pHash at lower cost. pHash applies a Discrete Cosine Transform to a 32×32 canvas and extracts the top‑left 8×8 block of low‑frequency coefficients. DCT is the same mathematical operation used in JPEG compression: those low‑frequency coefficients represent the fundamental structure of the image, not fine detail. Re‑compression, format conversion, mild sharpening, light colour grading, and watermarking all affect high‑frequency detail without touching the low‑frequency structure—which is why pHash is the most stable of the hash algorithms across image edits.

”Two clearly different photos are being grouped together. How do I fix it?”

Lower the similarity threshold slider to 4–8. Two photos with very similar structural composition—same type of scene, similar lighting, similar subject placement—can produce similar low‑frequency DCT patterns even if they’re different photos. pHash is more discriminating than aHash or BlockHash, but composition‑level similarities can still cause false positives at loose thresholds. Use the Compare modal (Ctrl+Click two cards, then Compare) to verify before acting. If false positives persist even at strict thresholds, try Color Signature, which also compares colour distribution and can distinguish structurally similar photos with different colour palettes.

”I know two files are duplicates but pHash isn’t grouping them. What should I try?”

First, raise the threshold toward 15–20. Second, check aspect ratios—pairs differing by more than 10% are excluded before hashing. Third, consider the type of edit: pHash handles re‑compression, format conversion, mild colour grading, and watermarking well, but fails on rotation (try ORB), heavy cropping that removes more than ~30% of the image (structural content shifts too much), or very dramatic brightness changes that clip large areas (try dHash for exposure‑adjusted copies). Fourth, confirm both files decode successfully—a corrupted image will produce a garbage hash.

”Why is pHash more stable across JPEG re‑compression than aHash?”

JPEG compression works by applying a DCT to the image and discarding small high‑frequency coefficients. aHash downscales to 16×16 and compares individual pixel values—those pixel values change slightly each time JPEG is re‑compressed because the encoder reconstructs them from the stored (and partially discarded) DCT data. pHash directly computes the DCT and extracts the low‑frequency coefficients, which are the ones JPEG keeps most accurately. So re‑compressing a JPEG barely changes pHash’s input data, while it does affect the pixel values that aHash reads.

”What does Fast Mode do for pHash, and should I leave it on?”

Fast Mode reads the EXIF‑embedded thumbnail in JPEG files (usually around 160×120 pixels) rather than decoding the full image. Since pHash works on a 32×32 canvas anyway, the thumbnail is more than large enough and produces an identical hash in the vast majority of cases. Leave Fast Mode on. The only reason to turn it off is if you notice groupings on JPEG files that disappear when Fast Mode is off, suggesting the EXIF thumbnails in those files were stripped or corrupted by an image editor.

”Can pHash find a watermarked version of my photo?”

Usually yes—this is one of pHash’s strengths. A watermark adds detail to the image (typically text or a logo overlay), which is inherently high‑frequency content. pHash only uses the low‑frequency DCT coefficients, which represent the broad structure of the image. As long as the watermark doesn’t cover such a large area that it fundamentally changes the image’s structural layout, pHash will still group the watermarked and original versions. At the default threshold of 10, medium‑opacity watermarks in corners or along edges are typically ignored entirely.

”Why does video scanning pause when I switch tabs?”

Browsers throttle video element processing when a tab is hidden to conserve battery and CPU. Sakarto detects this via the Page Visibility API and pauses video frame extraction, resuming automatically when you return. Image hashing runs in a background Web Worker, which is not throttled by tab visibility—images keep processing at full speed in the background.

”Can I recover files after deleting them?”

No. The File System Access API’s remove() method permanently deletes files without going through the OS Recycle Bin or Trash. Queue Mode is on by default to prevent accidents: files are staged for review before any deletion is executed. Verify each group using the preview icon and Compare modal before acting. When in doubt, use Move to a “Sakarto‑Duplicates” subfolder instead of Delete—you can always delete from there later.

”What file types are supported?”

Images: JPEG, PNG, GIF, WebP, BMP. Videos: MP4, WebM, MOV, MKV. Files over 40 MB are silently skipped. HEIC/HEIF, SVG, RAW formats, and TIFF are not supported because browsers cannot natively decode them. Convert RAW or HEIC files to JPEG or PNG first.

”Does this work on Firefox or Safari?”

Scanning, DCT computation, result display, and the Compare modal all work in Firefox and Safari. Move and Delete require the File System Access API, available only in Chrome 86+ and Edge 86+. In other browsers, scan, review results in the Compare modal, and use Download List to export a report for manual file management.


Final thoughts

pHash is the algorithm you reach for when you need to find duplicates across a wide range of image edits—re‑compressed versions, watermarked copies, format conversions, and lightly edited variations. It’s the most stable and reliable hash algorithm in Sakarto’s toolkit, built on the same mathematical foundation as JPEG compression itself.

It’s particularly effective for:

  • Mixed‑format libraries. JPEG, PNG, WebP, BMP—pHash finds copies regardless of format.
  • Re‑compressed photo collections. Images that have been saved multiple times at different quality settings.
  • Watermarked image sets. Same image with and without a logo or text overlay.
  • Photo archives with mild colour grading. Slight colour shifts don’t affect low‑frequency DCT coefficients.
  • General‑purpose deduplication. When you don’t know what kind of duplicates to expect, pHash is the safest starting point.

Where pHash falls short—rotated, heavily cropped, or dramatically colour‑shifted copies—other Sakarto algorithms fill the gap. Use ORB for geometric transforms, dHash for brightness shifts, or Color Signature for colour‑aware matching.

But for the vast majority of photo collections, pHash is the best all‑round choice. It’s the algorithm that finds the duplicates the others miss—without the false positives that coarser methods produce.

Ready to find duplicate images and videos with pHash?

May 28, 2026
⏱ 19 min read
🇬🇧 English