Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Zwei übereinander liegende Bilddateien trennen !!! (https://www.delphipraxis.net/188384-zwei-uebereinander-liegende-bilddateien-trennen.html)

33Olli33 26. Feb 2016 16:09

Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo alle zusammen,
vielen Dank für die Aufnahme in dieses interessante Forum. Gleich mal meine erste Frage.
Ich habe eine .jpg-datei, die aus zwei übereinander liegenden Bildern besteht.
Das erste Bild zeigt eine Landung von Eroberern in ein fremdes Land.
Auf das Bild, oder darunter liegt ein nur zum Teil sichtbarer QR-Code, den es
zu entschlüsseln gilt.
Ich poste das Bild in der Hoffnung, dass mir jemand sagen kann, wie man das
technisch löst.
Vielen Dank im Voraus
Olli

frankyboy1974 26. Feb 2016 16:28

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
hallo,

wenn du das Originalbild ohne QR-Code hast, kannst du natürlich Pixelweise die Bilder miteinander vergleichen. Ist ein Pixel identisch, speicherst du eine Null, bei einem Unterschied zwischen Originalbild und dem Bild mit QR-Code speicherst du eine 1. Am Ende wandeltst du dein Array aus Einsen und Nullen dann in eine Schwarz/Weiss Grafik um und das sollte dann den QR-Code ergeben.

Nachtrag: Da im QR-Code die Information redundant gespeichert ist, könnte dies funktionieren.

mfg

33Olli33 26. Feb 2016 16:32

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Hallo Frankyboy,

die Idee ist schon super. Das Originalbild habe ich. Aber wie lange dauert sowas. Gibt es ein Programm, dass beide Bilder vergleicht und anschließend die differenzierten Pixel, also den QR-Code markiert oder nur darstellt?
Gruß
Olli

frankyboy1974 26. Feb 2016 16:40

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
hallo,

was heisst, wie lange dauert das? Meinst du wie lange man braucht, um sowas zu programmieren? Ich würde schätzen ein Profi braucht vielleicht eine Stunde, um sowas zu programmieren. Gibt es Programme die sowas können? Bestimmt, kann dir aber jetzt keins empfehlen. Du Kann's ja mal nach Differenzbilder googeln (oder ähnlichen).


mfg

33Olli33 26. Feb 2016 16:45

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
ok danke erstmal. Wenn ich einen Schritt weiter bin, sage ich Dir Bescheid.
Gruß Olli

Uwe Raabe 26. Feb 2016 16:56

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Häng doch das Originalbild auch mal hier dran.

33Olli33 26. Feb 2016 17:05

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier bitte

Uwe Raabe 26. Feb 2016 17:29

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Die beiden Bilder sind unterschiedlich groß. Das eine ist 800x605 und das andere 799x604. Das wird mit einem direkten Pixelvergleich nicht funktionieren.

Der schöne Günther 26. Feb 2016 17:38

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Abgesehen davon dass sichtbaren Kompressionsartefakte (JPEG-Blöcke) das sicher nicht einfacher machen ;-)

Mavarik 26. Feb 2016 17:40

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Genau...

Das ist leider nicht das gleiche Bild...

Gleich würde auch bedeuten beide Bilder als BMP...

Ansonsten 5 Min...

Leider reicht es noch nicht für eine Erkennung...

Uwe Raabe 26. Feb 2016 17:42

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Zitat:

Zitat von Mavarik (Beitrag 1331484)
Ansonsten 5 Min...

Für die Programmierung - nicht für den Vergleich, oder?

33Olli33 26. Feb 2016 17:43

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Da muss beim hochladen das eine Bild wohl ein paar Pixel verloren haben.
Beide sind 800 x 605 pixel auf meinem Laptop.
Über Paint kann ich doch bestimmen, welche Farbe innerhalb des QR-Codes verwendet wird.
Gibt es die Möglichkeit, alle betreffenden Farben in z.B. pink umzuändern?
Sowie suchen und ersetzen bei Word?

Mavarik 26. Feb 2016 17:51

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Uwe Raabe (Beitrag 1331485)
Zitat:

Zitat von Mavarik (Beitrag 1331484)
Ansonsten 5 Min...

Für die Programmierung - nicht für den Vergleich, oder?

Sehr witzig...

Bitte mal beide Bilder als BMP zum zippen. (Ein Bilderupload macht daraus immer jpg's)

33Olli33 26. Feb 2016 18:11

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Der macht beim einstellen der beiden Bilder aus BMP jetzt JPG. Will also nur JPG runterladen.
Das funktioniert nicht.

Mavarik 26. Feb 2016 18:11

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Zitat:

Zitat von 33Olli33 (Beitrag 1331490)
Der macht beim einstellen der beiden Bilder aus BMP jetzt JPG. Will also nur JPG runterladen.
Das funktioniert nicht.

s.o. Zippen

33Olli33 26. Feb 2016 18:29

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Sorry, da bin ich Nerd. Was bedeutet BMP zum zippen? Habe die beiden Bilder als .bmp-Datei gespeichert.
Und wie gehts getzt weiter?

Mavarik 26. Feb 2016 18:32

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Zitat:

Zitat von 33Olli33 (Beitrag 1331493)
Sorry, da bin ich Nerd. Was bedeutet BMP zum zippen? Habe die beiden Bilder als .bmp-Datei gespeichert.
Und wie gehts getzt weiter?

Rechte Maustaste in den Ordner,

Datei/neu/Zip-komprimierter Ordner

Beide Bilder per Drag and Drop in den Zipordner rein ziehen und den Zip-File hier hochladen...

Harry Stahl 26. Feb 2016 19:48

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Interessante Aufgabe.

Deine Bilder sind allerdings nicht wirklich identisch überlagert, sondern sind in den Ausmaßen unterschiedlich (auch sind die Pixel leicht verschoben).

Zum Testen daher anliegend Dein Originalbild und ein Neues Bild, bestehend aus dem Originalbild mit einem QR-Code hinterlegt (aus meiner Terminverwaltung einfach einen Termin-QR-Code erstellt), leicht transparent.

Mit der nachfolgenden Funktion kann man den QR-Code da raus extrahieren:

Delphi-Quellcode:
type
  TRGBALine = array[word] of TRGBQuad;
  PRGBALine = ^TRGBALine;
 
  tBuff3Char = array [0..2] of AnsiChar;
  TBufTripleCharArray = array [0..32768] of TBuff3Char;
  pBufTripleCharArray = ^TBufTripleCharArray; // Pointer auf TRGBTripleArray


function GetNewPicFromDifferences (OrgPic, NewPic, BDif: TBitmap): Boolean;
var
  x, z, Y: Integer; RGBAOrg, RGBANew, RGBADif: pRGBALine;
  LineOrg, LineNew, LineDif : pBufTripleCharArray;
begin
  Result := FALSE;

  if OrgPic.PixelFormat = pf32Bit then begin

    RGBAOrg := OrgPic.Scanline[OrgPic.Height-1];
    RGBANew := NewPic.Scanline[OrgPic.Height-1];
    RGBADif := BDif.Scanline[OrgPic.Height-1];

    z := OrgPic.Width * OrgPic.Height;

    for x := 0 to z-1 do begin
      if Integer (RGBAOrg^[x]) <> Integer (RGBANew^[x]) then begin
        Result := True;
        RGBADif^[x].rgbBlue := 0;
        RGBADif^[x].rgbred := 0;
        RGBADif^[x].rgbgreen := 0;
        RGBADif^[x].rgbReserved := 255;
      end;
    end;
  end;

  if OrgPic.PixelFormat = pf24Bit then begin
    for y := 0 to OrgPic.Height - 1 do begin
      LineOrg := OrgPic.ScanLine[y];
      LineNew := NewPic.ScanLine[y];
      LineDif := BDif.ScanLine[y];

      for x := 0 to OrgPic.Width - 1 do begin
        if LineOrg[x] <> LineNew[x] then begin
          result:= True;
          //LineDif[x] := LineNew[x];

          LineDif[x][0] := AnsiChar (0);
          LineDif[x][1] := AnsiChar (0);
          LineDif[x][2] := AnsiChar (0);
        end;
      end;
    end;
  end;
end;
Wobei ich die 32-Bit-Variante nicht getestet habe.

Die Funktion setzt voraus, dass alle Bitmaps die gleiche Größe und das gleiche Pixelformat haben, musst Du also vorher abprüfen. In Orgpic muss das Originalbild geladen werden, in NewPic das, welches das Originalbild plus den überlagerten QR-code hat. In BDif erhältst Du den extrahierten QR-Code. Mein iPhone konnte den extrahierten QR-Code einlesen und richtig auswerten.

Aber die Funktion funktioniert nur, wenn Original-Bild und neues Bild sich wirklich nur durch den hinterlegten QR-Code unterscheiden. Wenn im neuen Bild alle Pixel verschoben sind (was bei Deinem Demo-Bild der Fall ist), funktioniert die Variante hier nicht.

33Olli33 26. Feb 2016 19:52

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Bitte um Entschuldigung, es war Stromausfall.

33Olli33 26. Feb 2016 19:54

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Habe auch ein Iphone5. Mit welchem App hast Du das auslesen können? Meine können das nicht lesen.

Harry Stahl 26. Feb 2016 20:02

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
App nennt sich einfach QR von tapmedia

33Olli33 26. Feb 2016 20:11

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Oder kannst Du mir einen Bildschirmdruck von der ausgelesenen Datei hier reinstellen bitte?
Das würde mir wirklich weiterhelfen.

33Olli33 26. Feb 2016 20:55

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hatte jetzt nochmal beide Fotos in eine RAR-Datei gepackt.

Harry Stahl 26. Feb 2016 21:32

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von 33Olli33 (Beitrag 1331504)
Oder kannst Du mir einen Bildschirmdruck von der ausgelesenen Datei hier reinstellen bitte?
Das würde mir wirklich weiterhelfen.

Klar, anliegend die Ergebnis-Datei (in Zip gepackt, damit nicht so groß).

hanvas 26. Feb 2016 21:36

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von 33Olli33 (Beitrag 1331470)
Hallo alle zusammen,
Gleich mal meine erste Frage. Ich habe eine .jpg-datei, die aus zwei übereinander liegenden Bildern besteht.
Das erste Bild zeigt eine Landung von Eroberern in ein fremdes Land. Auf das Bild, oder darunter liegt ein nur zum Teil sichtbarer QR-Code, den es
zu entschlüsseln gilt.
Olli

Nachtrag : Da Harry Stahl schon eine Prozedur zum Vergleich geliefert hat (während ich den Artikel schrieb) gilt das nachfolgende natürlich nur noch für die Anpassung der beiden Bilder aneinander.

Den Hinweis das Du das Originalbild vom Bild mit QR-Code abziehen kannst haben dir ja schon mehrere gegeben. Prinzipiell ist das schon mal der richtige Ansatz.

Mit den unterschiedlichen Größen von Referenzbild und Abbildung kannst Du auf verschiedene Arten umgehen, um nicht mit der Bazooka loszumarschieren [1] kannst Du Dir eine einfache Form von Bildregistrierung selbst basteln :

Wenn die Bilder sich nur in der Größe unterscheiden dann kannst Du eines der Bilder natürlich einfach skalieren. Da die Seitenverhältnisse bei beiden Bildern gleich sein müssten dürfte eine Skalierung eine relativ gute Abbildung ergeben.

Alternativ dazu kannst Du natürlich auch ohne Skalierung auskommen und einfach die Koordinaten umrechnen um für jeden Punkt (X,Y) im Bild 1 einen Punkt(X,Y) im Bild 2 zu bekommen.

Ist das Bild darüber hinaus verzerrt dann musst Du Dir drei oder vier Stützpunkte suchen die in beiden Bildern an der gleichen Position vorkommen. Diese Stützpunkte kannst Du mittels Template-Matching in beiden Bildern suchen (dazu kannst Du beispielsweise OpenCV verwenden) und wendest anschließend eine bilineare Interpolation auf das zu transformierende Bild an. (https://en.wikipedia.org/wiki/Bilinear_interpolation)

1. Anschließend gehst Du den bereits vorgeschlagenen Weg und erstellst Die eine SW - Maske die die gleichen Ausmaße wie Deine Bilder hat. An der Stelle an der der sich das Abbild vom Original unterscheidet setzt Du einen schwaren Punkt. Die weißen Quadrate des QR-Codes kannst Du auf diese Art zunächst nicht finden, denn Dein Bild sieht so aus als ob Weiß den Farbwert der Abbildung nicht beeinflusst, aber das dürfte keine Rolle spielen.

Wenn Du Glück hast, dann war es das. Du müstest Dir nur noch die Bounding-Box Deiner Maske suchen (als das minimale Quadrat das alle schwarzen Pixel einschließt) um diesen Bereich zu kopieren und du hättest Deinen QR-Code gefunden.

Die meisten der hier genannten und notwendigen Verfahren, einschließlich bilinearer Interpolation und logischen oder arithmetischen Operationen auf Bildern (Bilder mit OR,UND,SUB usw. bearbeiten) sind übrigens in Leptonica (www.leptonica.org/) implementiert.

Ich habe mir erlaubt eine selbst compilierte DLL und eine unvollständig getestete Headerübersetzung anzuhängen. Möglicherweise kannst Du ja was damit anfangen. Wenn etwas nicht funktioniert ist anstelle eines var XXX eine pXXX als Parameter verlangt (oder umgekehrt).

Leptonica steht unter der BSD Lizenz.

In Anbetracht des Umfangs bitte ich zu verzeihen das ich nur die Funktionen getestet habe die ich selbst verwende.

[1] http://www.itk.org/
Numerical Methods for Image Registration, ISBN 978-0-19-852841-8
2-D and 3-D Image Registration, ISBN 978-0-471-64952-0

Uwe Raabe 26. Feb 2016 21:37

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Geht auch mit geringfügig weniger Zeilen:
Delphi-Quellcode:
function GetNewPicFromDifferences (OrgPic, NewPic, BDif: TBitmap): Boolean;
begin
  BDif.Assign(OrgPic);
  result := BitBlt(BDif.Canvas.Handle, 0, 0, BDif.Width, BDif.Height, NewPic.Canvas.Handle, 0, 0, SRCINVERT);
  if result then begin
    BDif.Mask(clBlack);
  end;
end;

Harry Stahl 26. Feb 2016 22:12

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von 33Olli33 (Beitrag 1331508)
Hatte jetzt nochmal beide Fotos in eine RAR-Datei gepackt.

Jetzt sind die Bilder zwar gleich groß und das Bild ist von der Positionierung der Pixel auch gleich, allerdings weichen die Werte für die einzelnen Pixel auch da voneinander ab, wo kein QR-Code hinterlegt ist. Das kann z.B. durch eine JPG-Komprimierung entstanden sein.

Zum Beispiel hat das erste Pixel einmal 224,225,193 und im anderen Bild 231,231,180.

Selbst wenn man jetzt eine Toleranz-Option einbaut

Delphi-Quellcode:
  w1 := (Byte (LineOrg[x][0]) + Byte (LineOrg[x][1]) + Byte (LineOrg[x][2])) Div 3;
  w2 := (Byte (LineNew[x][0]) + Byte (LineNew[x][1]) + Byte (LineNew[x][2])) Div 3;
  dif := Abs (w2-w1);

  if (dif > Tolerance) then begin
kommt man leider nur zu unbefriedigenden Ergebnissen, siehe Screenshot (hier mit Wert "5").

Harry Stahl 26. Feb 2016 22:16

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1331512)
Geht auch mit geringfügig weniger Zeilen:
Delphi-Quellcode:
function GetNewPicFromDifferences (OrgPic, NewPic, BDif: TBitmap): Boolean;
begin
  BDif.Assign(OrgPic);
  result := BitBlt(BDif.Canvas.Handle, 0, 0, BDif.Width, BDif.Height, NewPic.Canvas.Handle, 0, 0, SRCINVERT);
  if result then begin
    BDif.Mask(clBlack);
  end;
end;

Cool!

33Olli33 26. Feb 2016 22:20

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Leute, Ihr habt schon viel zu viel für mich getan. Ich werde den QR mal meinem Rätselsteller mitteilen und schauen, was der sagt.
Ich bin morgen wieder hier und gebe gerade Meldung, ob das gepasst hat.
Vielen Dank an Euch :)

Gruß Oliver

hanvas 26. Feb 2016 23:27

AW: Zwei übereinander liegende Bilddateien trennen !!!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Harry Stahl (Beitrag 1331513)
Zitat:

Zitat von 33Olli33 (Beitrag 1331508)
Hatte jetzt nochmal beide Fotos in eine RAR-Datei gepackt.

Jetzt sind die Bilder zwar gleich groß und das Bild ist von der Positionierung der Pixel auch gleich, allerdings weichen die Werte für die einzelnen Pixel auch da voneinander ab, wo kein QR-Code hinterlegt ist. Das kann z.B. durch eine JPG-Komprimierung entstanden sein.

Wenn man das Referenzbild um einen einige Pixel breiten Rahmen erweitert und anschließend beide Bilder in ein klein wenig verwackelt bzw. die Werte der Pixel über die Nachbarpixel interpoliert (https://processing.org/examples/blur.html), dann in Graustufen konvertiert und ein Template-Matching durchführt - also die Abbildung pixelweise über das Referenzbild verschiebt und so die Koordinaten für die maximale Übereinstimmung ermittelt, anschließend wieder das eine Bild vom anderen abzieht (mit der von Dir angegebenen Toleranz arbeitet), das Ergebnis in ein Schwarzweissbild verwandelt, und anschließend die nicht verbundenen Komponenten unterhalb einer bestimmten Schwelle (z.b. 120 Pixel) also als Pixelverbunde die weniger als 120 zusammenhängende Pixel aufweisen entfernt, eine Segmentierung durchführt in der das verbleibende Quadrat "außgestanzt" wird (YX-CUT), dann kommt man zu den folgenden Ergebnis.

Das ist eigentlich schon recht gut. Da dieser Code durch Quadrate gebildet wird, könnte man versuchen die Länge/Breite eines der Quadrate zu ermitteln, das Bild in entsprechende Quadrate/Zellen unterteilen, für jede Zelle prüfen ob mehr als 50 % Pixel gesetzt sind. Ist das der Fall dann wird das Quadrat ausgefüllt, ist das nicht der Fall dann wird das Quadrat nicht ausgefüllt.

Das dürfte dann noch nicht perfekt sein aber doch schon sehr gut.

cu Ha-Jö


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:40 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