Registriert seit: 31. Mai 2009
1.198 Beiträge
Turbo Delphi für Win32
|
AW: Canny edge algorithmus und Sobel Matrix
26. Jul 2014, 18:43
Es ist klar, dass negative Werte rauskommen können.. Wenn man die Matrizen genauer ansieht, transformiert man von [0..255] auf [-1020..1020]
Dh du müsstest einen Normalisierungsschritt machen, indem du zuerst 1020 addierst, dann mit 255/2040 multiplizierst.
Bin mir momentan nicht ganz sicher.. Meine Überlegung war - wenn die "obere Pixellinie" die mit der ersten Zeile der G_Y Matrix multipliziert wird, aus 255'en bestehen, dann kommt dort als max. Wert 1*255 + 2*255 + 1*255 = 4*255 = 1020 raus.. Dasselbe gilt für die untere Pixellinie = -1020
Edit: Nen Sonderfall hat man bei Rändern. Ich hab ne Beispielsimplementierung, wo ich die Operatoren zähle, damit ich den neuen Intervall jeweils für X und Y kenne und somit dann normalisieren kann..
Delphi-Quellcode:
procedure gray(bmp: TBitmap);
var
sl: PRGBTriple;
y, x: Integer;
begin
for y := 0 to bmp.Height - 1 do
begin
sl := bmp.ScanLine[y];
for x := 0 to bmp.Width - 1 do
begin
sl.rgbtBlue := (sl.rgbtBlue + sl.rgbtGreen + sl.rgbtRed) div 3;
sl.rgbtGreen := sl.rgbtBlue;
sl.rgbtRed := sl.rgbtBlue;
Inc(sl);
end;
end;
end;
procedure sobel(bmp: TBitmap);
const
SobelXOperator: Array[-1..1,-1..1] of ShortInt =
((-1,0,1),
(-2,0,2),
(-1,0,1));
SobelYOperator: Array[-1..1,-1..1] of ShortInt =
((1,2,1),
(0,0,0),
(-1,-2,-1));
var
Data: Array of Array of Byte;
y, x: Integer;
i, j: Integer;
posXOp, negXOp: Integer; // positive & negative Sobel X Operatoren
posYOp, negYOp: Integer; // -- || -- Y Operatoren
sumX, sumY: Integer;
sl: PRGBTriple;
begin
SetLength(Data, bmp.Height, bmp.Width);
for y := 0 to bmp.Height - 1 do
begin
sl := bmp.ScanLine[y];
for x := 0 to bmp.Width - 1 do
begin
Data[y,x] := sl.rgbtBlue;
Inc(sl);
end;
end;
for y := 0 to bmp.Height - 1 do
begin
sl := bmp.ScanLine[y];
for x := 0 to bmp.Width - 1 do
begin
sumX := 0;
sumY := 0;
posXOp := 0;
negXOp := 0;
posYOp := 0;
negYOp := 0;
for i := -1 to 1 do
if (x + i >= 0) and (x + i < bmp.Width) then
for j := -1 to 1 do
if (y + j >= 0) and (y + j < bmp.Height) then
begin
if SobelXOperator[j,i] < 0 then
inc(negXOp, abs(SobelXOperator[j,i]))
else
inc(posXOp, abs(SobelXOperator[j,i]));
if SobelYOperator[j,i] < 0 then
inc(negYOp, abs(SobelYOperator[j,i]))
else
inc(posYOp, abs(SobelYOperator[j,i]));
inc(sumX, Data[y+j,x+i] * SobelXOperator[j,i]);
inc(sumY, Data[y+j,x+i] * SobelYOperator[j,i]);
end;
// Normalisierungsschritt
inc(sumX, negXOp*255);
sumX := sumX div (negXOp + posXOp);
inc(sumY, negYOp*255);
sumY := sumY div (negYOp + posYOp);
sumX := (sumX + sumY) div 2;
// .. done
sl.rgbtBlue := sumX;
sl.rgbtGreen := sumX;
sl.rgbtRed := sumX;
inc(sl);
end;
end;
end;
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
Geändert von Aphton (26. Jul 2014 um 19:23 Uhr)
|