2013-03-05 6 views
10

Vor einiger Zeit habe ich nach einer Möglichkeit gesucht, festzustellen, ob zwei Bilder identisch sind, um this question zu beantworten. Ich habe jetzt ein etwas anderes Problem: Ich habe ungefähr zweitausend Bilder zur Hand, von denen einige den gleichen Inhalt haben, aber skalierte/rotierte Versionen voneinander sind (Rotationen sind immer um ein Vielfaches von 90 °), zusammen mit dem Problem von verschiedene Kompressionen und Bildformate (meist jpg, etwas png, sonst nichts). Die Skalierung geht nicht über ungefähr 2: 1 hinaus. Was ich tun möchte, ist Dubletten zu eliminieren, während die Instanz von höchster Qualität erhalten bleibt. Da Java die einzige Sprache ist, in der ich ziemlich geübt bin, muss ich Java verwenden.Identifizieren Sie Bilder mit dem gleichen Inhalt in Java

The answers zu einer anderen Frage bieten viele nützliche Links, aber es sieht nicht aus wie jeder von ihnen kann Duplikate identifizieren, wenn skaliert/gedreht.

This question along with the answers vorschlagen, zuerst alle Bilder auf eine sehr kleine Größe skalieren (sagen 32 * 32 oder 16 * 16), dann im Grunde einige Hashing und Vergleiche basierend auf dem Hash. Das klingt schlau genug, die Bilder könnten vor dem Vergleich vorsortiert werden, was nach dem Sortieren ein O (n) Problem wäre. Da die Bilder jedoch gedreht werden können, bin ich mir nicht sicher, wie ich damit umgehen soll; Eine Option wäre, alle Bilder manuell durchzugehen und sich für eine Rotation zu entscheiden, da das, was sie darstellen, eine klare Orientierung hat (das menschliche Auge kann sehr leicht entscheiden, welcher Weg "aufwärts" sein sollte). Wenn möglich, möchte ich das jedoch vermeiden.

Gibt es etablierte Methoden/Algorithmen (die Links erwähnen SSIM), um mit dieser Art von Problemen umzugehen, oder kann jemand von Ihnen bessere Wege als oben beschrieben finden? Vielleicht kennt jemand Bibliotheken für Java, die sich gut für die Aufgabe eignen (in den verlinkten Fragen gibt es einen Java-Wrapper für OpenCV, dann ImageJ, imgsclr)? Jede Hilfe wird geschätzt.

Antwort

5

Ich denke, dass die allgemeine Antwort auf diese Frage einen unüberwachten maschinellen Lernansatz erfordert, der lokale invariante Merkmale erzeugt - im Prinzip eine raffinierte Methode, Hashes zu finden, die sich bei Skalierung oder Rotation nicht ändern - und dann einen Clustering-Algorithmus auszuführen . Hier sind einige Papiere, die relevant sein könnten:

+0

Prost, ich sehe mir diese an - klingt solide! –

+0

Nach einem Blick auf dieses Material, würde ich Ihnen ein paar mehr Upvotes geben; mehr als genug, um zu tun, was ich tun möchte! –

0

Nun, ich denke, dHash etwas ist du brauchst dafür. Sie müssen nur dHash verbessern, um die Rotation zu berücksichtigen, dh 2000 Bilder werden als 8000 Bilder betrachtet.

Ich schrieb eine reine Java-Bibliothek nur für diese paar Tage zurück. Sie können es mit dem Verzeichnispfad (einschließlich Unterverzeichnis) füttern und es werden die doppelten Bilder in der Liste mit dem absoluten Pfad aufgeführt, den Sie löschen möchten. Alternativ können Sie damit auch alle eindeutigen Bilder in einem Verzeichnis finden.

Es verwendet intern awt api, so kann nicht für Android verwendet werden. Da imageIO Probleme hat, viele neue Arten von Bildern zu lesen, verwende ich zwölf Affen, die intern verwendet werden.

https://github.com/srch07/Duplicate-Image-Finder-API

Jar mit Abhängigkeiten intern gebündelt aus, heruntergeladen werden https://github.com/srch07/Duplicate-Image-Finder-API/blob/master/archives/duplicate_image_finder_1.0.jar

Die api können Duplikate unter Bilder in verschiedenen Größen finden.

Verwandte Themen