Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Bitmaps vergleichen (https://www.delphipraxis.net/204883-bitmaps-vergleichen.html)

Amateurprofi 9. Jul 2020 18:25

Bitmaps vergleichen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier https://www.delphipraxis.net/204093-...ermitteln.html wurde seinerzeit gefragt, wie man in 2 Bitmaps mit gleicher Größe, die sich nur in einem bestimmten rechteckigen Bereich voneinander unterscheiden und ansonsten identischen Inhalt haben, diesen Bereich möglichst schnell (< 1 Sekunde) ermitteln kann.
Ich hatte seinerzeit eine kleine Funktion gepostet, die diese Aufgabe erledigte und dafür, bei Bitmaps mit ca. 16 MPixeln, < 50 ms brauchte.
Da mich das Thema interessierte, habe ich mich etwas intensiver damit beschäftigt und ein Programm erstellt, das einiges mehr kann, als die seinerzeit gepostete Funktion.
Das Programm, Stand Juli 2020, unterstützt im Wesentlichen folgende Aktivitäten.
- Bilder laden.
Unterstützt werden die Formate *.Bmp;*.Gif;*.Jpg;*.Png;*.Tif;*.Wmf;*.Emf.
Bei Formaten <> *.Bmp werden die Bilder in 24Bit-Bitmaps umgewandelt.
- Komplette Bitmaps vergleichen
- Einen definierten rechteckigen Bereich vergleichen.
- 2 gleichgroße rechteckige Bereiche vergleichen die an unterschiedlichen Positionen liegen.
- Die Bitmaps anzeigen.
Die Bitmaps, die verglichen werden, dürfen unterschiedliche Pixelformate haben.
Unterstützt werden die Formate pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit,
Nach Laden von Bildern werden diese automatisch verglichen und folgende Daten ermittelt und angezeigt:
- Rechteck, innerhalb dessen Unterschiede gefunden wurden.
- Liste der unterschiedlichen Pixel.
- Liste welche Farben wie oft in den Bitmaps vorkommen.

Im Anhang sind das Programm (.exe), alle Source-Codes (hoffentlich nichts vergessen) und eine ausführliche .hlp Datei.
Die mitgelieferte .exe ist eine 32Bit Version, das Ganze sollte aber auch für 64Bit kompilierbar sein.
Ich habe eine kontext-sensitive implementiert, die mit F1 aufgerufen wird.
Es wird hierbei versucht, die Hilfe zu dem Objekt zu zeigen, auf das die Maus zeigt.
Das sollte projektweit funktionieren, auch für die Einträge von Menus, hier aber nur auf der untersten Ebene.

Tipp:
Da das Programm auch unterschiedliche Farbmodelle (HSB, HSL, XYZ, CMY) unterstützt wird beim Programmstart eine Farbtabelle erzeugt, die die Daten für Umwandlung von RGB nach HSB, HSL und XYZ enthält.
Um die volle Funktionalität des Programms zu erhalten sollte nach dem ersten Programmstart mit Menu > Datei > "Farbtabelle um RAL-Farben ergänzen" die Farbtabelle vervollständigt werden (dauert ca. 35 s, deshalb nicht automatisch) und anschließend die Tabelle mit Menu > Datei > "Farbtabelle speichern" gespeichert werden.
Bei anschließenden Programmstarts wird dann die Tabelle aus dieser Datei geladen.

Vielleicht interessiert das den einen oder anderen.
Das Programm enthält sicher noch einige Bugs - wer solche findet, bitte posten, ggfs. auch als PN.

Jasocul 10. Jul 2020 07:34

AW: Bitmaps vergleichen
 
Klingt interessant. :thumb:

Ich habe da tatsächlich Ideen, wofür man das gebrauchen kann:
- Erkennen von Steganografie
- Vergleich bei Bilddiebstahl
- Manipulationserkennung
- Was verändern Bildbearbeitungsprogramme
Gibt bestimmt noch mehr.

Ich muss mal sehen, wann ich Zeit für Experimente habe.

Rollo62 10. Jul 2020 12:39

AW: Bitmaps vergleichen
 
Sehr schön, dankesehr :thumb:

Zwei Fragen:
Du schreibst dass Du Alles in 24-Bit wandelst, auch 32-Bit Bilder.
Warum nimmst Du nicht gleich 32-Bit, so wie Graphics32 ?
Hat der 24-Bit Raum irgendwelche Vorteile für Dich ?

Mit den RAL-Farben verstehe ich nicht ganz.
Das sind Printfarben, die kann man doch eigentlich nicht am Bildschirm darstellen.
Ist das die nächstbeste Farbe die der RAL entspricht, oder
gibt es einen "offiziellen" Algorithmus der irgendeine Farbe zu RAL umwandeln kann ?

Amateurprofi 11. Jul 2020 03:54

AW: Bitmaps vergleichen
 
Zitat:

Zitat von Rollo62 (Beitrag 1469291)
Sehr schön, dankesehr :thumb:

Zwei Fragen:
Du schreibst dass Du Alles in 24-Bit wandelst, auch 32-Bit Bilder.
Warum nimmst Du nicht gleich 32-Bit, so wie Graphics32 ?
Hat der 24-Bit Raum irgendwelche Vorteile für Dich ?

Mit den RAL-Farben verstehe ich nicht ganz.
Das sind Printfarben, die kann man doch eigentlich nicht am Bildschirm darstellen.
Ist das die nächstbeste Farbe die der RAL entspricht, oder
gibt es einen "offiziellen" Algorithmus der irgendeine Farbe zu RAL umwandeln kann ?

Zitat:

Du schreibst dass Du Alles in 24-Bit wandelst, auch 32-Bit Bilder
Ich schrieb "Bei Formaten <> *.Bmp werden die Bilder in 24Bit-Bitmaps umgewandelt.", also:
Nur wenn zum Beispiel ein .jpg geladen wird, wird die in eine 24Bit Bitmap umgewandelt.
Wenn eine .bmp Datei geladen wird, bleibt die im Original-Format.
Ausnahme:
Wenn bei einer .bmp Datei das Pixelformat=pfCustom und biBitCount=16 ist, wird das so gehandhabt:
A) Die Datei enthält Masken für Rot, Grün, Blau.
Dann wird aus den Masken entweder pf15bit oder pf16bit abgeleitet.
B) Die Datei enthält keine Farbmasken.
Dann werden die Farbmasken RMask:=$7C00; GMask:=$03E0; BMask:=$001F; benutzt und als PixelFormat pf15bit.
Da habe ich unsauber gearbeitet.
Korrekterweise sollte ich in diesem Fall alle 16Bit-Farbwerte der Bitmap prüfen.
Wenn zumindest bei einem Pixel das höchste Bit gesetzt ist sollte ich die Standardmasken für pf16Bit verwenden und als Pixelformat pf16bit.
Das werde ich in den nächsten Tagen ändern.
Danke für die Rückfrage - erst dadurch habe ich registriert, dass ich das Pixelformat aus den Farbdaten ableiten kann.

Zitat:

Warum nimmst Du nicht gleich 32-Bit, so wie Graphics32 ?
Hat der 24-Bit Raum irgendwelche Vorteile für Dich ?
Aus Gewohnheit und aus Speicherplatz-Gründen.
Die Umwandlung in 24Bit Bitmaps erfolgt ja nur bei Dateiformaten <> .bmp und z.B. JPEG kann nur pf8bit und pf24bit, zumindest die mir vorliegende Version.

Zitat:

Mit den RAL-Farben verstehe ich nicht ganz.
Das sind Printfarben, die kann man doch eigentlich nicht am Bildschirm darstellen.
Ist das die nächstbeste Farbe die der RAL entspricht, oder
gibt es einen "offiziellen" Algorithmus der irgendeine Farbe zu RAL umwandeln kann ?
Ich ordne einem RGB-Wert die RAL-Farbe zu, bei der die maximale Abweichung der Rot-, Grün-, Blauwerte am kleinsten ist.
Ein "offizieller" Algorithmus ist mir nicht bekannt.
Bei der Tabelle der RAL-Farben handelt es sich um die RAL-Classic-Farben.
Die hab ich vor ein paar Jahren auf http://www.ral-farben.de gefunden.
Delphi-Quellcode:
FUNCTION NearestRalColorIndex(CL:TColor):Integer;
var I,D,MinD:Integer;
begin
   MinD:=MaxInt;
   Result:=0;
   for I:=0 to High(RalColors) do
      with RalColors[I], TRgb(CL) do begin
         D:=Max(Max(Abs(Red-R),Abs(Green-G)),Abs(Blue-B));
         if D<MinD then begin
            MinD:=D;
            Result:=I;
         end;
      end;
end
;

Sinspin 12. Jul 2020 15:25

AW: Bitmaps vergleichen
 
Hallo. Sehr interessantes Projekt.
Dann sollte ich mit dem Programm auch in der Laage sein Bilder zu finden die zweimal mit unterschiedlicher Kompression gespeichert wurden sind oder an deren einer Version ein Stück abgeschnitten wurde.

Was ich aber nicht verstehe warum Du mit einer Farbtabelle arbeitest? Oder dient die nur der Umrechnung zwischen den Farbräumen?

Ich schreibe an einem Programm zum automatischen farblichen Angleichung von Bildern. Da hat sich RGB als eher ungeeignet herausgestellt.
Durch die Verwendung von HSV als Farbraum kann ich Farbe, Sättigung und Helligkeit einzeln betrachten und vergleichen. Verschiedene Formen und Objekte sind oft erstaunlich genau differenzierbar. Ich denke mal das läuft bei deinem Tool ähnlich.

Lohnt sich an irgend einer Stelle eine Farbtiefe höher als 24 Bit (8 Bit je Kanal)? 32 Bit verwendet man doch eigentlich nur wenn man Transparenz (via 8 Bit Alpha kanal) im Bild verwenden will oder den Zugriff auf Speed optimieren möchte.

Amateurprofi 12. Jul 2020 19:34

AW: Bitmaps vergleichen
 
Zitat:

Zitat von Sinspin (Beitrag 1469408)
Hallo. Sehr interessantes Projekt.
Dann sollte ich mit dem Programm auch in der Laage sein Bilder zu finden die zweimal mit unterschiedlicher Kompression gespeichert wurden sind oder an deren einer Version ein Stück abgeschnitten wurde.

Was ich aber nicht verstehe warum Du mit einer Farbtabelle arbeitest? Oder dient die nur der Umrechnung zwischen den Farbräumen?

Ich schreibe an einem Programm zum automatischen farblichen Angleichung von Bildern. Da hat sich RGB als eher ungeeignet herausgestellt.
Durch die Verwendung von HSV als Farbraum kann ich Farbe, Sättigung und Helligkeit einzeln betrachten und vergleichen. Verschiedene Formen und Objekte sind oft erstaunlich genau differenzierbar. Ich denke mal das läuft bei deinem Tool ähnlich.

Lohnt sich an irgend einer Stelle eine Farbtiefe höher als 24 Bit (8 Bit je Kanal)? 32 Bit verwendet man doch eigentlich nur wenn man Transparenz (via 8 Bit Alpha kanal) im Bild verwenden will oder den Zugriff auf Speed optimieren möchte.

Zitat:

Dann sollte ich mit dem Programm auch in der Laage sein Bilder zu finden die zweimal mit unterschiedlicher Kompression gespeichert wurden sind oder an deren einer Version ein Stück abgeschnitten wurde.
Ich denke Ja.

Zitat:

Was ich aber nicht verstehe warum Du mit einer Farbtabelle arbeitest? Oder dient die nur der Umrechnung zwischen den Farbräumen?
Die Farbtabelle enthält für jede der 256^3 RGB-Farben:
Für das HSB-Modell die Werte für Hue, Saturation, Brightness.
Für das HSL-Modell die Luminanz (Hue und Saturation sind wie bei HSB).
Für das XYZ-Model die X-, Y-, Z-Werte.
Welchem Farbbereich die Farbe zugeordnet ist.
Welche RAL-Farbe der RGB-Farbe zugeordnet ist.
Als Farbbereiche habe ich vorgesehen
Delphi-Quellcode:
   ColorRangeText:Array[TColorRange] of String=
      ('Rot','Orange','Gelb','Gelbgrün','Hellgrün','Grün','Dunkelgrün',
       'Seegrün','Cyan','Blau','Violett','Magenta','Pink','Rosa','Braun','Oliv',
       'Weiß','Grau','Schwarz');
Im Prinzip könnte man die Daten immer dann, wenn sie benötigt werden, errechnen.
Wenn es aber ums Sortieren zum Beispiel der Liste mit den Anzahlen der verschiedenen Farben geht, macht es sich schon bemerkbar, wenn ich die Daten bei jedem Vergleich berechne.
Lade einfach mal ein schönes großes Landschaftsbild mit 15MPixeln.
Dann klicke im HeaderControl der untersten Liste die Sektion "H" und dann mit gedrückter Ctrl-Taste "S" und "B".
Danach ist die Liste nach Hue, Sat, Bright sortiert.
Und dann klicke Menu > Info > "Sortieren der Farbanzahlen".
Unter anderem siehst du da, wie oft beim Sortiervorgang zwei Records verglichen wurden.
Wenn man nun bei jedem Vergleich die Werte neu errechnen würde ...
Die Prozedur, die die Liste sortiert
Delphi-Quellcode:
PROCEDURE TMain.SortCountsList;
findest du in der Unit DR_Main, irgendwo bei Zeile 4800 oder so.
Zitat:

Durch die Verwendung von HSV als Farbraum kann ich Farbe, Sättigung und Helligkeit einzeln betrachten und vergleichen. Verschiedene Formen und Objekte sind oft erstaunlich genau differenzierbar. Ich denke mal das läuft bei deinem Tool ähnlich.
Nein. Es werden nur RGB-Werte verglichen.

Zitat:

Lohnt sich an irgend einer Stelle eine Farbtiefe höher als 24 Bit (8 Bit je Kanal)? 32 Bit verwendet man doch eigentlich nur wenn man Transparenz (via 8 Bit Alpha kanal) im Bild verwenden will oder den Zugriff auf Speed optimieren möchte.
Wenn man dem https://de.wikipedia.org/wiki/Windows_Bitmap vertrauen möchte, ist das, was man landläufig als Alphakanal bezeichnet, nicht wirklich fest definiert.
M.E. bringt es (bei diesem Projekt) keine Zeitvorteile mit 32Bit-Bitmaps zu arbeiten.
Vor allem ist das Programm ja gerade darauf ausgerichtet, auch Bitmaps mit unterschiedlichen Formaten zu vergleichen.
Na klar könnte man bei Laden eines Bildes dieses in pf32bit umwandeln. Das würde die Vergleichsroutine vereinfachen und sicherlich auch etwas schneller machen. Allerdings gehen dabei auch Informationen verloren zum Beispiel bei pf1bit..pf8bit die Indizes in die Palette und bei pf15bit und pf16bit die Originalwerte aus der Bitmap.

Sinspin 13. Jul 2020 08:36

AW: Bitmaps vergleichen
 
Danke für die ausführliche Erklärung. :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf