Thema: Delphi Bildanalyse/-vergleich

Einzelnen Beitrag anzeigen

Slashmob

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

AW: Bildanalyse/-vergleich

  Alt 11. Dez 2011, 19:34
Hab den code jetzt korrigiert. Dennoch frag ich mich warum folgendes Problem auftritt.
Ich lass die Quadrate mit der Kantenlänge 3 zeichnen. Ok alles wunderbar,klappt!
Dann verändere ich z.B. auf die Kantenlänge 7. Das Quadrat mit Kantenlänge 3 bleibt bestehen und er zeichnet mir um dieses Quadrat nur einen Umriss des Quadrats mit Kantenlänge 7. Das heißt er füllt die Fläche nicht richtig aus.
Wenn man schrittweise die Kantenlänge um eins erhöht und jedesmal zeichnen lässt, dann sieht das so aus als würde die Fläche ganz ausgefüllt werden. Ist aber nicht Sinn der Sache.

Desweiteren hab ich noch die Frage wie ich das hier umsetzen soll.
Einen Teil in der Aufgabe hatten wir übersehen, weder im StringGrid noch in der Malroutine sollen Benachbarte Punkte nach Definition Kantenlänge erfasst werden. Dies bedeutet dass schon beim Scanvorgang Image3 miteinbezogen werden muss und nur wenn pixels[i,j] in Bild 3 schwarz ist dieser Punkt erfasst wird (gleiche Rangstufe wie der Schwellenwert), es muss dann wenn ein Punkt gefunden wurde auch direkt das Quadrat in Image3 gemalt und gefüllt werden, damit ein Beispielsweise direkt benachbarter Punkt bein nächsten Vergleich ausgeschlossen wird.
Würde mich über Tipps freuen.

Hier der Code:
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);
    procedure AddFound(nr,x,y,wert: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
   with image3.canvas do
   if (pixels[x,y]=clblack) then
      begin
      Pixels[x,y]:= fillcolor;
      floodFill_(x+1, y, clred, clblack);
      floodFill_(x-1, y, clred, clblack);
      floodFill_(x, y+1, clred, clblack);
      floodFill_(x, y-1, clred, clblack);
   end;
end;

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

   begin

    case image of
      1:
         with form1.image1.canvas do // Wird nicht benutzt
            begin
         end;
      2:
         with form1.image2.canvas do // Wird nicht benutzt
            begin
            end;
      3:
         with form1.image3.canvas do
            begin
            pen.color:=clred;
            moveto(round(left_-kantenlaenge),round (top_-kantenlaenge)); // Startpunkt
            lineto(round(left_+kantenlaenge),round (top_-kantenlaenge)); // 4 Linien für das Quadrat zeichnen
            lineto(round(left_+kantenlaenge),round (top_+kantenlaenge));
            lineto(round(left_-kantenlaenge),round (top_+kantenlaenge));
            lineto(round(left_-kantenlaenge),round (top_-kantenlaenge));
         end;
      4:
         with form1.image4.canvas do // Wird nicht benutzt
            begin
         end;
      end;
   end;

procedure TForm1.Addfound (nr,x,y,wert:Integer);
Begin

     If stringgrid1.rowcount < (nr+1) then
        begin // Zeile um eins erhöhen, wenn
           stringgrid1.rowcount:= nr+1;
        end;
        stringgrid1.cells[0,0]:='Nr.'; // Benennung der Spalten
        stringgrid1.cells[1,0]:='X';
        stringgrid1.cells[2,0]:='Y';
        stringgrid1.cells[3,0]:='Diff-Wert';

        stringgrid1.cells[0,nr]:=inttostr(Nr); // Daten in entsprechende Spalten/Zeilen einfügen
        stringgrid1.cells[1,nr]:=inttostr(X);
        stringgrid1.cells[2,nr]:=inttostr(Y);
        stringgrid1.cells[3,nr]:=inttostr(Wert);
end;

procedure TForm1.Button1Click(Sender: TObject);
Var

    farbe1, // Pixelfarbe im Image1
    farbe2, // Pixelfarbe im Image2
    wert, // Differenzwert
    schwellwert, // Schwellwert zum Vergleich
    x, // Laufindex in X-Richtung
    y, // Laufindex in Y-Richtung
    z // Zähler
        :integer;

begin
     schwellwert:=spinedit1.value; // Schwellwert
     z:=0; // Zähler auf Null gesetzt

     For x:=0 to b-1 do // Pixelweise Bilder auslesen
      Begin
           For y:=0 to h-1 do
               Begin
                    farbe1 := image1.canvas.pixels[x,y]; // Farbe merken und zuweisen
                    farbe2 := image2.canvas.pixels[x,y];
                    wert:= (farbe1 and clred)-(farbe2 and clred); // Differenzwert bilden (Rotmaske)
                    If wert > schwellwert then // Differenzwert mit Schwellwert vergleichen
                      begin
                       inc(z); // Zähler hochzählen
                       AddFound(z,x,y,wert); // Daten in Stringgrid einfügen
                       quadratmalen(3,y,x,spinedit2.value,clred); // Quadrat malen
                       floodfill_(x,y,clred,clblack); // Quadrat ausfüllen

                       image4.canvas.pixels[x,y]:=clred;
                       image4.canvas.pixels[x,y]; // Im Image4 die Punkte markieren
                      end;
               end;

      end;


end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close; // Schließen Knopf
end;

end.
  Mit Zitat antworten Zitat