Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog › Computer Vision

How to Build a Local Photo Deduplicator With Image Embeddings

By Freedom251 Team · · 11 min read

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Build the deduplicator as a review-first pipeline: inventory files, create one consistent image embedding per file, store each vector beside a stable file ID and metadata, retrieve nearest neighbors, group candidate pairs, and review them before anything is moved or deleted. Embeddings make good candidate finders, not automatic deletion decisions.

The entire photo index can stay on your computer, but “local” does not automatically mean “offline.” Model weights, packages, or a particular installation may still contact a network service. Verify those behaviors before indexing sensitive material, and keep the original collection untouched until review and backup are complete.

As an Amazon Associate I earn from qualifying purchases.

What you are building

A useful deduplicator has five separate responsibilities:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Inventory: walk only the directories you explicitly select and record a stable file identifier, path, size, modification time, and available EXIF data.
  2. Representation: decode each supported image and produce one embedding with a fixed model and preprocessing configuration.
  3. Indexing: persist the vector and enough metadata to locate and preview the source file.
  4. Candidate retrieval: find the nearest neighbors for each image and turn high-scoring pairs into review groups.
  5. Decision and removal: show thumbnails, distances, and file details to a person who decides what to keep. Move or delete only after that review and a backup.

This separation mirrors the image-read, CLIP-embedding, saved-embedding, semantic-deduplication, and filtered-output stages documented for NVIDIA NeMo Curator v26.07. It also lets you rebuild an index or change a threshold without touching the originals.

#1 Best Overall
SSK Portable SSD 1TB External Solid State Hard Drive USB C Up to 1050MB/s
  • Capacity Display Variance: 1TB external ssd often appears as around 931GB on Windows. MacOS can show full 1 TB capacity. This is binary calculation difference and doesn’t affect SSD hard drive actual physical storage
  • 1050 MB/s Speed: Instantly access to your files with blazing-fast 10Gbps external SSD read up to 1050MB/s and write up to 1000MB/s. LED Light indicates USB SSD instant activity
  • Data Security: Solid state drives S.M.A.R.T. health diagnostics​ and adaptive TRIM optimizing data block management ensures consistent write speeds and extends the longevity of the portable SSD
  • USB-C & USB-A Cable: Both cables featuring rapid USB 3.2 Gen2, this USB SSD effortlessly bridges devices, enabling seamless cross-platform file transfers and backup between computers, smartphones, tablets and iPhone
  • Always Fast: No slowdowns for large file transfers. With SLC caching (25% of current available capacity allocated as high-speed cache), this external SSD delivers steady 10Gbps for transfers within the cache capacity

How do I inventory photos without changing them?

Choose the source directories explicitly. Follow symlinks only if you intend to include their targets, and record the decision in the run configuration. For each file, collect:

  • a stable identifier that does not depend on the current folder name;
  • the absolute or otherwise unambiguous path used for preview and review;
  • file size and modification time;
  • format, width, height, and orientation when decoding succeeds;
  • available EXIF capture time and camera fields; and
  • an indexing status and a human-readable error for files that cannot be read.

A content-derived identifier, such as a cryptographic digest, remains associated with a file when it is renamed, while a database-generated ID is simpler for repeated imports. Whichever policy you choose, document it and keep the path as mutable metadata. Two byte-identical files may intentionally share a content ID, so retain every path record if you want to find redundant copies in different folders.

Do not discard unreadable files silently. Log the path, decoder error, and timestamp, then continue with the rest of the collection. Unsupported formats, encrypted files, truncated downloads, and permissions errors should be visible in a report that can be fixed and re-run.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A minimal inventory record can look like this:

{
  "file_id": "stable-id",
  "path": "/photos/2024/trip/image-001.jpg",
  "size_bytes": 4839201,
  "mtime": "2024-06-14T18:22:31Z",
  "width": 4032,
  "height": 3024,
  "exif": {"date_taken": "2024-06-12T09:18:04Z"},
  "status": "ready"
}

The example shows a record shape, not a requirement to use JSON. A relational table works just as well and is easier to filter by folder, date, or status.

Should you use hashes, embeddings, or both?

Perceptual hashes and learned embeddings answer overlapping but different questions. A hash compresses an image into a short binary representation and is efficient for exact copies and modest visual changes. An embedding represents broader visual features and can retrieve images that depict a similar scene even when the files are not byte-for-byte copies.

Method Representation or documented example Best role Important limitation
pHash 64-bit perceptual representation; compare with Hamming distance Fast screening of exact and visually close variants Crops, substantial edits, and semantically similar but distinct photos can confuse the match
PDQHash 256-bit perceptual representation; compare with Hamming distance Compact near-duplicate screening Thresholds reported in PIXELMOD were calibrated for that study’s datasets, not for a personal library
OpenCLIP embedding LibrePhotos documents OpenCLIP ViT-B/32 for tags, semantic search, and similar-photo retrieval Broader visual or semantic candidate retrieval The model and preprocessing determine what “similar” means; it is not proof that two files are interchangeable

A hybrid design is often practical: use a perceptual hash to remove obvious byte-level or near-byte-level repeats from the candidate workload, then use embedding neighbors to find resized, recompressed, lightly edited, or scene-level matches. Keep the two scores separate so a reviewer can see whether a candidate was found by hash, embedding, or both.

How do I generate consistent image embeddings?

Pick one model, one preprocessing pipeline, and one distance convention for an index build. Save the model identifier or version and preprocessing settings with every index. If you later change the model, image resizing, color handling, or normalization, rebuild the affected vectors rather than mixing incompatible representations.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sandisk 2TB Extreme Portable SSD, Up to 1050MB/s, USB-C, USB 3.2 Gen 2, IP65 Water and Dust Resistance, Updated Firmware, External Solid State Drive, SDSSDE61-2T00-G25
  • Get NVMe solid state performance with up to 1050MB/s read and 1000MB/s write speeds in a portable, high-capacity drive(1) (Based on internal testing; performance may be lower depending on host device & other factors. 1MB=1,000,000 bytes.)
  • Up to 3-meter drop protection and IP65 water and dust resistance mean this tough drive can take a beating(3) (Previously rated for 2-meter drop protection and IP55 rating. Now qualified for the higher, stated specs.)
  • Use the handy carabiner loop to secure it to your belt loop or backpack for extra peace of mind.
  • Help keep private content private with the included password protection featuring 256‐bit AES hardware encryption.(3)
  • Easily manage files and automatically free up space with the SanDisk Memory Zone app.(5). Non-Operating Temperature -20°C to 85°C

The documented NeMo Curator pattern configures an image-embedding stage with a model directory and writes records containing image IDs and embeddings. LibrePhotos provides a concrete OpenCLIP ViT-B/32 implementation, but that example is not a universal “best” model or a performance guarantee. Select a model whose license, hardware requirements, and visual behavior fit your collection.

An implementation-neutral embedding pass is:

model = load_model(model_directory, model_identifier)
preprocess = load_preprocessing_configuration(model_identifier)

for photo in inventory where photo.status == "ready":
    image = decode(photo.path)
    tensor = preprocess(image)
    vector = model.embed(tensor)
    save_vector(
        file_id=photo.file_id,
        vector=vector,
        model_id=model_identifier,
        preprocessing_id=preprocess.identifier
    )

The function names are intentionally generic because model-loading APIs differ. The invariants matter: each successful file gets one vector, the vector is tied to the file ID, and the model metadata is persisted so the run can be reproduced.

Run a small pilot first. Confirm that orientation metadata is handled consistently, transparent images do not crash the decoder, and the same file produces the same vector when reprocessed with the same model and settings. Keep a count of successes, failures, and skipped formats.

How can the index stay local and searchable?

Maintain a relational mapping from vector ID to file ID, path, metadata, and embedding. A simple schema is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
CREATE TABLE photo_index (
  vector_id INTEGER PRIMARY KEY,
  file_id TEXT NOT NULL,
  path TEXT NOT NULL,
  size_bytes INTEGER NOT NULL,
  mtime TEXT NOT NULL,
  width INTEGER,
  height INTEGER,
  model_id TEXT NOT NULL,
  preprocessing_id TEXT NOT NULL,
  embedding BLOB NOT NULL
);

The vector column can be stored in a format supported by your search library, while the relational columns remain available for filtering and preview. Keep a persistent copy of the vectors or a deterministic way to rebuild them. If an index file is corrupted, you should not have to decode every original image merely to recover the metadata.

SQLite’s vec1 extension documents both exact flat search and approximate nearest-neighbor modes, along with metadata columns that can be filtered during a search. That makes a compact, self-contained application possible. Faiss is a separate similarity-search library with Python wrappers and CPU and optional GPU implementations. It offers several index families rather than one mandatory layout.

Do not choose an approximate index because it sounds faster. Measure on your own collection and hardware. The relevant trade-offs are search time, recall or search quality, memory, index-training time where applicable, add time, and rebuild time. Exact scans are easiest to reason about; approximation becomes attractive only when measured workload size justifies the added operational complexity.

Rank #3
SSK Portable SSD 250GB External Solid State Hard Drive USB C Up to 1050MB/s
  • Capacity Display Variance: 250GB external ssd often appears as around 232GB on Windows. MacOS can show full 250 GB capacity. This is binary calculation difference and doesn’t affect SSD hard drive actual physical storage
  • 1050 MB/s Speed: Instantly access to your files with blazing-fast 10Gbps external SSD read up to 1050MB/s and write up to 1000MB/s. LED Light indicates USB SSD instant activity
  • Data Security: Solid state drives S.M.A.R.T. health diagnostics​ and adaptive TRIM optimizing data block management ensures consistent write speeds and extends the longevity of the portable SSD
  • USB-C & USB-A Cable: Both cables featuring rapid USB 3.2 Gen2, this USB SSD effortlessly bridges devices, enabling seamless cross-platform file transfers and backup between computers, smartphones, tablets and iPhone
  • Always Fast: No slowdowns for large file transfers. With SLC caching (25% of current available capacity allocated as high-speed cache), this external SSD delivers steady 10Gbps for transfers within the cache capacity

Exact search, SQLite vec1, or Faiss?

Choice What it provides When it fits Decision to measure
Exact flat scan Compares a query with every stored vector and returns exact nearest neighbors Small collections, prototypes, and validation of another index Query time and memory as the library grows
SQLite vec1 SQLite-hosted vectors, exact flat search, approximate modes, and metadata pre-filtering A self-contained tool that needs file metadata and vector search together Filtering cost, update behavior, and approximate-search recall on your data
Faiss Dedicated vector indexes, Python wrappers, CPU support, and optional GPU support Applications that need multiple index choices or hardware acceleration Search quality, memory, add and training time, and rebuild complexity

Benchmark with representative queries, not just a synthetic timing loop. Include portrait and landscape images, repeated imports, edited files, and folders you expect to filter. Keep exact search as a reference set while evaluating an approximate index so you can quantify which candidates it misses.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do I retrieve neighbors and form candidate groups?

For every indexed vector, request more than one neighbor, remove the item itself, and retain the returned distance or similarity. Faiss describes nearest-neighbor retrieval as distance or inner-product comparison and supports returning multiple neighbors. The metric and whether larger or smaller values mean “closer” must be recorded alongside the threshold.

for query in indexed_photos:
    neighbors = search(query.vector, k=K, metric=metric)
    for neighbor in neighbors:
        if neighbor.file_id == query.file_id:
            continue
        pair = canonical_pair(query.file_id, neighbor.file_id)
        if pair not in pairs:
            pairs[pair] = {
                "distance": neighbor.distance,
                "metric": metric
            }

Canonicalizing the pair prevents counting A–B and B–A twice. Store the strongest or most relevant score according to your metric, but preserve the original pairwise value used for the review decision.

Do not build groups by blindly taking the transitive closure of every match. If A is close to B and B is close to C, A may still be too far from C. A safer approach is to create an edge only when a pair passes the calibrated candidate rule, then show connected components as provisional groups while displaying every pairwise score. A reviewer can split a chain when one edge is weak.

Keep group membership provisional. The output should identify candidate sets, not declare a canonical file automatically.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What similarity threshold should I use for near-duplicates?

There is no universal embedding threshold. The right value depends on the model, preprocessing, distance metric, image mix, and how your library defines “duplicate.” The PIXELMOD paper discusses dataset-specific calibration and reports prior pHash and PDQHash studies with different thresholds; those numbers should not be transplanted into a personal photo collection.

Create a labeled calibration sample from your own files:

Rank #4
SSK Portable SSD 500GB External Solid State Hard Drive USB C Up to 1050MB/s
  • Capacity Display Variance: 500GB external ssd often appears as around 465GB on Windows. MacOS can show full 500 GB capacity. This is binary calculation difference and doesn’t affect SSD hard drive actual physical storage
  • 1050 MB/s Speed: Instantly access to your files with blazing-fast 10Gbps external SSD read up to 1050MB/s and write up to 1000MB/s. LED Light indicates USB SSD instant activity
  • Data Security: Solid state drives S.M.A.R.T. health diagnostics​ and adaptive TRIM optimizing data block management ensures consistent write speeds and extends the longevity of the portable SSD
  • USB-C & USB-A Cable: Both cables featuring rapid USB 3.2 Gen2, this USB SSD effortlessly bridges devices, enabling seamless cross-platform file transfers and backup between computers, smartphones, tablets and iPhone
  • Always Fast: No slowdowns for large file transfers. With SLC caching (25% of current available capacity allocated as high-speed cache), this external SSD delivers steady 10Gbps for transfers within the cache capacity
  • obvious byte-identical copies;
  • resized or recompressed versions;
  • cropped, color-adjusted, or lightly edited images that you would still treat as duplicates;
  • bursts or alternate frames that should remain separate; and
  • unrelated photos with similar colors, faces, buildings, or landscapes.

Run the candidate search across this sample and inspect false positives and false negatives. Increase strictness when unrelated images are being grouped; relax it when known variants are missing. Record the selected threshold with the model and index version. If you use separate hash and embedding rules, calibrate each rule and document whether a candidate must pass one rule or both.

Precision and recall provide a useful vocabulary: precision asks how many proposed matches are genuinely acceptable duplicates, while recall asks how many acceptable duplicates were found. The review screen should expose both the score and the images so a person can correct mistakes that a single number cannot resolve.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How should the review and removal stage work?

Identification and destruction should be different commands or clearly different screens. A review record should include:

  • thumbnail previews with a way to open the full-resolution file;
  • each path, file size, dimensions, capture time when available, and modification time;
  • the pairwise distance or similarity and the metric used;
  • which model and preprocessing configuration produced the vectors; and
  • an explicit keep, move, reject, or undecided state.

Choose a keeper by rules that make sense for your library, such as the original-resolution file, the earliest capture, the copy in a designated archive folder, or a manually selected image. Do not let “nearest” decide the keeper: embedding proximity says nothing about resolution, metadata completeness, artistic preference, or whether a file is your edited master.

Export a review report before changing files. After a backup, move rejected files to a quarantine directory with a manifest rather than deleting immediately. Verify that every move succeeded, retain the original path in the manifest, and provide a restore operation. Only empty quarantine after a separate confirmation period.

The semantic-deduplication workflow documented by NeMo Curator has a distinct filtered-output stage. Treat that separation as a safety boundary: indexing and candidate generation should be repeatable and non-destructive, while removal is an explicit, auditable action.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can this run without uploading photos?

Yes, the data path can be designed around local directories and local vector storage. That does not prove that every installation is offline. A model may need to download weights, and a package may have its own telemetry or remote service behavior. Before processing private images, inspect the model-loading process, cache location, package documentation, and firewall or network logs appropriate to your environment.

Best Value
UnionSine 1TB Ultra Slim Portable External Hard Drive HDD-USB 3.0 | for PC, Mac, Laptop, PS4, Xbox one, Xbox 360-(Black)
  • 【Upgraded version】 - The mirror logo strip is combined with the striped non-slip design. The rounded corners of the shell are more suitable for holding. The strips play a heat dissipation function to ensure a stable and fast transmission process.
  • 【Ultra-thin and quiet】 - The motherboard adopts JMicron 578 noise-free solution, giving you a quiet working environment. Lightweight and portable size designed to fit in your pocket for easy portability.
  • 【Ultra-Fast Data Transfers】 - Pairing this external hard drive with JMicron 578 solution USB 3.0 and USB 2.0 interfaces enables blazing-fast data transfer. It boasts theoretical read speeds of up to 125MB/s and write speeds of up to 103MB/s.
  • 【Plug and Play】 - With no software to install, just plug it in and the drive is ready to use.The hard disk chip is wrapped with an aluminum anti-interference layer to increase heat dissipation and protect data.
  • 【What You Get】 - 1 x Portable Hard Drive, 1 x USB 3.0 Cable, 1 x User Manual, Gift-type shell packaging ,Three-year manufacturer's warranty and free technical support services.

After model files are available, run with network access disabled only if your chosen stack supports that mode. Record the model files and versions so a rebuild does not unexpectedly fetch a different artifact. Avoid sending thumbnails, EXIF data, paths, or embeddings to a hosted API unless that transfer is an intentional part of your design.

Common failure modes and fixes

The same image gets different results on different runs

Check that the model identifier, weights, preprocessing, image orientation handling, and distance metric are unchanged. Rebuild vectors created with a different configuration instead of combining them.

Many unrelated photos appear together

Your threshold may be too permissive, or the model may emphasize scene semantics rather than duplicate-level detail. Tighten the candidate rule, add a perceptual-hash screen, and inspect false positives from the calibration set.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Known resized or edited copies are missing

Increase the candidate count before changing the threshold, verify that the files decoded correctly, and test a less strict rule on labeled examples. Keep a separate rule for broad similarity so it does not silently alter your duplicate policy.

Groups contain a long chain of only partly similar images

Transitive grouping is masking weak edges. Show pairwise distances, split groups at the review stage, or require stronger edges before creating a provisional component.

Search is slow or memory-heavy

Measure an exact scan first, then compare an approximate index on the same queries. Consider SQLite vec1 metadata filtering or a Faiss index suited to your scale, but verify recall against exact results before switching production behavior.

Moved files cannot be previewed

Paths are mutable. Re-scan the selected roots, reconcile records by the stable file ID or content digest, and keep prior paths in the audit manifest. Do not create a second vector merely because a file was renamed.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Deletion removes the wrong copy

Stop using automatic deletion. Require a human keeper decision, write a manifest, quarantine first, and verify a backup and restore path before permanent removal.

A practical build sequence

  1. Define scope: select source directories, supported formats, symlink behavior, and the stable-ID policy.
  2. Inventory: write one metadata record per file and a separate error log for unreadable inputs.
  3. Choose representations: decide whether a perceptual hash, an embedding, or a hybrid matches your duplicate definition.
  4. Generate vectors: use one fixed model and preprocessing configuration; persist that configuration with the index.
  5. Persist data: store vectors, IDs, paths, metadata, and model information in a rebuildable local index.
  6. Validate search: compare exact results with any approximate index and measure time, memory, and candidate recall on representative files.
  7. Calibrate: label examples from the target library and select thresholds using observed false positives and false negatives.
  8. Group cautiously: exclude self-matches, canonicalize pairs, retain distances, and avoid assuming similarity is transitive.
  9. Review: present thumbnails and metadata, choose keepers explicitly, and export an audit report.
  10. Quarantine: move rejected files only after backup, retain a manifest, and delete permanently only after a separate confirmation.

This design answers “How do I find duplicate photos on my computer?” without turning a similarity score into an irreversible command. It also gives you a controlled way to compare exact search, SQLite vec1, and Faiss as your collection grows, while keeping model changes and destructive actions auditable.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Computer VisiondeduplicationFaissimage embeddingslocal softwareOpenCLIPphoto managementSQLite

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.