For a long time I faced the same problem every postcard collector eventually runs into. I had scanned thousands of cards, neatly organised them in folders, and even built a database to manage them. But tagging them by hand was another story. It was slow, repetitive, and completely unsustainable at scale. I needed a way to automate the first round of tagging so I could focus on verification and research instead of data entry.
Enter CardAI, my AI postcard tagger.
CardAI is a Python project that grew out of my need to automate tagging. It uses PyTorch and the open source CLIP model (Contrastive Language–Image Pretraining) from OpenAI to understand what each postcard actually shows. CLIP is a dual-encoder transformer that embeds images and text in the same 512-dimensional semantic space, meaning that an image of a harbour and the word harbour end up close together in that space.
For every scanned postcard CardAI generates a feature vector, a dense numerical fingerprint that encodes not just colours and edges but the underlying meaning of the scene. Two cards showing similar subjects produce vectors pointing in similar directions in this high-dimensional space, allowing the system to group or compare images by what they depict rather than by filename.
Instead of comparing pixels or using hand-crafted image descriptors, CardAI calculates cosine similarity between embeddings to quantify how closely two cards are related. This allows it to detect relationships that are visually meaningful rather than just geometrically similar. A bridge seen from above and another from the side may look quite different to a human eye but still lie close together in vector space because they depict the same concept.
Under the hood, CardAI stores each image’s embedding and metadata in a lightweight SQLite database. When a new scan appears in the input directory, the program preprocesses the image, computes its embedding, and normalises it to unit length. It then performs a nearest-neighbour search against the stored embeddings to find the most similar cards already in the collection. Based on these matches, CardAI infers likely descriptive tags such as harbour, church, or train and records them alongside the image path.
The result is a continuously evolving knowledge base that grows as new cards are added. Every additional scan refines the model’s understanding of the collection, turning thousands of individual images into a connected semantic network that can be browsed, searched, and analysed by visual meaning rather than filenames or folders.
A front end for verification
To make it easier to review the results I created a small front end in Flask. The app displays every postcard as a thumbnail, suggests descriptive tags such as harbour, church, or train, and lets me browse or search visually through the collection. I added pagination so large directories remain responsive, and when I hover over a thumbnail I see the full filename together with all tags that CardAI has assigned.
The goal is full automation. New scans go into a folder, CardAI tags them, and the system automatically prepares everything for import into my existing postcard database.
Up next is text recognition, so the program can also read printed or handwritten information from the cards, making the search even richer and the archive fully self-organising.
To be continued ...