Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Bilder-Vergleichen / Farbe erkennen (https://www.delphipraxis.net/160080-bilder-vergleichen-farbe-erkennen.html)

Lifthrasir 26. Apr 2011 17:03

Bilder-Vergleichen / Farbe erkennen
 
Hello again,

um nicht im falschem Licht zu stehen das Wichtigste gleich vorweg: Ich bin ein Anfänger in Delphi auf Schulniveau und die folgenden Fragen sollen nicht dienen um aus fertigen Antworten ein Prog zu basteln und mein Namen rauf zu schreiben, sondern sollen mir nur etwas helfen..

Ich habe vor ein nützliches Programm zu schreiben, welches 2 Bilder mit einander vergleicht und die Unterschiede Aufzeigt. Auf die Idee kam ich bei nem Fehlersuchbild und dem Gedanken das doch via Delphi lösen zu müssen.
Ich setze jedoch vorraus, dass die Bilder bereits digital vorliegen und in etwa der gleichen Qualität sind.
Erweitert wurde diese Idee nun mit dem Bestreben auch weitere Bilder vergleichen zu können. Also Doppelte Bilder auf dem Rechner zu finden, ein bestimmtes Bild durch eine 'Suchmaschiene' auf der Platte wieder zu finden, bzw. ein Bild zu finden, welches ein anderes als Ausschnitt beinhaltet.

Ziel also folgende "Features":

A - Bild nach vorlage wiederfinden
B - Bilder auf Unterschiede vergleichen
C - Bild im Bild wiederfinden

Um das ganze umzusetzten dachte ich mir zwei TImages zu verwenden, da die Vorlage und das zu vergleichende Bild einladen, etwa beide auf gleich größe scalieren (Autosice false / stretch true / Image2göße an Image1 anpassen oder beide Runterskalieren) und dann über einen Befehl systematisch Pixel für Pixel, oder je nach Größe nur jeden zweiten, fünften oder zehnten Pixel vergleichen. Eine Paintbox mit Günen oder Rot werdenenden Pixeln je der Ähnlichkeit zu füllen und über eine Verhältnissgleichung der Grünen zu den Roten eine Übereinstimmung anfertigen..

Soweit schonmal nen Statement, liege ich voll falsch oder ist die Aufgabe zu groß?

Die Probleme liegen meiner Meinung nach in dem Farbvergleich. Ich meine wenn das eine Hellblau ist, würde das andere Bild mit schlechterer Qualli oder sonst aus einem Grund, an der selben KoordinatenStelle vllt ein Marineblau haben. Selbstverständlich müsste man die Farben als Code betrachten..

Und weiter frage ich mich bei dem Versuch ein Bild in einem Bild wieder zu finden, ob es Möglich ist dem Program ein Muster beizubringen, welches er im zweitem Image ja in etwa wiederfinden müsste..

Muster ist ja überhaupt das Stichwort, denn vergleichen lassen sich Bilder an sich ja nicht nur durch die Farbe sondern auch durch das Muster, sonst wäre ja ein Bild ungleich dem selbem Bild im Winter, z.B.

Ihr seht, Fragen über Fragen, mit denen ich hoffentlich nicht die Lesernerven überstrapazieren, bzw zu viel in einen Thread packen..

Ist es möglich ähnliche Farben zu vergleichen? Sehr ihr Probleme die ich übersehen, oder sollte man das Pferd anders herum aufsatteln?
Seid bitte schonungslos ehrlich, ich lerne ja erst noch :)

Gruß und danke fürs lesen

patti 26. Apr 2011 17:24

AW: Bilder-Vergleichen / Farbe erkennen
 
Also zumindest bei dem Farb-Vergleich kann ich dir helfen.

Eine RGB-Farbe besteht aus den drei Farb-Komponenten (Kanälen) Rot, Grün und Blau, wobei jeder Wert ein (vorzeichenloses) Byte ist, also Werte von 0 bis 255 annehmen kann. Den Unterschied zwischen zwei Farben kannst du beispielsweise als die durchschnittliche Differenz ihrer Kanal-Werte interpretieren:

Delphi-Quellcode:
function FarbAbweichung(c1, c2 : TColor) : byte;
var abweichung_r, abweichung_g, abweichung_b : byte;
var mittlere_abweichung : byte;
begin
abweichung_r := abs(GetRValue(c1) - GetRValue(c2));
abweichung_g := abs(GetGValue(c1) - GetGValue(c2));
abweichung_b := abs(GetBValue(c1) - GetBValue(c2));
//
mittlere_abweichung := round((abweichung_r + abweichung_g + abweichung_b) / 3);
result := mittlere_abweichung;
end;
Leg dir intern zwei Bitmaps (TBitmap) an, die die selbe Größe haben. Auf das erste Bitmap stretchst du (am besten per StretchBlt, einfach suchen) dein erstes Bild, auf dein zweites Bitmap dein zweites Bild. Dann gehst du in einer zweidimensionalen Schleife jeden Pixel durch, überprüfst die beiden Farb-Werte aus den zwei Bitmaps auf Ähnlichkeit (natürlich mit einer gewissen Toleranz) und speicherst das Ergebnis in einem zweidimensionalen Array of boolean.

Delphi-Quellcode:
var ergebnis : array of array of boolean; // natürlich in der Größe deiner Bitmaps
//
for x := 0 to breite -1 do
begin
  for y := 0 to hoehe -1 do
    ergebnis[x,y] := FarbAbweichung(bitmap1.Canvas.Pixel[x,y],bitmap2.Canvas.Pixel[x,y]) < toleranz;
end;
(lässt sich sicherlich noch alles optimieren, nur so als Denkanstoß)

Ein Array-Wert von 1 steht dann für "ähnlich", ein Wert von 0 für "unähnlich".

Das war jetzt nur eine knappe Zusammenfassung, wie ich es angehen würde. Vielleicht hilft dir das ja schonmal einen Schritt weiter ;)

Phoenix 26. Apr 2011 17:39

AW: Bilder-Vergleichen / Farbe erkennen
 
Das TImage solltest Du ganz schnell vergessen. Das Problem ist hierbei, dass das TImage das Bild selber nicht skaliert sondern nur skaliert darstellt. Das heisst Du müsstest dann nochmal einen Screenshot von dem skalierten Bild machen und versaust Dir damit das Ergebnis.

Weiteres Problem wenn Du mit unterschiedlichen Bildergrößen und Skalierungen arbeitest und, wie Du meintest, nur jedes n-te Pixel vergleichst: Allein die leichteste Verschiebung des Inhaltes um ein Pixel wird Dir je nach Inhalt ein Changeset von annähernd 100% liefern.

Du solltest bei Bildern unterschiedlicher Größen hergehen, und beim höher aufgelösten (größeren) Bild, Pixelgruppen im größenverhältnis zum kleineren Bild zusammenfassen und über deren Mittelwert berechnen (also sozusagen das größere zum Vergleich in-memory runterskalieren). Das dürfte ein besseres Ergebnis geben.

Um Verschiebungen vorzubeugen wäre es auch besser, erstmal nur eine reine Kantenerkennung zu machen (da gibts noch relativ leichte Algorithmen), und wenn in beiden Bildern ähnliche Kantenvektoren erkannt wurden, entlang dieser Kanten entsprechend skaliert zu vergleichen (rechts bzw. links von der Kante). Anhand der Kantenvektoren kannst Du dann auch einige Punkte zwischen den Kanten ermitteln und hier weitere vergleiche machen um das Ergebnis zu verbessern.

Bei den Farbvergleichen: Du musst immer mit Toleranzen arbeiten. Welche Toleranzen allerdings die besten Ergebnisse ergeben ist leider von ungeheuer vielen Faktoren abhängig. Da ist erstmal viel Ausprobieren notwendig.

Alles in allem ist das eine durchaus lösbare Aufgabe, aber unterschätze den Aufwand nicht. Das ist viel Mathe, und es ist schon schwierig das überhaupt hinzubekommen. Das dann noch performant zu lösen, so dass sich der Rechner nicht totrechnet sondern in einer ordentlichen Zeit das Ergebnis ausspuckt ist dann nochmal eine Stufe drüber.

Wie gesagt würde ich erstmal mit Kantenerkennung anfangen um überhaupt zu entscheiden ob es sich lohnt mit Farbvergleichen loszulegen. Und dann die große Frage: Soll ein Farb- und ein Schwarzweissbild als dasselbe Motiv erkannt werden oder nicht? ;-)

shmia 26. Apr 2011 19:19

AW: Bilder-Vergleichen / Farbe erkennen
 
Von turboPASCAL gibt es zum Vergleich von Bitmaps ein Demo/Tool mit Sourcecode:
http://www.delphipraxis.net/49986-%5...-scanline.html
Das könne man als Startpunkt verwenden und dann weiterentwickeln.
Man müsste den eigentlichen Vergleichsalgorithmus aus der Unit1 rausrupfen und als Klassenbibliothek bereitstellen...

Lifthrasir 27. Apr 2011 16:23

AW: Bilder-Vergleichen / Farbe erkennen
 
Vielen Dank für eure Antworten, ich werde mir mal das mit der Kantenerkennung ansehen..

Farbbereiche zusammenzuführen und dann einen Mittelwert zu bilden erscheint mir im späterem Verlauf ebenso sinnig. Schade das nun Images nicht skalieren *lach


Freue mich aber auf noch mehr Denkanstöße und Tipps, da bin ich immer sehr Dankbar

Lifthrasir 27. Apr 2011 16:53

AW: Bilder-Vergleichen / Farbe erkennen
 
Zwischenfrage:
patti und Phoenix - ihr habt beide von TBitmap bzw Bitmaps gesprochen.. Habe nun auch zwei angelegt in welche ein Probebild eingeladen wird. So weit so gut. Aber, verzeiht die blöde Frage, was passiert mit jpegs? Die kann man nicht wirklich in ein Bitmap laden, oder? :)

Danke für's Bemühen


PS:
Ich habe durch Suchfu herrausgefunden das sich jpgs ''Recht leicht'' in bmp umwandeln lassen, das wäre also der nötige vorschritt, oder?

-187- 27. Apr 2011 19:12

AW: Bilder-Vergleichen / Farbe erkennen
 
Ich glaube du brauchst die uses JPEG um ein jpg in ein TBitmap zu laden.

patti 27. Apr 2011 21:47

AW: Bilder-Vergleichen / Farbe erkennen
 
Ja, Unit JPEG einbinden und dann kann's los gehen ;)
Du kannst dann beispielsweise per
Delphi-Quellcode:
Bitmap.Canvas.Draw(0,0,jpeg);
ein JPEG auf eine Bitmap-Canvas zeichnen. Schau dir dazu mal Hier im Forum suchenTJPEGImage an.

DeddyH 28. Apr 2011 07:24

AW: Bilder-Vergleichen / Farbe erkennen
 
Man kann auch per Assign ein JPEG einer Bitmap zuweisen.

Sir Rufo 28. Apr 2011 07:45

AW: Bilder-Vergleichen / Farbe erkennen
 
Zitat:

Zitat von Lifthrasir (Beitrag 1097238)
Zwischenfrage:
patti und Phoenix - ihr habt beide von TBitmap bzw Bitmaps gesprochen.. Habe nun auch zwei angelegt in welche ein Probebild eingeladen wird. So weit so gut. Aber, verzeiht die blöde Frage, was passiert mit jpegs? Die kann man nicht wirklich in ein Bitmap laden, oder? :)
...
Ich habe durch Suchfu herrausgefunden das sich jpgs ''Recht leicht'' in bmp umwandeln lassen, das wäre also der nötige vorschritt, oder?

Hier liegt eine Verwechslung zwischen dem gespeicherten Format auf dem Datenträger und der Repräsentation im Arbeitsspeicher.

Die Basis für ein Bild ist die Klasse TBitmap. Das Bild benötigt nun im Speicher die Größe von
Code:
Breite x Höhe x Farbtiefe
.
So ein Bild kann man nun auch (logisch) speichern und zwar in verschiedenen Formaten.
JPEG, PNG, BMP

Das Bitmap-Format erzeugt sehr große Dateien, da hier das Bild eigentlich genauso abgespeichert wird, wie es im Speicher vorliegt - daher hat dieses Datei-Format auch seinen Namen bekommen ;)

Ich hoffe es wird jetzt klarer ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:21 Uhr.

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