Registriert seit: 25. Feb 2008
95 Beiträge
Delphi 7 Personal
|
Re: Region Growing und Rekursive Aufrufe
20. Okt 2008, 12:06
@Uwe Raabe
Dein Code hat leider immer noch einen Stack Overflow ausgelöst.
Ich habe meinen Code noch ausgebessert.
Er funktioniert jetzt ohne Fehler (zumindest habe ich noch keinen gefunden).
Hier noch einmal der gesamte Code, für alle, die mal schnell einen Algorithmus für Region Growing brauchen:
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(i: integer): 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];
if form1.progressbar1.position = form1.progressbar1.max then
form1.progressbar1.position := 0;
form1.progressbar1.Position := form1.progressbar1.Position+1;
if (High(values) >= x) and (x >= 0) then
if (high(values[x]) >= y) and (y >= 0) then
begin
if high(values) > x then
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;
if x > 0 then
begin
if (values[x-1][y]=0) then
if (IsAenlich(50, c, c2)) then
begin
values[x-1][y] := i;
RegionGrowing(x-1,y,i,image);
end;
end;
if y > 0 then
begin
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;
end;
if high(values[x]) > y then
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;
end;
end;
procedure TXYValues.StartRegionGrowing(image: TImage; i: integer);
begin
form1.progressbar1.min := 0;
form1.progressbar1.position := 0;
form1.progressbar1.max := 100;
values[leftx][lefty] := i;
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(i: integer): 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.RegionGrowingButtonClick(Sender: TObject);
var x, i: Integer;
Regions: TXYValues;
begin
i := 0;
Regions := TXYValues.Create(image1.Width, image1.Height);
while not Regions.NoRegionLeft(i) do
begin
inc(i);
Regions.StartRegionGrowing(image1,i);
end;
showmessage(inttostr(i));
Regions.Free;
end;
i ist am Ende die Anzahl der Regionen.
Mit Regions[x][y] kann man danach feststellen, welcher Region der Pixel x y angehört.
Letztendlich noch einmal vielen Dank an alle, die mir geholfen haben.
Falls noch jemand weiß, wie man die Methoden sonst noch verbessern oder schneller machen kann, bitte posten.
|