Einzelnen Beitrag anzeigen

Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Canny edge algorithmus und Sobel Matrix

  Alt 26. Jul 2014, 17: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 18:23 Uhr)
  Mit Zitat antworten Zitat