Guten Morgen.
Ich habe die neue Funktion von Himitsu ausprobiert. Hier werden einzelne große Flächen in vertikale Streifen aufgeteilt. Den Fehler habe ich nicht gefunden. Ein Durchlauf dauert hier bei meinem Bild ca. 300 Millisekunden.
Danach habe ich noch einmal die Idee von jfheins aufgegriffen und meine Funktion umgeschrieben und iterativ mit einem Array gearbeitet. Das geht wunderbar und ist sogar noch schneller als der rekursive Ansatz.
Im Moment brauche ich nur die Daten der gefundenen Bereiche und das so schnell wie möglich. Wenn einmal gefordert ist, dass ich die Bereiche im Bild anzeigen muss, werde ich wahrscheinlich noch mal auf Himitsus Ansatz zurückkommen.
Falls jemanden die Funktion interessiert:
Die Funktionen für den Zugriff auf die Pixel sind Teil einer anderen Klasse, die ich hier aber nicht veröffentlichen kann.
Delphi-Quellcode:
var
Points: Array of TPoint;
procedure init;
begin
ImgWidth:= Image.Width;
ImgHeight:= Image.Height;
//Array größe = 4*Pixelanzahl, da im worst case auf jedes Pixel von jeder Seite zugegriffen wird.
SetLength(Points,4*ImgWidth*ImgHeight);
end;
procedure SearchBlob;
var
x,y: integer;
MeanX, MeanY: double;
index: integer;
ListCount: integer;
count: integer;
s: string;
imgo:pointer;
begin
For Y := 0 to ImgHeight - 1 do
begin
For X := 0 to ImgWidth - 1 do
begin
if GetGrayVal(x,y) < Threshold) then
Begin
index:=0;
ListCount:= 0;
MeanX:= 0;
MeanY:= 0;
count:= 0;
//Startpunkt in Liste aufnehmen
Points[ListCount].X:= x;
Points[ListCount].Y:= y;
//Liste abarbeiten
Repeat
//Wenn Pixel dunkel, dann Position aufnehmen und umgebende Punke in die Liste aufnehmen
if GetGrayVal(Points[index].X,Points[index].Y) <= Threshold) then
begin
MeanX:= MeanX + Points[index].X;
MeanY:= MeanY + Points[index].Y;
inc(Count);
GrayVal[Points[index].X][Points[index].Y]:= 255;
//umgebende Punke zur Liste hinzufügen
if (Points[index].x < ImgWidth-1) then
begin
inc(ListCount);
Points[ListCount].X:= Points[index].X + 1;
Points[ListCount].Y:= Points[index].Y;
end;
if (Points[index].x > 0) then
begin
inc(ListCount);
Points[ListCount].X:= Points[index].X - 1;
Points[ListCount].Y:= Points[index].Y;
end;
if (Points[index].y < ImgHeight-1) then
begin
inc(ListCount);
Points[ListCount].X:= Points[index].X;
Points[ListCount].Y:= Points[index].Y + 1;
end;
if (Points[index].y > 0) then
begin
inc(ListCount);
Points[ListCount].X:= Points[index].X;
Points[ListCount].Y:= Points[index].Y - 1;
end;
end;
inc(index);
Until index >= ListCount;
//zu kleine Flächen ignorieren
if Count > 100 then
begin
MeanX:= MeanX/Count;
MeanY:= MeanY/Count;
s:= 'Position: X=' + FormatFloat('0.0',MeanX)
+ ' ; Y=' + FormatFloat('0.0',MeanY)
+ ' ; S=' + IntToStr(Count);
ResultList.Add(s);
end;
end;
end;
end;
end;
Damit ist mein Problem gelöst. Vielen Dank an alle für Eure Hilfe!!
Gruß
Thomas