zwei Bilder miteinander vergleichen

Status
Nicht offen für weitere Antworten.

beachdiddi

Mitglied
Hallo,

ich möchte zwei Bilder miteinander vergleichen. Jetzt habe ich gelesen, dass man aus den Bildern Pixel-Arrays macht und diese dann miteinander vergleicht. Ich will diese Bilder nirgends anzeigen lassen oder sonst was mit ihnen machen. Ich will nur prüfen ob sie identisch sind.

Ich habe dazu schon ein paar Beiträge gelesen und auch schon gegoogelt. Leider komme ich immer noch nicht auf eine ordentliche Lösung.
Vielleicht hat jemand die Geduld es mir noch einmal zu erklären wie ich da vorgehen muss.

Ich beschreibe mal meinen bisherigen Weg.
Code:
             File f = new File("/pfad/zu/meinem/Bild/xy.jpg");
             BufferedImage img = ImageIO.read(f);
             int[] pix = new int[img.getWidth()*img.getHeight()]; // int[] mit der Größe "breite * höhe", um alle Pixel unterzubringen
Jetzt hab ich gelesen, dass ich irgendwie die Klasse PixelGrabber ins Spiel bringen muss.
Aber da hängts irgendwie...
Vielleicht bin ich ja auch mit obigen Vorgehen schon auf dem Holzweg.
Ich bitte also um Rat.

mfg, beachdiddi
 

Wildcard

Top Contributor
Ich würde erstmal eine Vorauswahl anhand der Dateigröße oder des Hashwerts treffen bevor ich mich auf einen teuren Pixelvergleich einlasse.
 

beachdiddi

Mitglied
Ariol hat gesagt.:
Das hier suchst du vermutlich:
public synchronized Object getPixels() [1.1]
Liefert die kopierten Pixel in einem int-Array, falls ein RGB-Farbmodell benutzt wurde, ansonsten in einem byte-Array.

Ok, so hab ich es hinbekommen.
Danke Ariol!
Code:
public class Grab {
	
       void grab(Image img, int pix[], int width, int height) {
	        PixelGrabber grabber =  new PixelGrabber(img, 0, 0, width, height, pix, 0, width);
	      try {
	        grabber.grabPixels();
	      }
	      catch (InterruptedException e) {
	        e.printStackTrace();
	      }
	    }
	
	public static void main(String[] args) {
		try{
 		File f = new File("/pfad/zu/dem/Bild/xy.jpg");
		BufferedImage img = ImageIO.read(f);
		int w = img.getWidth();
		int h = img.getHeight();
		int[] pix = new int[w*h];
		Grab y = new Grab();
		y.grab(img, pix, w, h);

		}catch (IOException e){
			
		}
}

@Wildcard:
Gibts da irgendwie eine bestimmte Reihenfolge, die Du bevorzugen würdest?
Z.B.:
1. Das Verhältnis von w*h
// dann, falls das Verhältnis gleich ist
2. Die Dateigröße
//falls gleich, dann
3. Hashwertvergleich
// und zuletzt
4. Pixelvergleich

Kann man da eine solche Reihenfolge wählen?
Oder gibts noch andere Möglichkeiten zur Überprüfung?
Macht es Sinn sich aus dem Bild ein Stück rauszuschneiden (also z.B. 16x16 Pixel), bei dem anderen Bild natürlich auch an der gleichen Stelle auch ein 16x16 Stück ausschneiden und diese kleineren Byte-Arrays miteinander zu vergleichen? Und nur falls die beiden Arrays übereinstimmen folgt ein kompletter Pixelvergleich. Spart ja bestimmt einiges an Zeit, oder? Oder ist die Zeitersparnis vernachlässigbar?
 

Wildcard

Top Contributor
Ich sag mal so, wenn der Hashwert identisch ist (nicht der Java Hash sondern MD5, SHA oder so) ist die Wahrscheinlichkeit das beide Bilder gleich sind schon sehr hoch.
 

Ariol

Top Contributor
1. ergibt keinen sinn, denn bei 400*300 und auch bei 800*600 das Größenverhältnis gleich ist, aber du die beiden nicht vergleichen kannst.

also zuerst mal auf dateigröße testen, dann auf höhe und auf breite.

ob hashwert sinn macht weiss ich nicht, aber zumindest den vergleich kannst du abbrechen lassen, wenn nur ein pixel falsch ist.

Zur verbesserung der Laufzeit könntest du das überprüfen in mehrere Threads auslagern mit geteiltem String natürlich, dann findest du schneller raus, wenn das ganze ungleich ist.

Was ich nicht weiss, ob vielleicht auch equal das ganze abkürzen kann (glaubs aber nicht)
 

beachdiddi

Mitglied
Ok, also dann über den Hashwert.

Bin ich dann bei dem Paket "java.security.MessageDigest" richtig?
Damit werd ich mich mal auseinander setzen.

Danke für Deine Hilfe!!!
 

Ariol

Top Contributor
Wildcard hat gesagt.:
Ich sag mal so, wenn der Hashwert identisch ist (nicht der Java Hash sondern MD5, SHA oder so) ist die Wahrscheinlichkeit das beide Bilder gleich sind schon sehr hoch.

sehr hoch, aber nicht gleich.

aber mir fällt gerade ein, das die Größe auch nix über die Gleichheit sagen muss (gleiches Bild einmal als gif und einmal als jpeg)

dann stimmt der hashwert natürlich nicht überein.


Insofern fallen diese beiden Überprüfungen zum Abbruch eigentlich flach
 

Wildcard

Top Contributor
Ein gif und ein jpg können praktisch gar nicht gleich sein, da (fast alle) jpegs verlustbehaftet komprimiert werden.
 

beachdiddi

Mitglied
Jetzt waren wir drei fast gleichzeitig fertig :D

Ariol hat gesagt.:
Zur verbesserung der Laufzeit könntest du das überprüfen in mehrere Threads auslagern mit geteiltem String natürlich, dann findest du schneller raus, wenn das ganze ungleich ist.
Du meinst den String in X Teile aufteilen und alle X Teile von jeweils einem Thread überprüfen lassen?
 

Wildcard

Top Contributor
Da fällt mir ein:
Geht es dir eigentlich um identische Bilder oder identische Dateien?
Denn wenn es dir um echt identische Bilder (von den Pixeln) geht dann kannst du den Hash nicht verwenden.
Bilder enthalten zum Beispiel auch Meta-Daten (Autor,...) die den Hash-Wert selbst wenn das Bild das gleiche ist.
 

Ariol

Top Contributor
muss j nicht unbedingt jpeg sein, was ist denn mit tiff??

@beachdiddi:

ja, das Array (wieso String) aufteilen und dann von mehren Threads testen lassen, sobald dann einer einer Fehler findet abbrechen.

Das Verbessert die Laufzeit zumindest, wenn der Unterschied zwischen den Bildern irgendwo mitten im Bild ist, weil du sonst da erst recht spät hinkommst.

Wenn beide Bilder gleich sind wirst du allerdings kaum eine Verbesserung merken, weil die Laufzeit dann trotzdem O(n) ist.
 

beachdiddi

Mitglied
Ich denke aus oben genannten Gründen, ist eine sinnvolle und durchdachte Reihenfolge an Überprüfungen von Nöten.

wildcard hat gesagt.:
Geht es dir eigentlich um identische Bilder oder identische Dateien?

Mir geht es um identische Bilder. Es geht um einen Vergleich von Bildern auf einer Homepage, die ich mit denen in einem Ordner vergleiche. Mein Ziel ist es "geklaute" Bilder auf fremden Hp's zu entdecken.
 

Ariol

Top Contributor
beachdiddi hat gesagt.:
Mir geht es um identische Bilder. Es geht um einen Vergleich von Bildern auf einer Homepage, die ich mit denen in einem Ordner vergleiche. Mein Ziel ist es "geklaute" Bilder auf fremden Hp's zu entdecken.

Das wird allerdings schwierig mit dem Programm, wenn, wie Wildcard schon angemerkt hat, die geklauten Bilder komprimiert wurden. Dann wirst du immer eine Meldung bekommen, das die Bilder nicht gleich sind!
 

beachdiddi

Mitglied
Oh!
Das ist harter Stoff für 23 Uhr 50...
Das muss ich mir morgen mal mit einer Tasse Kaffee anschauen.

Habt ihr selbst Erfahrung mit einer Selbstorganisierenden Karte?
 

beachdiddi

Mitglied
Gut, dass es nicht nur mir so geht :wink:

Noch ein Versuch das Ganze zusammenzufassen bevor ich offline gehe:
Es gibt zwei Möglichkeiten:
1. Bilder direkt vergleichen
- Dateigröße
- Breite und Höhe
- Hashwert
- Pixelvergleich
was natürlich alles für die Katz is, falls die Bilder komprimiert werden...

2. der harte Stoff :bahnhof: : Selbstorganisierende Karte

Seh ich das so richtig, oder?
 

beachdiddi

Mitglied
Ok, danke für die super schnellen Antworten!!!
Ihr habt mir sehr geholfen. :toll:

Falls ihr noch andere Ideen habt, lasst es mich einfach wissen.

Gute Nacht,
beachdiddi
 

schalentier

Gesperrter Benutzer
Was mir noch spontan einfallen wuerde:

Du rechnest beide Bilder auf die gleiche, kleine Groesse (zb 50x50 Pixel) runter. So dass, wenn zb das Ursprungsbild 100x100 gross ist, immer aus 2x2 Bloecken ein Pixel mit dem Durchschnitt der 4 Pixel wird. Dann nimmst du die Differenz der beiden (nun gleich grossen) Bilder, errechnest die Summe der Pixel-Differenzen und ab einem Grenzwert vergleichst du (oder jemand anderes ;-) ) die beiden Originalbilder.

Nur so als Idee...
 
G

Gast

Gast
Du könntest auch die Arrays komplett durchlaufen und dir in einem weiteren Array die Differenzen speichern.

Diese Werte dann positiv noch um die Toleranz verringern (auf negative werte achten)

wenn du dann noch mehr als x Differenzen über 0 hast, wird das Bild wohl ein anderes sein.

Dann gibt es aber auch noch die Möglichkeit die Differenzen mitteinander zu vergleichen um herauszufinden, ob das bild nur anders eingefärbt wurde...


Die Selbstorganisierende Karte würde vermutlich die besten ergebnisse zurückgeben.
 

byte

Top Contributor
Du kannst auch heuristisch an das Problem herangehen, z.b. mit Hilfe von Entscheidungsbäumen (Decision Trees). Das Prinzip ist folgendes: Du definierst Dir verschiedene Metriken zum Vergleich der beiden Bilder, z.b. wie Gast gerade beschrieben hat eine Berechnung der Differenz der RGB Werte der Pixel. Dann kannst Du mit Hilfe der richtigen Algorithmen auf Basis eines Testdatensatzes einen Entscheidungsbaum aufbauen. Mit den richtigen Metriken kann man je nach Problem auf verblüffend gute Ergebnisse kommen.

Klingt sehr theoretisch, ist es auch, aber dank der Weka-Bibliothek mit Java recht easy zumzusetzen: http://www.cs.waikato.ac.nz/ml/weka/
 

beachdiddi

Mitglied
schalentier hat gesagt.:
Was mir noch spontan einfallen wuerde:

Du rechnest beide Bilder auf die gleiche, kleine Groesse (zb 50x50 Pixel) runter. So dass, wenn zb das Ursprungsbild 100x100 gross ist, immer aus 2x2 Bloecken ein Pixel mit dem Durchschnitt der 4 Pixel wird. Dann nimmst du die Differenz der beiden (nun gleich grossen) Bilder, errechnest die Summe der Pixel-Differenzen und ab einem Grenzwert vergleichst du (oder jemand anderes ;-) ) die beiden Originalbilder.

Nur so als Idee...
Mal ne blöde Frage: Wie bildest Du den Durchschnitt bei 4 Pixeln. Da steht doch in jedem Feld immer 0 oder 1 drin, oder?
Zählst Du einfach die 1er und teilst sie durch 4?
Das finde ich eine gute Idee. Wie performant ist das resizen eines Bildes?
Und den Vergleich der "Durchschnittspixel" könnte ich ja dann wieder mit verschiedenen Threads machen.


Gast hat gesagt.:
Du könntest auch die Arrays komplett durchlaufen und dir in einem weiteren Array die Differenzen speichern.
Da stehe ich ja wieder vor dem wie 'wildcard' sagt, teuren Pixelvergleich, oder?


byto hat gesagt.:
Klingt sehr theoretisch, ist es auch, aber dank der Weka-Bibliothek mit Java recht easy zumzusetzen: http://www.cs.waikato.ac.nz/ml/weka/
Klingt wirklich sehr theoretisch. ???:L
Ich habe zwar schon mal was von Entscheidungsbäumen gehört, aber nur in Verbindung mit Ausprägungen wie: kalt, warm, heiß und sehr heiß
Kannst Du die Idee noch ein bisschen genauer beschreiben?
Dienen die verschiedenen Methoden sozusagen als Entscheidungspunkte in meinem Entscheidungsbaum?
Und wie würden meine Trainingsdaten dann zum Beispiel aussehen? Viele Bilder?
 

byte

Top Contributor
beachdiddi hat gesagt.:
Ich habe zwar schon mal was von Entscheidungsbäumen gehört, aber nur in Verbindung mit Ausprägungen wie: kalt, warm, heiß und sehr heiß
Kannst Du die Idee noch ein bisschen genauer beschreiben?
Dienen die verschiedenen Methoden sozusagen als Entscheidungspunkte in meinem Entscheidungsbaum?
Und wie würden meine Trainingsdaten dann zum Beispiel aussehen? Viele Bilder?

Das stimmt schon, aber selbst bei einfachen Ja/Nein Entscheidungen (in Deinem Fall Bilder gleich oder nicht) kann man damit oft gute Ergebnisse erzielen. In Deinem Fall könntest Du als Metrik halt ne Methode schreiben, die prüft um welchen RGB Wert die einzelnen Pixel auseinander liegen. Als Testdatensatz nimmst du dann verschiedene Bilder (identische Bilder, gleiche Bilder aber anderes Format/ Komprimierung, unterschiedliche Bilder). Du gibst dem Algorithmus für diese Testdaten die Ergebnisklassifikation vor. Daraus generiert der Algorithmus (zig Classifier sind in Weka schon implementiert) dann den Entscheidungsbaum, der (je nach Güte der Testdaten und Metriken) allgemeingültig ist. Du musst in diesem Fall also keine Schwellwerte für die RGB-Differenzen festlegen.

Richtig interessant ist dieser Lösungsansatz allerdings erst, wenn man viele verschiedene Metriken (also Entscheidungsknoten) hat. Musst Du mal gucken, ob das bei Deiner Entscheidung sinnvoll ist. Die Umsetzung ist mit Weka zumindest nicht sonderlich schwierig.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
O Text aus einer Textdatei rausholen, der zwischen zwei Schlüsselworten steht Allgemeine Java-Themen 4
D Zwei Listen vergleichen Allgemeine Java-Themen 7
Tobero Wie berechnet man ob zwei Linien sich schneiden? Allgemeine Java-Themen 2
kodela Zwei gleichzeitig gedrückte Steuertasten Allgemeine Java-Themen 10
X Bedingung zwei mal überprüfen Allgemeine Java-Themen 4
Zrebna Random Number - Generische Formel zwischen zwei INKLUSIVEN Werten Allgemeine Java-Themen 16
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
D OOP Gemeinsamen ID-Raum für zwei Klassen implementieren Allgemeine Java-Themen 7
S Wenn eine Klasse zwei Interfaces mit derselben Methodensignatur implementiert: welche wird aufgerufen? Allgemeine Java-Themen 15
S Kann man Variablen oder Felder definieren deren Typ zwei Interfaces ist..? Allgemeine Java-Themen 9
K Aus String zwei Jahreszahlen auslesen Allgemeine Java-Themen 18
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
VfL_Freak Double mit zwei festen NK-Stellen ausgeben Allgemeine Java-Themen 9
Neoline Methoden Zwei Arrays abwechselnd zusammenführen Allgemeine Java-Themen 15
J Zwei Wavdateien gleichzeitig mit SourceDataLine abspielen Allgemeine Java-Themen 0
D Best Practice Die niedrigste Differenz zwischen zwei Listen ermitteln. Allgemeine Java-Themen 10
J Fahrroute zwischen zwei Punkten finden Allgemeine Java-Themen 1
J Kollision von zwei Kreisen Allgemeine Java-Themen 15
J Transfer von Integer zwischen zwei Clients - RMI Allgemeine Java-Themen 4
S Variablen split-Funkton mit zwei Variabeln verwenden? Allgemeine Java-Themen 4
T Alle Kombinationen aus zwei Arrays Allgemeine Java-Themen 8
G Liste zwischen zwei Kalenderdaten erstellen Allgemeine Java-Themen 3
AssELAss Zwei Arrays / ArrayLists inhaltlich vergleichen Allgemeine Java-Themen 2
H RegularExpression zwischen zwei Strings Allgemeine Java-Themen 2
P Zwei Applikationen mit einem Job Allgemeine Java-Themen 0
A Lineare Interpolation mit zwei Arrays Allgemeine Java-Themen 4
E Berechnung des Schnittpunktes von zwei Geraden Allgemeine Java-Themen 1
S Zwei String vergleichen, Fehler markieren Allgemeine Java-Themen 3
G Matrix reduzieren zwei Methoden Allgemeine Java-Themen 2
Dechasa Vergleichen von zwei Arrays Allgemeine Java-Themen 4
P Zwei ArrayLists: Ohne die eine überhaupt anzurühren, wird sie verändert Allgemeine Java-Themen 2
S Anwendung zum ausrechnen der Differenz von zwei Tagen Allgemeine Java-Themen 9
F Zwei LinkedHashMaps iterieren und vergleichen Allgemeine Java-Themen 2
M Zwei unterschiedliche JAR Dateien mit ANT erstellen Allgemeine Java-Themen 8
B Fehler beim Auslesen von Einstellungen. Zwei ähnliche Blöcke, nur eins geht. Allgemeine Java-Themen 5
L Zwei Files miteinander vergleichen und Grafisch darstellen Allgemeine Java-Themen 1
T Zwei Wortendungen vergleichen ohne .equals Allgemeine Java-Themen 10
F Webstart zwei Java Versionen / aktivieren bzw deaktivieren Allgemeine Java-Themen 2
S Zwei Comparable (compareTo) vergleichen Allgemeine Java-Themen 6
E zwei Gleitkommazahlen durcheinander dividieren Allgemeine Java-Themen 2
X Generic muss zwei Klassen/Interfaces erfüllen Allgemeine Java-Themen 5
turmaline OOP zwei gleiche Methoden mit kleinen Unterschieden Allgemeine Java-Themen 15
C Threads Zwei Threads greifen auf LinkedList zu. Allgemeine Java-Themen 12
T Wie heißt ein Binärbaum, dessen Knoten immer zwei Kinder haben müssen? Allgemeine Java-Themen 2
C ActionListener zwei Buttons zuweisen Allgemeine Java-Themen 11
M Eclipse drei slashs durch zwei ersetzen? Allgemeine Java-Themen 3
1 zwei Strings vergleichen Allgemeine Java-Themen 16
C Buchstaben, die in zwei Wörtern vorkommen Allgemeine Java-Themen 13
J Gleiche Packagestruktur in zwei *.jar Dateien Allgemeine Java-Themen 4
G Zwei bytes vergleichen Allgemeine Java-Themen 2
B zwei-dimensionale Collections bzw. Array mit Indizes Allgemeine Java-Themen 3
C Zwei Arrays vereinen Allgemeine Java-Themen 3
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
H Zwei verschiedene Dateien mittels einem Binärstream übertragen? Allgemeine Java-Themen 13
N hashCode() für zwei ints Allgemeine Java-Themen 5
turmaline Gleichheit von zwei Maps Map <String, Map <String, String>> Allgemeine Java-Themen 30
N Wie Listenabgleich auf zwei CPU Cores auslagern? Allgemeine Java-Themen 6
D Zufall wahr bzw. falsch mit zwei Faktoren Allgemeine Java-Themen 10
H Datenaustausch zwischen zwei Java-Programmen Allgemeine Java-Themen 5
H Ausgabe von zwei Textfeldern Allgemeine Java-Themen 3
H Zwei unabhängige Threads miteinander kommunizieren lassen Allgemeine Java-Themen 3
G zwei mal synchronized Allgemeine Java-Themen 5
Z zwei Daten vergleichen Allgemeine Java-Themen 4
C ArrayList anhand von zwei Attributen sortieren Allgemeine Java-Themen 4
S Alle Elemente von zwei Listen vergleichen Allgemeine Java-Themen 10
T IText: Zwei A4 PDF´s auf ein A3 PDF´s Allgemeine Java-Themen 2
J Verschachtelte ListIteratoren um in zwei Listen hin und herzugehen Allgemeine Java-Themen 5
A Differenz zwischen zwei Uhrzeiten Allgemeine Java-Themen 7
H Shortcut ruft zwei Menu-punkte auf Allgemeine Java-Themen 5
J Zwei konstruktoren? Allgemeine Java-Themen 8
A zwei listen vergleichen und unterschiede anzeigen Allgemeine Java-Themen 3
J Zwei sortierte Listen zusammenfassen Allgemeine Java-Themen 8
G Linked List zwischen zwei Threds übergeben Allgemeine Java-Themen 11
J zwei HashMaps vereinen Allgemeine Java-Themen 3
C Viele Informationen aus zwei Collections vergleichen Allgemeine Java-Themen 2
G Jfreechart zwei charts Allgemeine Java-Themen 2
S Zwei Anwendungen unter Tomcat Allgemeine Java-Themen 4
T Anzahl Tage zwischen zwei Daten - Stunde fehlt? Allgemeine Java-Themen 2
V Zwei ArrayList(s) vergleichen Allgemeine Java-Themen 6
T Überprüfen ob zwei Farben ähnlich sind Allgemeine Java-Themen 14
M zwei main-Methoden Allgemeine Java-Themen 7
P zwei JFrames zusammenhängen Allgemeine Java-Themen 4
A Summe und Produkt von zwei Feldern ( arrays) Allgemeine Java-Themen 9
M HashMap kapselt zwei Objekte aber wie baut man eine Matrix? Allgemeine Java-Themen 2
H zwei Date Variablen überschreiben sich Allgemeine Java-Themen 2
2 Tage zwischen zwei Datumsdaten zählen Allgemeine Java-Themen 2
G Tage zwischen zwei Datumsdaten zählen Allgemeine Java-Themen 3
J Zwei String auf ähnlichkeiten untersuchen? Allgemeine Java-Themen 3
C kürzester weg zwischen zwei Punkten, Koordinaten finden Allgemeine Java-Themen 15
L Anzahl Tage zwischen zwei Kalenderdaten Allgemeine Java-Themen 5
P Threadprogrammierung - zwei Threads parallel - einer beendet Allgemeine Java-Themen 3
G Kommunikation von zwei Java-Programmen Allgemeine Java-Themen 3
A Zusammenfassen von zwei Dateien (wie beim DOS-Befehl copy) Allgemeine Java-Themen 6
S zwei Arrays zusammenfassen Allgemeine Java-Themen 14
L Zwei Hashtables statt einer? Allgemeine Java-Themen 6
M zwei Threads - ein singleton-Objekt Allgemeine Java-Themen 3
A funktion schiffeZeichnen zwei mal aufrufen Allgemeine Java-Themen 16
G zwei Rückgabewerte gefordert. Was tun ? Allgemeine Java-Themen 10
Chucky Zwei Binärbäume vereinigen Allgemeine Java-Themen 7
B Fehler:Mein Applet kann nicht auf zwei txt-Dateien zugreifen Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben