Einzelnen Beitrag anzeigen

Gutelo

Registriert seit: 29. Sep 2013
152 Beiträge
 
#23

AW: Canny edge algorithmus und Sobel Matrix

  Alt 31. Jul 2014, 00:20
Kein Problem, ich poste es hier auch noch mal:


Delphi-Quellcode:

// ############################################################################
// Build pixel array of gradient directions
// ############################################################################

Procedure MakeEdgeDirections(PA_Sx, PA_Sy : TPixelArray; var PA_Out : TPixelArray);
//
var rows, cols : Integer;
    Th : Double; // Angle Theta
//
begin
   // Set dimensions of output pixel array
   SetLength(PA_Out, Length(PA_Sx));
   For rows := 0 to High(PA_Out) do SetLength(PA_Out[rows], Length(PA_Sx[0]));
   // calculate output pixel array:
   For rows := 0 to High(PA_Sx) do
   For cols := 0 to High(PA_Sx[0]) do
   begin
      Th := (180/Pi) * ArcTan2(PA_Sy[rows,cols],PA_Sx[rows,cols]);
      // write output pixel array
      PA_Out[rows,cols] := Round(Th);
   end;
end;

Function FMod(x,y : Double) : Double;
begin
   If y = 0 then
   begin
     Showmessage('Error in function FMod: Cannot divide through 0');
     FMod := 0;
   end
   else
   begin
     FMod := x-Int(x/y)*y;
   end;
end;

// ############################################################################
// Perform Non-maximum Suppression (quantisized way)
// ############################################################################

// Symmetry => 180 degree cover the four main directions: 0,45,90,and 135 deg
// Corresponding equivalent directions: 180,225,270,and 315 deg

// Divide the 180 degree region into four quadrant sections
// (0) to (Pi/8) and (Pi-(Pi/8)) to (Pi) <= quadrant around 0 (or symmetry equivalent
// 180 deg,respectively)
// (1*Pi/4) +- Pi/8 <= quadrant around 45 deg
// (2*Pi/4) +- Pi/8 <= quadrant around 90 deg
// (3*Pi/4) +- Pi/8 <= quadrant around 135 deg

// Introduce 'dir' value: dir := (FMod(PA_ED[rows,cols]+180, 180) /180) * 8
// Used to classify the member quadrant for a particular gradient direction
//
// How 'dir' works:
// Example: Input angle at point (x,y) : PA_ED[x,y] = -135
// Shift to get positive angle: PA_ED[x,y] + 180 = 45
// Value on 'dir' scale: (FMod(45,180)/180)*8= (45/180)*8 = 2
//
// Integer 'dir' values correspond to the following angles:
// dir = 0 <=> Th = 0 = 0 { center of 1st quadrant
// dir = 1 <=> Th = Pi/8 = 1*Pi/8 <= border from 1st to 2nd quadrant
// dir = 2 <=> Th = Pi/4 = 2*Pi/8 { center of 2nd quadrant
// dir = 3 <=> Th = Pi/4 + Pi/8 = 3*Pi/8 <= border from 2nd to 3rd quadrant
// dir = 4 <=> Th = Pi/2 = 4*Pi/8 { center of 3rd quadrant
// dir = 5 <=> Th = Pi/2 + Pi/8 = 5*Pi/8 <= border from 3rd to 4th quadrant
// dir = 6 <=> Th = 3*Pi/4 = 6*Pi/8 { center of 4th quadrant
// dir = 7 <=> Th = 3*Pi/4 + Pi/8 = 7*Pi/8 <= border from 4th to 1st quadrant
// dir = 8 <=> Th = Pi = 8*Pi/8 { center of 1st quadrant

Procedure MakeNMS(PA_SO, PA_ED : TPixelArray; var PA_Out : TPixelArray);
//
var dir : Double;
    rows, cols : Integer;
//
begin
   // Set dimensions of output pixel array
   SetLength(PA_Out, Length(PA_SO));
   For rows := 0 to High(PA_Out) do SetLength(PA_Out[rows], Length(PA_SO[0]));
   // Calculate output pixel array:
   For rows := 1 to High(PA_SO)-1 do
   For cols := 1 to High(PA_SO[0])-1 do
   begin
      // Calculate 'dir' value to determine the right quadrant
      dir := (FMod(PA_ED[rows,cols]+180, 180) /180) * 8;
      //
      // Check membership in quadrant, keep maxima,or suppress minima
      //
      // 0 degree quadrant (EE <-> WW)
      If ((dir <= 1) or (dir > 7))
          and (PA_SO[rows,cols] > PA_SO[rows,cols+1]) // EE
          and (PA_SO[rows,cols] > PA_SO[rows,cols-1]) // WW
      then PA_Out[rows,cols] := PA_SO[rows,cols]
      //
      else
      // 45 degree quadrant (NW <-> SE)
      If ((dir > 1) or (dir <= 3))
          and (PA_SO[rows,cols] > PA_SO[rows-1,cols-1]) // NW
          and (PA_SO[rows,cols] > PA_SO[rows+1,cols+1]) // SE
      then PA_Out[rows,cols] := PA_SO[rows,cols]
      //
      else
      // 90 degree quadrant (NN <-> SS)
      If ((dir > 3) or (dir <= 5))
          and (PA_SO[rows,cols] > PA_SO[rows-1,cols]) // NN
          and (PA_SO[rows,cols] > PA_SO[rows+1,cols]) // SS
      then PA_Out[rows,cols] := PA_SO[rows,cols]
      //
      else
      // 135 degree quadrant (NE <-> SW)
      If ((dir > 5) or (dir <= 7))
          and (PA_SO[rows,cols] > PA_SO[rows-1,cols+1]) // NE
          and (PA_SO[rows,cols] > PA_SO[rows+1,cols-1]) // SW
      then PA_Out[rows,cols] := PA_SO[rows,cols]
      //
      else
      // If no maximum -> Suppress Value
          PA_Out[rows,cols] := 0;
   end;
end;
Also ein Copy+Paste Fehler ist schonmal, dass es

If ((dir > 1) and (dir <= 3))
If ((dir > 3) and (dir <= 5))
((dir > 5) and (dir <= 7))

heissen muss. Da es alles verschlimmert stimmt wohl auch irgendwas mit den Richtungen nicht.

Geändert von Gutelo (31. Jul 2014 um 00:34 Uhr)
  Mit Zitat antworten Zitat