AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Bildanalyse/-vergleich

Bildanalyse/-vergleich

Ein Thema von Slashmob · begonnen am 8. Dez 2011 · letzter Beitrag vom 11. Dez 2011
Antwort Antwort
Seite 1 von 5  1 23     Letzte » 
Slashmob

Registriert seit: 28. Okt 2011
45 Beiträge
 
#1

Bildanalyse/-vergleich

  Alt 8. Dez 2011, 17:31
Guten Tag zusammen,

ich möchte das untenstehende Projekt bearbeiten, das ich allerdings inhaltlich nicht ganz verstehe und mir somit die konkrete Umsetzung sehr schwer fällt.

Hier ist die Aufgabenstellung:

__________________________________________________ __________________________________________________ _____
Es sollen zwei Bilder des identischen Bereichs des Sternhimmels untersucht werden, die zu verschiedenen Zeiten aufgenommen wurden.
Es handelt sich um Grauwertbilder, von denen der Einfachheit halber nur der Rotanteil zur Auswertung benutzt wird (d.h. die Pixelfarben sind mit der Rotmaske zu maskieren).

Das Projekt enthält eine Funktion TForm1.floodfill_(x,y,fillColor,oldColor:integer), die eine mit einer Farbe umgrenzten Fläche ausfüllt.
Es handelt sich um eine rekursive Funktion.(Wie funktioniert die Funktion? Welche Farbkombination von RGB liefern graue Pixel?)

Für das Programm ist es notwendig ein ausgefülltes Quadrat der Fläche n*n an einer beliebigen Position (x,y=linke obere Ecke) in die vier Imagefelder zeichnen zu können.

Hierfür ist die Prozedur TForm1.quadratmalen(image,top_,left_,kantenlaenge, farbe:integer) zu erstellen, die mittels CASE das Zielimage (Image3) bedient.
Mit Hilfe der Parameter ist die Farbe einzustellen und dann vom linken oberen Eckpunkt aus mit vier Linien der Umriss des Quadrats zu zeichnen. Wird mit Farbe "rot" gezeichnet,
soll danach auf den rechten/unteren Punkt gesetzt werden, der noch nicht rot ist, sich also innerhalb des roten Kastens befindet. Dies ist der Startpunkt für die Floodfill-Funktion.
Dieser innere Punkt existiert erst ab der Kantenlänge 3.
Bei kleineren Kantenlängen wird nicht gezeichnet.

Die eigentliche Prozedur ist nun so zu programmieren, dass Pixel für Pixel das Ausgangsbild (Image1) mit dem Vergleichsbild (Image2) verglichen wird.
Man bildet dazu einfach den Absolutwert der Differenz der Pixel mit den gleichen Koordinaten.
Ist dieser Wert größer als der Schwellwert (Voreinstellung: Grauwert 10),
so ist an dieser Koordinate das rote Quadrat in Image3 zu zeichnen.

Gleichzeitig ist der Differenzwert zusammen mit der laufenden Nummer und Koordinate in ein Stringfeld einzutragen.
Jedes Mal, wenn sich die laufende Nummer der entdeckter Differenzen erhöht,
ist auch die Länge des Stringgrid-Feldes um eins zu erhöhen (Eigenschaft rowcount)

Sollte nun ein benachbarter Punkt innerhalb der Kantzenlänge des Quadrats liegen,
so ist er bei der Untersuchung zu ignorieren.
Zur Entscheidung dazu nutzt man die roten Pixel im Image3.
In das weiße Image4 werden die gefundenen Einzelpunkte in roter Farbe eingetragen.

Im Image4 sollten genauso viele Punkte sein, wie Quadrate in Image3 oder Zeilen im Stringgrid.
__________________________________________________ __________________________________________________ _______
Wie es fertig aussehen und funktionieren soll ist im Anhang als Bild dargestellt.


Als Hilfe haben wir schon einen Teil des Codes bekommen:
Delphi-Quellcode:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Grids, Spin;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Label1: TLabel;
    Label2: TLabel;
    SpinEdit1: TSpinEdit;
    SpinEdit2: TSpinEdit;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure floodFill_(x,y,fillColor,oldColor: integer);
    procedure quadratmalen(image,top_,left_,kantenlaenge,farbe:integer);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  b,h:integer;
implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
     b:=image1.width; h:=image1.height; // Breite und Höhe der Imagefelder
     image2.width:=b; image2.height:=h;
     image3.width:=b; image3.height:=h;
     image4.width:=b; image4.height:=h;

     image1.canvas.brush.color:=clblack; // Hintergrundfarben
     image2.canvas.brush.color:=clblack;
     image3.canvas.brush.color:=clblack;
     image4.canvas.brush.color:=clwhite;

     image1.canvas.fillrect(rect(0,0,b,h)); // Rechteck mit obigen Farben ausfüllen
     image2.canvas.fillrect(rect(0,0,b,h));
     image3.canvas.fillrect(rect(0,0,b,h));
     image4.canvas.fillrect(rect(0,0,b,h));

     image1.Picture.loadfromfile('1sw.bmp'); // Bilder hochladen
     image2.Picture.loadfromfile('pic2.bmp');

     form1.caption:= 'Bildanalyse-Suche nach Vergleichsschwankungen';
end;

procedure tform1.floodFill_(x,y,fillColor,oldColor: integer);
   begin
         // Wie arbeitet diese Füllfunktion?
   with image3.canvas do
   if (pixels[x,y]=oldColor) then
      begin
      Pixels[x,y]:= fillcolor;
      floodFill_(x+1,y, fillcolor, oldColor);
      floodFill_(x-1,y, fillcolor, oldColor);
      floodFill_(x,y+1, fillcolor, oldColor);
      floodFill_(x,y-1, fillcolor, oldColor);
   end;
end;

procedure tform1.quadratmalen(image,top_,left_,kantenlaenge,farbe:integer);
   var km1:integer;

   begin
   km1:=kantenlaenge-1;

   // hier Programmierung des Quadrats in jedem Image 1-4
   // mittels zeichnen der Kanten aus 4 linien
   // und dann Füllen mit Füllfunktion
   // nur 3 wird benutzt
   case image of
      1:
         with form1.image1.canvas do
            begin
         end;
      2:
         with form1.image2.canvas do
            begin
            end;
      3: // der Fall wird im Programm benutzt
         with form1.image3.canvas do
            begin

         end;
      4:
         with form1.image4.canvas do
            begin
         end;
      end;
   end;

procedure TForm1.Button1Click(Sender: TObject);
Var i, // Laufindex
    farbe1, // Pixelfarbe im Image1
    farbe2, // Pixelfarbe im Image2
    wert, // Differenzwert
    schwellwert, // Schwellwert zum Vergleich
    zeile,
    grid_zeilennr, // Zeilennummer im Grid
    sz, // Spaltenzahl
    zz, // Zeilenzahl
    kantelange // Kantenlänge des Quadrats
            :integer;

begin
     grid_zeilennr:=0;
     i:=0;
     schwellwert:=spinedit1.value; // Voreinstellung 10
     kantelange:=spinedit2.value; // minimal 3
     stringgrid1.cells[0,grid_zeilennr]:='Nr.';
     stringgrid1.cells[1,grid_zeilennr]:='Diff-Wert';
     stringgrid1.cells[2,grid_zeilennr]:='x';
     stringgrid1.cells[3,grid_zeilennr]:='y';
     // hier weiter programmieren
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

end.
Nun meine Fragen hierzu:
1) Was ist damit gemeint
Zitat:
Es handelt sich um Grauwertbilder, von denen der Einfachheit halber nur der Rotanteil zur Auswertung benutzt wird (d.h. die Pixelfarben sind mit der Rotmaske zu maskieren).
2)Wie genau funktioniert diese Funktion?
Zitat:
TForm1.floodfill_(x,y,fillColor,oldColor:integer)
Ich weiß, dass eine rekursive Funktion sich quasi "selbst aufrufen" kann.
Was bedeuten die Parameter fillColor und oldcolor? (vgl.obenstehenden code)
Auf die Frage
Zitat:
Welche Farbkombination von RGB liefern graue Pixel?)
würde ich ich sagen: $00ffffff.

3)Die Prozedur
Zitat:
TForm1.quadratmalen(image,top_,left_,kantenlaenge, farbe:integer)
versteh ich nicht ganz. Was bedeuten die beiden Parameter "top_" und "left_"?? Wie soll ich damit ein Quadrat malen?

4)
Zitat:
Die eigentliche Prozedur ist nun so zu programmieren, dass Pixel für Pixel das Ausgangsbild (Image1) mit dem Vergleichsbild (Image2) verglichen wird. Man bildet dazu einfach den Absolutwert der Differenz der Pixel mit den gleichen Koordinaten. Ist dieser Wert größer als der Schwellwert (Voreinstellung: Grauwert 10), so ist an dieser Koordinate das rote Quadrat in Image3 zu zeichnen.
Wie kann ich die beiden Bilder Pixelweise vergleichen?

Hab schon bisschen dran gearbeitet, aber wie gesagt komme hier nicht wirklich weiter, weil mich die obigen Fragen quälen.
Vielleicht werdet ihr schlauer aus der ganzen Sache als ich.
Wäre über jeden Tipp und Ansatz dankbar!

Gruß Slash
Miniaturansicht angehängter Grafiken
ab33lqmj.png  

Geändert von Slashmob ( 8. Dez 2011 um 17:35 Uhr)
  Mit Zitat antworten Zitat
freeway

Registriert seit: 11. Jul 2009
57 Beiträge
 
Delphi XE Professional
 
#2

AW: Bildanalyse/-vergleich

  Alt 8. Dez 2011, 18:13
1) Ausmaskieren ? keine Ahnung aber getpixel oder scanline erfüllen den selben zweck

2) fillColor Farbe die ausgegeben werden soll
oldcolor Farbe die ersetzt werden soll

$00ffffff würde weiss entsprechen, $007F7F7F wäre dann ein Grauton

3)top_ left_ ist die Startposition und über die Kantenlänge wird bottom und right berechnet

4) dazu gibt es hier schon einige Beiträge z.B. --> http://www.delphipraxis.net/80639-bi...rgleichen.html
  Mit Zitat antworten Zitat
Slashmob

Registriert seit: 28. Okt 2011
45 Beiträge
 
#3

AW: Bildanalyse/-vergleich

  Alt 9. Dez 2011, 16:56
1) Ausmaskieren ? keine Ahnung aber getpixel oder scanline erfüllen den selben zweck

2) fillColor Farbe die ausgegeben werden soll
oldcolor Farbe die ersetzt werden soll

$00ffffff würde weiss entsprechen, $007F7F7F wäre dann ein Grauton

3)top_ left_ ist die Startposition und über die Kantenlänge wird bottom und right berechnet

4) dazu gibt es hier schon einige Beiträge z.B. --> http://www.delphipraxis.net/80639-bi...rgleichen.html
Wie geht das mit dem ausmaskieren? In der Aufgabe steht ja ich soll eine Rotmaske für die Pixel verwenden.

Zu 4)Wie sieht das als Code aus, wenn ich das erste Bild pixelweise, also in jeder Zeile und Spalte die Pixel auslese und mit dem zweiten Bild vergleiche und dann die Differenz der Pixel bei den gleichen Koordinaten bilde?

Dachte irgendwie an sowas...
Delphi-Quellcode:
For i:=1 to image1.width do // Erstes Bild pixelweise auslesen
         Begin
              For j:=1 to image1.height do
                  Begin
                       farbe1:= image1.canvas.pixels[x,y];
                    end;
           end;

      For k:=1 to image2.width do // Zweites Bild pixelweise auslesen
         Begin
              For l:=1 to image2.height do
                  Begin
                       farbe2:= image2.canvas.pixels[x,y];
                    end;
           end;
      wert:= farbe1-farbe2; // Differenzwert bilden
Jemand ne Ahnung wie man hier vorgeht??

Geändert von Slashmob ( 9. Dez 2011 um 17:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#4

AW: Bildanalyse/-vergleich

  Alt 9. Dez 2011, 17:01
wenn Du
wert:= (farbe1 AND clRed) - (farbe2 AND clRed); verwendest bist Du diesbezüglich näher an den Vorgaben.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Slashmob

Registriert seit: 28. Okt 2011
45 Beiträge
 
#5

AW: Bildanalyse/-vergleich

  Alt 9. Dez 2011, 17:12
wenn Du
wert:= (farbe1 AND clRed) - (farbe2 AND clRed); verwendest bist Du diesbezüglich näher an den Vorgaben.
Das heißt bei der Differenz hab ich dann automatisch die Rotmaske drinnen,richtig?
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#6

AW: Bildanalyse/-vergleich

  Alt 9. Dez 2011, 17:30
Ja ...
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Slashmob

Registriert seit: 28. Okt 2011
45 Beiträge
 
#7

AW: Bildanalyse/-vergleich

  Alt 9. Dez 2011, 17:45
Nun möchte ich den "wert" mit dem schwellwert vergleichen und ihn im stringgrid ausgeben, aber das klappt nicht. Dann kommt folgende Fehlermeldung:
Error: Incompatible type for arg no.3: Got "LongInt", expected "AnsiString"



Delphi-Quellcode:
For i:=1 to image1.width do // Erstes Bild pixelweise auslesen
         Begin
              For j:=1 to image1.height do
                  Begin
                       farbe1:= image1.canvas.pixels[i,j];
                    end;
           end;

      For i:=1 to image2.width do // Zweites Bild pixelweise auslesen
         Begin
              For j:=1 to image2.height do
                  Begin
                       farbe2:= image2.canvas.pixels[i,j];
                    end;
           end;

     wert:= (farbe1 and clred)-(farbe2 and clred); // Differenzwert bilden

     If wert > schwellwert then
        Begin
             stringgrid1.cells[1,1]:=inttostr(wert); // Edit
        end;
Und wie bekomm ich raus an welchen Stellen X und Y er die Unterschiede im Bild gefunden hat?

Geändert von Slashmob ( 9. Dez 2011 um 17:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.412 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Bildanalyse/-vergleich

  Alt 9. Dez 2011, 17:52
Wie wandelt man denn eine Ganzzahl in einen String um? Format oder IntToStr könnten da ganz hilfreich sein.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Slashmob

Registriert seit: 28. Okt 2011
45 Beiträge
 
#9

AW: Bildanalyse/-vergleich

  Alt 9. Dez 2011, 17:58
Wie wandelt man denn eine Ganzzahl in einen String um? Format oder IntToStr könnten da ganz hilfreich sein.
Ach logisch, stimmt! (Bin noch Anfänger )
Jetzt ist der Fehler weg, aber es wird kein Wert angezeigt, stattdessen ändert sich die zeilenanzahl
Kriegt er denn mit dem obigen code einen Wert? Bin mir nicht ganz sicher...
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.412 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Bildanalyse/-vergleich

  Alt 9. Dez 2011, 18:00
Irgendwie passen Deine Schleifen überhaupt nicht zusammen.

[edit] Da die Bilder ja gleich groß sind, müsste das auch so gehen:
Delphi-Quellcode:
For i:=1 to image1.width do
  Begin
    For j:=1 to image1.height do
      Begin
        farbe1 := image1.canvas.pixels[i,j];
        farbe2 := image2.canvas.pixels[i,j];
        wert:= (farbe1 and clred)-(farbe2 and clred);
      end;
  end;
[/edit]
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen

Geändert von DeddyH ( 9. Dez 2011 um 18:04 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:48 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