Recent

Author Topic: Spiral search of an image  (Read 200 times)

user5

  • Sr. Member
  • ****
  • Posts: 366
Spiral search of an image
« on: April 28, 2025, 04:05:34 pm »
    I'm back after a long absence and I thought that I would share some code in case anyone is interested. The code below searches
through a picture or video frame image in a clockwise spiral from any given point. It searches for a target solid colored area and then
flood fills that area with the chosen fill color. The example here stops processing after the flood fill is done but it could be easily modified
to continue through all the pixels of the image to flood fill all instances of the target search color.
    For purposes of illustration a TImage is used here but in actual practice a TBGRABitmap would be used to get the fastest possible speed.
    The attached picture shows the search pattern with red being the first search, blue being the second search and so on. The starting
point is the black pixel and the red pixel diagonally to the right of the black pixel is where the next search begins.
    The beauty about searching in a spiral from a given point instead of starting at any corner of the image is that this type of flood fill
process can work with target areas that change shape and even move around. The user would make one click on a target color and then the
program would do the rest.
    For example, the user clicks a target red area on the first frame of a video to get X and Y. In the second frame that area has changed its
shape and has also moved to a different location some distance from where it used to be. In the second frame the program searches from
the previous click location for that red area and then flood fills it. Ta Ta.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var count,X,Y,factor,newx,newy:integer;
  3.     go,gothit,gonow:boolean;
  4.     searchcolor:TColor;
  5.     size:integer;
  6. begin
  7. //Set size to the largest dimension.
  8. size := image1.width div 2;
  9. if image1.height > image1.width then
  10.  size := image1.height div 2;
  11.  
  12. searchcolor := clRed; //target color to fill
  13. image1.Canvas.Brush.Color := clLime;
  14. //In this case start the search at the center of the image.
  15. X := 150;
  16. Y := 150;
  17.  
  18. factor := 0;
  19. go := true;
  20. gothit := false;
  21. //If the starting pixel is the target color then skip the search
  22. if image1.canvas.pixels[X,Y] = searchcolor then
  23.  go := false;
  24.  
  25. while go do
  26.  begin
  27.   //Search from top to bottom
  28.   factor := factor + 1;
  29.   newx := X + factor;
  30.   newy := Y - factor;
  31.  
  32.   if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
  33.    begin
  34.     go := false;
  35.     gothit := true;
  36.     X := newx;
  37.     Y := newy;
  38.    end
  39.   else
  40.    begin
  41.     //do nothing
  42.    end;
  43.  
  44.   if go then
  45.    begin
  46.     gonow := true;
  47.     count := 0;
  48.     while (gonow) and (count < (factor * 2)) do
  49.      begin
  50.       count := count + 1;
  51.       newy := newy + 1;
  52.  
  53.       if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
  54.        begin
  55.         X := newx;
  56.         Y := newy;
  57.         gonow := false;
  58.         gothit := true;
  59.         go := false;
  60.        end;
  61.      end;
  62.    end;
  63.  
  64.   //Search from right to left.
  65.   if go then
  66.    begin
  67.     newx := X + factor;
  68.     newy := Y + factor;
  69.  
  70.     if go then
  71.      begin
  72.       gonow := true;
  73.       count := 0;
  74.       while (gonow) and (count < (factor * 2)) do
  75.        begin
  76.         count := count + 1;
  77.         newx := newx - 1;
  78.  
  79.         if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
  80.          begin
  81.           X := newx;
  82.           Y := newy;
  83.           gothit := true;
  84.           gonow := false;
  85.           go := false;
  86.          end;
  87.        end;
  88.      end;
  89.    end;
  90.  
  91.   //Search from bottom to top.
  92.   if go then
  93.    begin
  94.     newx := X - factor;
  95.     newy := Y + factor;
  96.  
  97.     if go then
  98.      begin
  99.       gonow := true;
  100.       count := 0;
  101.       while (gonow) and (count < (factor * 2)) do
  102.        begin
  103.         count := count + 1;
  104.         newy := newy - 1;
  105.  
  106.         if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
  107.          begin
  108.           X := newx;
  109.           Y := newy;
  110.           gothit := true;
  111.           gonow := false;
  112.           go := false;
  113.          end;
  114.        end;
  115.      end;
  116.    end;
  117.  
  118.   //Search from left to right.
  119.   if go then
  120.    begin
  121.     newx := X - factor;
  122.     newy := Y - factor;
  123.  
  124.     if go then
  125.      begin
  126.       gonow := true;
  127.       count := 0;
  128.       while (gonow) and (count < (factor * 2)) do
  129.        begin
  130.         count := count + 1;
  131.         newx := newx + 1;
  132.  
  133.         if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
  134.          begin
  135.           gothit := true;
  136.           X := newx;
  137.           Y := newy;
  138.           gonow := false;
  139.           go := false;
  140.          end;
  141.        end;
  142.      end;
  143.    end;
  144.   //Stop the loop is the entire image has been searched.
  145.   if (gothit = false) and (factor >= size) then
  146.    go := false;
  147.  end;
  148.  
  149. if gothit then
  150.  begin
  151.   image1.Canvas.FloodFill(X,Y,searchcolor,fssurface);
  152.  end;
  153.  
  154. showmessage('Process done.');
  155.  
  156. end;





 

TinyPortal © 2005-2018