Registriert seit: 25. Feb 2008
95 Beiträge
Delphi 7 Personal
|
Region Growing und Rekursive Aufrufe
19. Okt 2008, 19: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;
|