Registriert seit: 29. Sep 2013
152 Beiträge
|
AW: Canny edge algorithmus und Sobel Matrix
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)
|