Advertisement
WarPie90

Canny Edge

Jun 29th, 2018
432
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 5.04 KB | None | 0 0
  1. program Canny;
  2. {$I SRL1300/osr.simba}
  3. {$R-}
  4.  
  5. procedure SplitRGB(a: TMufasaBitmap; out R,G,B: TSingleMatrix);
  6. var
  7.   W,H,x,y: Int32;
  8. begin
  9.   W := a.GetWidth();
  10.   H := a.GetHeight();
  11.   R.SetSize(W,H);
  12.   G.SetSize(W,H);
  13.   B.SetSize(W,H);
  14.   for y:=0 to H-1 do
  15.     for x:=0 to W-1 do begin
  16.       R[y,x] := (a.GetPixel(x,y){shr 00}and $FF);
  17.       G[y,x] := (a.GetPixel(x,y) shr 08 and $FF);
  18.       B[y,x] := (a.GetPixel(x,y) shr 16 and $FF);
  19.     end;
  20. end;
  21.  
  22. procedure Gradients(a: TMufasaBitmap; out Mag, Dir: TSingleMatrix);
  23. var
  24.   W,H,x,y: Int32;
  25.   dx,dy,theta: Single;
  26.   r,g,b: TSingleMatrix;
  27. const
  28.   Deg22_5:  Single = 0.3926990816987;
  29.   Deg45_0:  Single = 0.7853981633975;
  30.   Deg67_5:  Single = Deg45_0 + Deg22_5;
  31.   Deg90_0:  Single = 1.5707963267949;
  32.   Deg112_5: Single = Deg90_0 + Deg22_5;
  33.   Deg135_0: Single = 2.35619449019234;
  34.   Deg157_5: Single = Deg135_0 + Deg22_5;
  35. begin
  36.   W := a.GetWidth();
  37.   H := a.GetHeight();
  38.  
  39.   Mag.SetSize(W, H);
  40.   Dir.SetSize(W, H);
  41.  
  42.   SplitRGB(a, r,g,b);
  43.  
  44.   for y:=1 to H-2 do
  45.     for x:=1 to W-2 do
  46.     begin
  47.       dx := (-1 * r[y-1,x-1]) + (-2 * r[y-1,x+0]) + (-1 * r[y-1,x+1]) + (+1 * r[y+1,x-1]) + (+2 * r[y+1,x+0]) + (+1 * r[y+1,x+1]);
  48.       dy := (-1 * r[y-1,x-1]) + (+1 * r[y-1,x+1]) + (-2 * r[y+0,x-1]) + (+2 * r[y+0,x+1]) + (-1 * r[y+1,x-1]) + (+1 * r[y+1,x+1]);
  49.  
  50.       dx += (-1 * g[y-1,x-1]) + (-2 * g[y-1,x+0]) + (-1 * g[y-1,x+1]) + (+1 * g[y+1,x-1]) + (+2 * g[y+1,x+0]) + (+1 * g[y+1,x+1]);
  51.       dy += (-1 * g[y-1,x-1]) + (+1 * g[y-1,x+1]) + (-2 * g[y+0,x-1]) + (+2 * g[y+0,x+1]) + (-1 * g[y+1,x-1]) + (+1 * g[y+1,x+1]);
  52.  
  53.       dx += (-1 * b[y-1,x-1]) + (-2 * b[y-1,x+0]) + (-1 * b[y-1,x+1]) + (+1 * b[y+1,x-1]) + (+2 * b[y+1,x+0]) + (+1 * b[y+1,x+1]);
  54.       dy += (-1 * b[y-1,x-1]) + (+1 * b[y-1,x+1]) + (-2 * b[y+0,x-1]) + (+2 * b[y+0,x+1]) + (-1 * b[y+1,x-1]) + (+1 * b[y+1,x+1]);
  55.  
  56.       Mag[y,x] := Sqrt(Sqr(dx * 0.333333334) + Sqr(dy * 0.333333334));
  57.       theta := ArcTan2(dy,dx); // approximate me please
  58.       Dir[y,x] := -1;
  59.  
  60.       if      ((theta >= -Deg22_5) and (theta <= Deg22_5))  or ((theta <= -Deg157_5) or  (theta >= Deg157_5)) then
  61.         Dir[y,x] := 0
  62.       else if ((theta >= Deg22_5)  and (theta <= Deg67_5))  or ((theta <= -Deg112_5)  and (theta >= -Deg157_5)) then
  63.         Dir[y,x] := 1
  64.       else if ((theta >= Deg67_5)  and (theta <= Deg112_5)) or ((theta <= -Deg67_5)  and (theta >= -Deg112_5)) then
  65.         Dir[y,x] := 2
  66.       else if ((theta >= Deg112_5) and (theta <= Deg157_5)) or ((theta <= -Deg22_5) and (theta >= -Deg67_5)) then
  67.         Dir[y,x] := 3;
  68.     end;
  69. end;
  70.  
  71. function NonMaximaSuppress(Gm, Gd: TSingleMatrix; low:Single = 1.0): TSingleMatrix;
  72. var
  73.   x,y,dx,dy: Int32;
  74.   mag, theta: Single;
  75. begin
  76.   Result.SetSize(Gm.Width, Gm.Height);
  77.  
  78.   for y:=1 to Gm.Height()-2 do
  79.     for x:=1 to Gm.Width()-2 do
  80.     begin
  81.       mag := Gm[y,x];
  82.       if mag < low then Continue;
  83.       dx := 0;
  84.       dy := 0;
  85.       case Round(Gd[y,x]) of
  86.         0: if (mag > Gm[y+1,x])   and (mag > Gm[y-1,x]) then
  87.              Result[y,x] := mag;
  88.         1: if (mag > Gm[y-1,x-1]) and (mag > Gm[y+1,x+1]) then
  89.              Result[y,x] := mag;
  90.         2: if (mag > Gm[y,x+1])   and (mag > Gm[y,x-1]) then
  91.              Result[y,x] := mag;
  92.         3: if (mag > Gm[y-1,x+1]) and (mag > Gm[y+1,x-1]) then
  93.              Result[y,x] := mag;
  94.       end;
  95.     end;
  96. end;
  97.  
  98. function Threshold(Image: TSingleMatrix; low, high: Int32): TSingleMatrix;
  99. var
  100.   i,j,x,y: Int32;
  101.   isValuable, isUnsure: Boolean;
  102. begin
  103.   Result.SetSize(Image.Width, Image.Height);
  104.  
  105.   for i:=1 to Image.Height-2 do
  106.   begin
  107.     for j:=1 to Image.Width-2 do
  108.     begin
  109.       if(Image[i,j] > high) then
  110.         Result[i,j] := 255
  111.       else if(Image[i,j] < Low) then
  112.         Result[i,j] := 0
  113.       else
  114.       begin
  115.         // figure out if it's low or high, must have high neighbor
  116.         isValuable := False;
  117.         isUnsure   := False;
  118.         for y:=i-1 to i+1 do
  119.         begin
  120.           for x:=j-1 to j+1 do
  121.           begin
  122.             if(Image[y,x] > high) then
  123.             begin
  124.               Result[i,j] := 255;
  125.               isValuable := True;
  126.               break;
  127.             end
  128.             else if (Image[y,x] <= high) and (Image[y,x] >= low) then
  129.               isUnsure := True;
  130.           end;
  131.           if (isValuable) then
  132.             break;
  133.         end;
  134.  
  135.         if(not isValuable) then
  136.           Result[i,j] := 0;
  137.       end;
  138.     end;
  139.   end;
  140. end;
  141.  
  142. function CannyEdge(Image: TMufasaBitmap; TLow, THigh: Int32): TSingleMatrix;
  143. var
  144.   Gm, Gd, nms: TSingleMatrix;
  145. begin
  146.   Gradients(Image, Gm, Gd);
  147.   nms := NonMaximaSuppress(Gm, Gd);
  148.   Result := Threshold(nms, TLow, THigh);
  149. end;
  150.  
  151. var
  152.   bmp, tmp: TMufasaBitmap;
  153.   t: Double;
  154. begin
  155.   bmp.Init(client.GetMBitmaps);
  156.   bmp.LoadFromFile('Images/lenna.jpg');
  157.   tmp.Init(client.GetMBitmaps);
  158.  
  159.   //bmp.Downsample(2,tmp);
  160.   //bmp.Free();
  161.   //bmp := tmp;
  162.  
  163.   bmp.Blur(3); bmp.Blur(3);
  164.  
  165.   t := PerformanceTimer();
  166.   bmp.DrawMatrix(CannyEdge(bmp, 40,70).ToInt);
  167.   WriteLn(PerformanceTimer() - t);
  168.  
  169.   bmp.Debug();
  170.   bmp.Free();
  171. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement