Optimierung beim Vergleichen von 2 Bildern

raimannma

Mitglied
Hallo,

Ich habe diesen Code hier:
Java:
private static double getDifferencePercent(BufferedImage img1, BufferedImage img2) {
        int width = img1.getWidth();
        int height = img1.getHeight();
        int width2 = img2.getWidth();
        int height2 = img2.getHeight();
        if (width != width2 || height != height2) {
            throw new IllegalArgumentException(String.format("Images must have the same dimensions: (%d,%d) vs. (%d,%d)", width, height, width2, height2));
        }
        long diff = 0;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                diff += pixelDiff(img1.getRGB(x, y), img2.getRGB(x, y));
            }
        }
        long maxDiff = 3L * 255 * width * height;
        return 100.0 * diff / maxDiff;
    }
    private static int pixelDiff(int rgb1, int rgb2) {
        int r1 = (rgb1 >> 16) & 0xff;
        int g1 = (rgb1 >>  8) & 0xff;
        int b1 =  rgb1        & 0xff;
        int r2 = (rgb2 >> 16) & 0xff;
        int g2 = (rgb2 >>  8) & 0xff;
        int b2 =  rgb2        & 0xff;
        return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2);
    }

Und der funktioniert auch so ohne Problem, wenn ich also
Code:
getDifferencePercent(img1,img2)
aufrufe bekomme ich eine Prozentzahl, die mir angibt wie unterschiedlich die Bilder sind.

Allerdings sollte das mehrere Male pro Sekunde aufgerufen werden.

Mein gesamtes Programm habe ich mit VisualVM (Profiler) analysiert.
Und dabei festgestellt, dass genau diese Methode
Code:
getDifferencePercent()
für lange Ladezeiten sorgt.

Deshalb ist meine Frage, ob und wie es möglich ist diesen Code zu optimieren.

Info:
Die Bilder die verglichen werden sind nicht in Farbe sondern nur Grau, vielleicht kann man damit etwas machen.
 

Thallius

Top Contributor
Du kannst dir den raw buffer holen mit

Imagebuffer.getRaster().getDataBuffer().getData()

Dann kannst du direkt die Pixel 1:1 vergleichen und sparst dir den ganzen RGB Blödsinn.

Gruß

Claus
 

thecain

Top Contributor
R G und B müssten bei graustufen den selben wert haben. du könntest also 2 vergleiche sparen, bzw bei den raw pixeln werte überspringeb
 

mrBrown

Super-Moderator
Mitarbeiter
Vielleicht ist es noch interessant zu wissen woher er das hat:
https://www.java-forum.org/thema/hs...plikator-ermitteln.181852/page-2#post-1156599

Gefragt wurde ich natürlich nicht danach.
Besser als Klauen, ein Plagiat verstehst Du?

Du glaubst doch nicht wirklich, dass du er einzige bist, der so einen einfachen Vergleiche zwischen zwei Pixeln hinbekommt? ;)

Wäre nett, nicht gleich mit so haltlosen Unterstellungen zu kommen...
 

Thallius

Top Contributor
Wenn es wirklich nur für GRaustufen gehen muss ja. Frage ist warum du überhaupt einen RGB Buffer bekommst/nimmst wenn es nur ein Graustufenbild ist. Da würde ich eigentlich anfangen zu optimieren. Wenn Du nur ein Graustufenbild einlist hast du 1/3 weniger Daten die du laden und vergleichen musst. Das würde deutlich die Performance steigern.
 

mrBrown

Super-Moderator
Mitarbeiter
Glauben ist so eine Sache, ich würd ihn für die zukunft raten, NICHT weiter Sachen abzuschreiben. Aber das muss er wissen, welchen Preis das dann hat.
Und dir würde ich raten, solche haltlosen Unterstellungen sein zu lassen ;)
Abgesehen davon ist der Code auch noch so unglaublich einfach, dass das vermutlich selbst wenn niemand ernsthaft als abschreiben bezeichnen würde... (und wenn doch: Die Worte "Glauben ist so eine Sache" hab ich auch schon mal gesagt, du solltest sowas nicht klauen ;) )
 

NeuHier6

Mitglied
und wenn doch: Die Worte "Glauben ist so eine Sache" hab ich auch schon mal gesagt,
ja es kommt dann darauf an, wer als erstes wann was gesagt hat.

solche haltlosen Unterstellungen
Ich würd mir ja auch für ihn wünschen das ich unrecht behalte. Allerdings ist ein Pessimist Optimist mit Erfahrung und realistisch betrachtet wird das wohl nicht konsequenzfrei bleiben.

Aber was solls wiss. Arbeiten liegt nicht jedem.

ist der Code auch noch so unglaublich einfach
So trivial ist es nicht, aber naja das ist deine meinung, die zählt nicht viel.
 
1. Wenn du vermutest, daß das Bild in weiten Teilen ohnehin gleich ist, könntest du die Pixel zunächst auf Gleichheit prüfen, bevor du das Rechnen anfängst.

2. Du mußt irgendwo Abstriche machen bei der Qualität der Aussage. Also zB nur jeden zehnten Pixel überprüfen.

3. Klar, zwei von drei Farben weglassen bringt auch was. Der größte Zeitfresser ist aber eben, daß du wirklich jeden Pixel ankucken willst.

4. Du verwendest nicht ImageBuffer, sondern DataBufferByte

Vielleicht so:

Je nachdem, wie du SKIP einstellst, prüft er wirklich jede Farbe, nur die Graustufen oder eben noch seltener.

final int SKIP = 1 //echt jeden einzelnen Pixel
final int SKIP = 3 //nur Graustufen
final int SKIP = 12 //Graustufen und nur jeden vierten Pixel

Java:
    private static double getDifferencePercent(BufferedImage img1, BufferedImage img2) {
        final int SKIP = 1;

        byte[] b1 = ((DataBufferByte) img1.getRaster().getDataBuffer()).getData();
        byte[] b2 = ((DataBufferByte) img2.getRaster().getDataBuffer()).getData();
  
        int size = b1.length;
  
        if (img1.getWidth() != img2.getWidth() || img1.getHeight() != img2.getHeight()) {
            throw new IllegalArgumentException(String.format("Images must have the same dimensions: (%d,%d) vs. (%d,%d)", img1.getWidth(), img1.getHeight(), img2.getWidth(), img2.getHeight()));
        }
        long diff = 0;
        int p1=0,p2=0;
  
        for (int p = 0;p < size; p+=SKIP) {
            p1 = ((int) b1[p] & 0xff);
            p2 = ((int) b2[p] & 0xff);
            diff += Math.abs(p1 - p2);
        }

        long maxDiff = 255 * size;
        return 100.0 * diff / maxDiff;
    }

Bei einem Bild mit 901x596 braucht diese Lösung mit SKIP=1 etwa 3,5% der Zeit, mit SKIP=3 sinds noch 1,7% und mit SKIP=12 sinds 0,8%
 
Zuletzt bearbeitet:

windl

Bekanntes Mitglied
Hallo,

ich verstehe nicht wozu man die Abweichung in % zu einem Bild benötigt welches sich nur auf Pixelebene bewegt.
Weil ich gedacht habe - ich denke nicht richtig - habe ich zwei unterschiedliche Bilder eingeladen. Beide Bilder haben wirklich nichts miteinander zu tun und haben dennoch eine Ähnlichkeit von über 41%. Was sagt mir jetzt diese Zahl?
Dann habe ich eines der Bilder verkleinert und künstlich mit einem schwarzen Rand wieder auf die Größe gebracht.
Diese Bilder haben optisch eine sehr hohe Änlichkeit - aber lt. Programm gerade einmal 35%.

Wenn es Dir nur darum geht - die Anzahl der RGB's zu vergleichen - dann laufe durch jedes Bild genau einmal und speichere diese Werte ab und vergleiche beim zweiten Aufruf nur noch diese!!

Das wäre mein Vorschlag um das zu optimieren.

Gruß
Uwe
 

windl

Bekanntes Mitglied
Du addierst die einzelnen Werte und hast danach eine Summe.
Dann vergleichst Du R mit R / G mit G und B mit B.
Hat den Vorteil dass Du halt das Bild nicht immer neu scannen musst - denn die Informationen liegen ja schon vor.
 
Da bräuchten wir dann wohl mal die beiden Beispielbilder, um dir sagen zu könne, warum die so gleich (noch nichtmal ähnlich, sondern gleich) sind. Immerhin vergleichen wir da recht exakte Werte und noch nichtmal +-x zum RGB-Wert.

Aus der Summe läßt sich aber doch keine Ähnlichkeit ableiten? Nimm ein Bild 1 Pixel hoch und 200 Pixel breit. Mach die ersten 100 Pixel schwarz und die zweiten 100 machst du weiß. Die Summe ist die gleiche wie wenn du das umgekehrt hast, nämlich die ersten 100 weiß und die letzten 100 schwarz. Die Bilder sind sich aber nicht grade ähnlich.

Oder möchtest du die beiden Arrays in eines summieren, also pixelErstesBild[1] + pixelZweitesBild[1] =pixelSumme[1], und dieses Array dann durchkucken??

Ansonsten kann ich mir das grad schwer vorstellen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Optimierung beim Casten Allgemeine Java-Themen 4
M Optimierung einer Methode (byte-Geraffel) Allgemeine Java-Themen 2
L Best Practice Auslagerung von Code = Performance Optimierung? Allgemeine Java-Themen 4
F Zeit Optimierung - bzw. ms Optimierung Allgemeine Java-Themen 35
HarleyDavidson Regex - Optimierung Allgemeine Java-Themen 4
K Optimierung kürzester Weg im Warenlager Allgemeine Java-Themen 8
O Algorithmus Optimierung Allgemeine Java-Themen 3
H Optimierung durch Threads Allgemeine Java-Themen 31
C Programmflow-Optimierung Allgemeine Java-Themen 7
G Klasse Optimierung Allgemeine Java-Themen 6
N Optimierung einer Berechnung Allgemeine Java-Themen 17
S jdk versus openjdk - Optimierung von Konstanten? Allgemeine Java-Themen 8
P Optimierung (&& ||) deaktivieren / umgehen? Allgemeine Java-Themen 9
G Optimierung StringBuilder Allgemeine Java-Themen 9
S Optimierung vom Laden von Grafiken Allgemeine Java-Themen 4
S Brainstorming --> Optimierung vonn Gefälleplatten Allgemeine Java-Themen 8
berserkerdq2 Weiß jemand wie ich im Scenebuilder das Fenster so darstellen kann, dass beim Vollbildmodus die Objekte so angezeigt werden? Allgemeine Java-Themen 1
C Probleme beim Erstellen eines runnable-jar files Allgemeine Java-Themen 1
B Mysteriöse Ergebnisse beim Baccarat Programm? Allgemeine Java-Themen 13
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
A Zweite Service Klasse beim Kompilieren Allgemeine Java-Themen 6
B Java Reflection Probleme beim wehcselseitigen Referenzieren zweier Klassen/Objekte Allgemeine Java-Themen 14
B Stringmanipulationen beim Dateinamen Allgemeine Java-Themen 8
B Woher kommen die Bildschirmkoordinaten beim java Robot? Allgemeine Java-Themen 14
Alex_99 Programm stürzt beim Aufruf der Funktion ab? Text ausgeben Allgemeine Java-Themen 45
J Mein Frame friert ein beim Uploaden Allgemeine Java-Themen 4
P Selenium Scriipt zeigt Fehler beim Import Allgemeine Java-Themen 3
A Hilfe beim Verständnis Allgemeine Java-Themen 16
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
K Verbesserung der Laufzeit beim Sortieren von Einwohnern nach ihrem Geburtsjahr Allgemeine Java-Themen 0
B Compiler-Fehler Probleme beim Kompilieren mit Jsoup Allgemeine Java-Themen 8
G javamail Problem beim Empfangen von Nachrichten Allgemeine Java-Themen 3
yakazuqi Fehler beim Laden. JDA (Java Discord API) Allgemeine Java-Themen 1
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
W Suche Ursache für NPE - woher kommt sie? (Hilfe beim Debugging) Allgemeine Java-Themen 19
U Fehler beim Compillieren Allgemeine Java-Themen 13
B neuroph hält beim XOR lernen nicht an Allgemeine Java-Themen 13
bueseb84 Fehler beim Import von Maven Dependencies aus lokalem artifactory Allgemeine Java-Themen 2
J Jasper Report - seltame Meldung beim compilieren Allgemeine Java-Themen 3
J Linux .jar beim Start automatisch ausführen Allgemeine Java-Themen 6
T String-Manipulation beim Ablauf in Eclipse und als JAR-File Allgemeine Java-Themen 8
V Threads Probleme beim Aufrufen von Methoden einer anderen Klasse (Threads) Allgemeine Java-Themen 14
M Gibt es eine API die den aktuellen Wert eines Indikators beim Trading zurückgibt? Allgemeine Java-Themen 7
A Fehler beim Öffnen eines Projekts Allgemeine Java-Themen 6
L Compiler-Fehler Generics beim Anhängen von Predicates Allgemeine Java-Themen 1
J WARNING: An illegal reflective access operation has occurred, beim Compilieren von JasperReports, was bedeutet das ? Allgemeine Java-Themen 23
J Problem beim Umstellen auf Java jdk 13 Allgemeine Java-Themen 3
A Problem beim öffnen von Java-Installern Allgemeine Java-Themen 1
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
C Fehler beim Debuggen von Listen Allgemeine Java-Themen 4
L File beim Kopieren in einen anderen Ordner umbenennen Allgemeine Java-Themen 6
B Input/Output Probleme beim Ausführen von Shell-Befehlen mit Java Allgemeine Java-Themen 28
J Probleme beim einbinden von Zip4j library Allgemeine Java-Themen 6
T Compiler-Fehler NoClassDefFoundError beim Laden einer Class Allgemeine Java-Themen 11
S Seitenausrichtung beim Drucken Allgemeine Java-Themen 1
RalleYTN Brauche Hilfe beim Run-Length-Decoding Allgemeine Java-Themen 9
F SQLite mit Java / Probleme beim INSERT Befehl Allgemeine Java-Themen 4
I Fehler beim Ant-Package erstellen mit Java 9 Allgemeine Java-Themen 1
S Eclipse Probleme beim Implementieren / Ausführen von jUnit 5-Test Suites Allgemeine Java-Themen 14
M Beim Öffnen Dialog Directory und Filetype definieren Allgemeine Java-Themen 2
G Problem beim GUI Allgemeine Java-Themen 9
A Probleme beim Verstehen einer Aufgabenstellung Allgemeine Java-Themen 11
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
F Problem beim Einlesen einer Textdatei Allgemeine Java-Themen 12
J Konstruktor in JSP beim Kompilieren nicht gefunden Allgemeine Java-Themen 3
perlenfischer1984 Probleme beim Mocken Allgemeine Java-Themen 6
A Fehler beim Aktualisieren JTable Allgemeine Java-Themen 1
D Pivot-Wahl beim QuickSort steigert die Effizienz, eine Lüge??? Allgemeine Java-Themen 17
J-Gallus Erste Schritte Wahrscheinlich Anfänger Fehler beim rechnen. Falsches Ergebnis. Allgemeine Java-Themen 9
U Swing Hilfe beim Quellcode für ein Codierungs-/Decodierungsprogramm Allgemeine Java-Themen 9
Fischkralle Beim Clean Coden an den Schnittstellen geschnitten. Allgemeine Java-Themen 10
H Beim Konstruktor "this" Allgemeine Java-Themen 4
I Problem beim Aufrufen, von Objektmethoden/ -variablen Allgemeine Java-Themen 6
J Interpreter-Fehler Fehler beim Verschlüsseln Invalid AES key length Allgemeine Java-Themen 1
R probleme beim starten von jar unter linux Allgemeine Java-Themen 2
Thallius Swing Merkwürdiges Verhalten beim Panel Tausch Allgemeine Java-Themen 3
Tacofan Sound beim öffnen der GUI Allgemeine Java-Themen 8
Z NullPointerException beim Schreiben einer ArrayList in eine Datei Allgemeine Java-Themen 6
B Endlosschleife beim Verteilen von Objekten Allgemeine Java-Themen 4
V JavaFX Fehler beim Starten einer Jar Allgemeine Java-Themen 7
B Fortschritt beim Schreiben einer Datei ausgeben lassen Allgemeine Java-Themen 7
J JDK installieren Das Jdk funtioniert beim Editor nicht. Allgemeine Java-Themen 3
R Verdrückt beim Sicherheitshinweis Allgemeine Java-Themen 2
M Probleme beim rechnen, bei Zahlen mit führenden Nullen. Allgemeine Java-Themen 7
javampir Input/Output Effizienz beim binären Lesen einer Datei Allgemeine Java-Themen 6
javampir Seltsame Lücken beim Abspielen von Sound Allgemeine Java-Themen 2
RalleYTN JAnsi Warum bleiben die Hintergrundfarben beim Reseten der Konsole? Allgemeine Java-Themen 0
T BufferedImage verändert sich beim Einlsesen Allgemeine Java-Themen 1
E JCuda-0.6.5 Probleme beim ausführen der Datei Allgemeine Java-Themen 0
S Verständnisproblem beim Mocking Allgemeine Java-Themen 8
W JNDI - LDAP - Probleme beim editieren von Usern Allgemeine Java-Themen 0
Athena Programm funktioniert nur beim Debugging korrekt, sonst nicht. Allgemeine Java-Themen 1
N Zahlensysteme umrechnen; Probleme beim Umwandeln Allgemeine Java-Themen 4
K Fehler beim erstellen von .jar Datei Allgemeine Java-Themen 3
M Eclipse Fehler beim Installieren des Plugins "Jigloo" Allgemeine Java-Themen 12
A Eclipse - Fehler beim "RUN" - "Unable to Launch - The selection cannot be launched" Allgemeine Java-Themen 6
G StackoverflowError beim laden einer FXMML Datei Allgemeine Java-Themen 1
L Methoden Methode gibt mir beim verschlüsseln mit RSA 0 bytes aus ? Allgemeine Java-Themen 1
D Selenium WebDriver HtmlUnitDriver Problem beim Automatisieren Allgemeine Java-Themen 1
A Probleme beim auslesen von Quelltext (HTML) Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben