Einzelnen Beitrag anzeigen

blender

Registriert seit: 25. Feb 2008
95 Beiträge
 
Delphi 7 Personal
 
#1

Region Growing und Rekursive Aufrufe

  Alt 19. Okt 2008, 18:06
Hallo,

ich möchte gerne ein Programm schreiben, dass mit der Region Growing Methode Regionen erkennt.
Die erkannten Regionen dienen dazu, ein Bild zu Vektorisieren.
Ich bin mir dessen bewusst, dass Farbverläufe dann als eine Region erkannt werden.

Wenn ich den unten angegebenen Code ausführe, kommt nach einiger Wartezeit eine Warnmeldung: Stack Überlauf. (Die Stelle ist im Quellcode markiert.)

Dort habe ich einen Rekursiven Aufruf, was wahrscheinlich auch zu dem Fehler geführt hat.
Allerdings hätte ich bei einem Rekursiven Aufruf einen Fehler eher hier Erwartet:
Delphi-Quellcode:
c := image.Canvas.Pixels[x,y];
c1 := image.canvas.pixels[x+1,y];
c2 := image.Canvas.Pixels[x-1,y];
c3 := image.canvas.pixels[x,y-1];
c4 := image.canvas.pixels[x,y+1];
da die Variablen ja auch noch beim nächsten mal die gleiche Adresse haben.

Delphi-Quellcode:
//...

type
  TXYValues = class
  Values: array of array of byte;
  LeftX, LeftY: Integer;
   private
    procedure RegionGrowing(x,y,i: integer; var image: TImage);
   public
    constructor Create(LengthX, LengthY: Integer);
    function NoRegionLeft: boolean;
    function IsAenlich(maxunterschied:Integer; var c1,c2:tcolor):boolean;
    procedure StartRegionGrowing(image: TImage; i: integer);
  end;

//...

procedure TXYValues.RegionGrowing(x,y,i: integer; var image: TImage);
var c, c1, c2, c3, c4: TColor;
begin
c := image.Canvas.Pixels[x,y];
c1 := image.canvas.pixels[x+1,y];
c2 := image.Canvas.Pixels[x-1,y];
c3 := image.canvas.pixels[x,y-1];
c4 := image.canvas.pixels[x,y+1];

try //Nur um die Fehlermeldungen zu unterdrücken. Werde ich später ausbessern.
if (values[x+1,y]=0) then
if (IsAenlich(50, c, c1)) then
 begin
 values[x+1,y] := i;
 RegionGrowing(x+1,y,i,image);
 end;
except
end;

try
if (values[x-1,y]=0) then //in dieser Zeile ist der Stack Überlauf
if (IsAenlich(50, c, c2)) then
 begin
 values[x-1,y] := i;
 RegionGrowing(x-1,y,i,image);
 end;
except
end;

try
if (values[x,y-1]=0) then
if (IsAenlich(50, c, c3)) then
 begin
 values[x,y-1] := i;
 RegionGrowing(x,y-1,i,image);
 end;
except
end;

try
if (values[x,y+1]=0) then
if (IsAenlich(50, c, c4)) then
 begin
 values[x,y+1] := i;
 RegionGrowing(x,y+1,i,image);
 end;
except
end;

end;

procedure TXYValues.StartRegionGrowing(image: TImage; i: integer);
begin
RegionGrowing(leftx,lefty,i,image);
end;

function TXYValues.IsAenlich(maxunterschied:Integer; var c1,c2:tcolor):boolean;
var r1,g1,b1,
    r2,g2,b2: byte;
    crgb1,crgb2: Integer;
begin
  c1 := colortorgb(c1);
  c2 := colortorgb(c2);

  r1 := getrvalue(c1); // ROT
  g1 := getgvalue(c1); // GRÜN
  b1 := getbvalue(c1); // BLAU
  r2 := getrvalue(c2); // ROT
  g2 := getgvalue(c2); // GRÜN
  b2 := getbvalue(c2); // BLAU

  if r1+g1+b1 < r2+g2+b2 then
  begin
  crgb1 := r1+g1+b1;
  crgb2 := r2+g2+b2;
  end
  else
  begin
  crgb2 := r1+g1+b1;
  crgb1 := r2+g2+b2;
  end;

result := crgb1 >= crgb2 - maxunterschied;

end;

constructor TXYValues.Create(LengthX, LengthY: Integer);
var x, y: integer;
begin
inherited create;

SetLength(Values,lengthx,lengthy);

for x := 0 to High(values) do
 begin
 for y := 0 to High(values[x]) do
  begin
  Values[x][y] := 0;
  end;
 end;

end;

function TXYValues.NoRegionLeft: boolean;
var x,y: Integer;
begin

result := true;

for x := 1 to High(Values) do
 begin
 if result then
 for y := 1 to High(Values[x]) do
  begin
  if result then
  if Values[x][y] < 1 then
   begin
   result := false;
   Leftx := x;
   lefty := y;
   end;

  end;

 end;
end;

//...

procedure TForm1.ButtonClick(Sender: TObject);
var x, i: Integer;
    Regions: TXYValues;
begin
i := 0;
Regions := TXYValues.Create(image1.Width, image1.Height);

while not Regions.NoRegionLeft do
 begin

 inc(i);
 Regions.StartRegionGrowing(image1,i);

 end;

//Restliche Behandlung

Regions.Free;

end;
  Mit Zitat antworten Zitat