Bilder sortieren mit KI - aber richtig

Wie sortiert man 10.000 Bilder zuverlässig, lokal und ohne Cloud? Ich habe mein eigenes Tool mit Hashing und KI gebaut - und dabei mehr gelernt als gedacht. Hier ist der Weg dorthin.

03.06.2025 10:48 von Christian

Warum ich ein eigenes Tool entwickelt habe

Irgendwann kommt der Moment, wo man seinen Bilder-Ordner aufräumen will. Bei mir waren es tausende Bilder, gesammelt über Jahre - Smartphone-Backups, Downloads, WhatsApp, Screenshots, doppelte Serienfotos, teils dreifach gespeichert. Ich wollte Ordnung schaffen. Die meisten Tools, sogar manche KI-gestützten, enttäuschten mich: unpräzise, langsam, nicht vertrauenswürdig oder schlicht zu unflexibel.

Also beschloss ich, das Problem selbst zu lösen. Als Entwickler lag es nahe: Ich baue ein eigenes Tool - genau auf meine Bedürfnisse zugeschnitten. So entstand ReMedia: ein modernes Python-Tool zur intelligenten Duplikat- und Ähnlichkeitserkennung in großen Bildsammlungen.

Wie ich es gebaut habe – von Hash bis KI

Der erste Schritt war klassisch: Ich habe dhash und phash verwendet - zwei etablierte Algorithmen für Bild-Hashing. Beide funktionieren gut, aber jeder hat seine Schwächen. Erst eine gewichtete Kombination lieferte richtig robuste Ergebnisse bei exakt gleichen oder stark ähnlichen Bildern.

Aber ich wollte mehr. Ich wollte nicht nur erkennen, ob zwei Bilder technisch gleich sind - ich wollte auch verstehen, ob sie inhaltlich zusammengehören. Also entschied ich mich für einen zweiten Modus mit künstlicher Intelligenz.

Zunächst testete ich CLIP, ein Modell, das Bilder und Texte semantisch verknüpft. Schnell wurde aber klar: CLIP ist exzellent darin, verwandte Bilder zu erkennen - etwa dieselbe Person in unterschiedlicher Kleidung, ähnliche Hintergründe, identische Orte. Aber es scheiterte oft daran, echte Duplikate zu erkennen. Es ging nicht um Pixelgleichheit, sondern Kontext. Die Folge: viele falsche Freunde - Bilder, die nur thematisch zueinander passten.

Die Lösung: Ich nutze CLIP nicht mehr für einfache 1:1-Vergleiche, sondern mit einer deutlich intelligenteren Gruppierungslogik. Statt wie zuvor nur zwei Bilder miteinander zu vergleichen, prüft das Tool jetzt, ob alle Bilder innerhalb einer potenziellen Gruppe sich auch untereinander ähnlich genug sind. Erst dann gilt die Gruppe als Gruppe. Dadurch wird CLIP zwar nicht präziser - aber das Verfahren wird es. Man erhält gut sortierte Bilder, die auch in den meisten Fällen tatsächlich zusammenpassen.

Deep Dive: Wie ReMedia unter der Haube funktioniert

Lokale Intelligenz statt Cloud-Upload

Einer der wichtigsten Punkte bei der Entwicklung von ReMedia war der Datenschutz. Viele Bilder enthalten sensible Inhalte - sei es aus dem privaten Umfeld, der Arbeit oder aus rechtlicher Sicht. Deshalb war für mich klar: ReMedia soll vollständig lokal arbeiten. Keine API-Calls zu Dritten, keine Cloud-KI - alles bleibt auf dem Rechner.

Architektur: Klar getrennt, sauber skalierbar

ReMedia basiert auf einem modularen, objektorientierten Aufbau. Der zentrale Punkt ist das sogenannte SimilarityEngine-Interface:

from abc import ABC, abstractmethod

class SimilarityEngine(ABC):
    @abstractmethod
    def compute_features(self, media_list):
        pass

    @abstractmethod
    def are_similar(self, a, b):
        pass

Dieser Ansatz erlaubt es, verschiedene Vergleichslogiken parallel zu entwickeln: klassische Hash-Engines, KI-basierte Varianten, hybride Methoden - alles ist leicht austauschbar. Aktuell gibt es zwei konkrete Engines:

Feature-Extraktion mit OpenCLIP

Für die "ähnliche Bilder"-Funktion verwendet ReMedia OpenCLIP, ein visuelles Sprachmodell von LAION/AI-community. Es erzeugt sogenannte Embeddings - eine Art Fingerabdruck eines Bildes, ähnlich wie die Hash-Methode.

import open_clip

self.model, _, self.preprocess = open_clip.create_model_and_transforms("ViT-B-32-quickgelu", pretrained="openai")
self.model.eval().to(self.device)

Durch diese Features können wir Bilder unabhängig von Auflösung, Farbe oder sogar kleinen Änderungen an Inhalt und Stil miteinander vergleichen.

Gruppierung mit smarter Validierung

Ein klassisches Problem bei naiven KI-Vergleichen: Neue Bilder werden oft nur mit einem einzigen Referenzbild abgeglichen - das führt dazu, dass eine Gruppe zwar jeweils ähnliche Paare enthält, aber nicht als geschlossene Einheit zusammenpasst. Das Ergebnis? Ich hatte einen Ordner mit 1200 Bildern, die eine "Gruppe" darstellen sollten. Das war also nicht Zielführend. Die Lösung:

if all(engine.are_similar(candidate, other) for other in group):
    group.append(candidate)

Jedes neue Bild wird mit allen bisherigen Gruppenmitgliedern verglichen. Nur wenn es zu allen passt, wird es aufgenommen. So vermeiden wir Fehlzuordnungen und verbessern die Präzision - besonders bei CLIP, das semantisch sehr tolerant ist.

UX-Details mit technischer Wirkung

Auch kleine Dinge haben große Wirkung. Etwa der Fortschrittsbalken via tqdm, der zeigt, wie viele Bilder bereits verarbeitet wurden. Oder die Option, wie „streng“ verglichen werden soll - das wird als Threshold-Wert an die Engines übergeben, aber intelligent skaliert. So kann auch ohne technisches Hintergrundwissen schnell unterschieden werden zwischen "Suche wir Duplikate" und "Suche mir ähnliche Bilder".

Praxistest - funktioniert's?

Absolut. Die Hash-Engine identifizierte in wenigen Minuten über 200 echte Duplikate, sauber sortiert nach Gruppen. Die KI-Engine dagegen zeigte mir auf, dass manche Bilder aus demselben Shooting stammen, aber leicht abweichen - ein Segen, wenn man nach den besten Aufnahmen sucht. Beide Modi ergänzen sich perfekt.

Und das Beste: Du kannst es direkt nutzen, anpassen oder erweitern - der Code ist auf GitHub als Open Source Projekt verfügbar.

Themen

Über den Author

Christian

Ich bin Christian Seip - Softwareentwickler mit Schwerpunkt auf Web-Technologien. In den letzten Jahren war ich unter anderem als Lead Developer und Datenschutzkoordinator bei der Ströer-Gruppe tätig. Davor habe ich bei Amazon Games gearbeitet.

Ich schreibe hier, weil ich Dinge hinterfrage. Weil ich wissen will, was unter der Oberfläche steckt - technisch, gesellschaftlich und sprachlich. Und weil ich glaube, dass es nicht reicht, Dinge nur zu tun, ohne darüber zu reden.

Dieser Blog ist kein Tutorial-Archiv und keine Selbstvermarktung. Er ist mein Versuch, klare Gedanken zu formulieren und Position zu beziehen auch wenn es unbequem ist. Mal technisch, mal kritisch, mal persönlich.