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