Advertisement
WarPie90

Quick skeleton

Jul 9th, 2024 (edited)
395
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 2.08 KB | None | 0 0
  1. function TSingleMatrix.ArgExtremaXY(Count: Int32; HiLo: Boolean = True; XYIntersection: Boolean = True): TPointArray;
  2. var
  3.   W, H: Integer;
  4.   Buffer: TPointArray;
  5.   function pass_x(): TPointArray;
  6.   var
  7.     c,X,Y: Integer;
  8.   begin
  9.     for Y:=0 to H-1 do
  10.     begin
  11.       X := 1;
  12.       while (X < W) do
  13.       begin
  14.         while (X < W) and (Self[Y,X] >= Self[Y,X-1]) do Inc(X);
  15.         Buffer[c] := [X-1,Y];
  16.         Inc(c);
  17.         while (X < W) and (Self[Y,X] <= Self[Y,X-1]) do Inc(X);
  18.       end;
  19.     end;
  20.  
  21.     Result := Copy(Buffer, 0, c);
  22.   end;
  23.  
  24.   function pass_y(): TPointArray;
  25.   var
  26.     c,X,Y: Integer;
  27.   begin
  28.     for X:=0 to W-1 do
  29.     begin
  30.       Y := 1;
  31.       while (Y < H) do
  32.       begin
  33.         while (Y < H) and (Self[Y,X] >= Self[Y-1,X]) do Inc(Y);
  34.         Buffer[c] := [X,Y-1];
  35.         Inc(c);
  36.         while (Y < H) and (Self[Y,X] <= Self[Y-1,X]) do Inc(Y);
  37.       end;
  38.     end;
  39.  
  40.     Result := Copy(Buffer, 0, c);
  41.   end;
  42.  
  43. var
  44.   I: Integer;
  45.   Weights: TSingleArray;
  46. begin
  47.   W := Self.Width();
  48.   H := Self.Height();
  49.   SetLength(buffer, W*H);
  50.  
  51.   if XYIntersection then
  52.   begin
  53.     Result := pass_x().Intersection(pass_y());
  54.   end else begin
  55.     Result := pass_x();
  56.     Result.Extend(pass_y());
  57.   end;
  58.  
  59.   // just use sort, since there arn't that many peaks
  60.   SetLength(Weights, Length(Result));
  61.   for I := 0 to High(Result) do
  62.     Weights[I] := Self[Result[I].Y, Result[I].X];
  63.  
  64.   Result.Sort(Weights, not HiLo);
  65.   if (Length(Result) > Count) then
  66.     SetLength(Result, Count);
  67. end;
  68.  
  69. function DistanceTransform(pts: TPointArray): TSingleMatrix;
  70. var
  71.   inverse: TPointArray;
  72.   itree: TSlackTree;
  73.   b: TBox;
  74.   i: Int32;
  75. begin
  76.   inverse := pts.Invert();
  77.   b := pts.Bounds.Combine(inverse.Bounds);
  78.   Result.SetSize(b.x2+1, b.y2+1);
  79.   itree.Init(inverse);
  80.   for i:=0 to High(pts) do
  81.     Result[pts[i].y, pts[i].x] := itree.Nearest(pts[i]).DistanceTo(pts[i]);
  82. end;
  83.  
  84. function QuickSkeleton(pts: TPointArray): TPointArray;
  85. var
  86.   m: TSingleMatrix;
  87. begin
  88.   m   := DistanceTransform(pts);
  89.   Result := m.ArgExtremaXY($FFFFFF, True, False);
  90. end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement