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.
procedure TForm1.Button1Click(Sender: TObject);
var count,X,Y,factor,newx,newy:integer;
go,gothit,gonow:boolean;
searchcolor:TColor;
size:integer;
begin
//Set size to the largest dimension.
size := image1.width div 2;
if image1.height > image1.width then
size := image1.height div 2;
searchcolor := clRed; //target color to fill
image1.Canvas.Brush.Color := clLime;
//In this case start the search at the center of the image.
X := 150;
Y := 150;
factor := 0;
go := true;
gothit := false;
//If the starting pixel is the target color then skip the search
if image1.canvas.pixels[X,Y] = searchcolor then
go := false;
while go do
begin
//Search from top to bottom
factor := factor + 1;
newx := X + factor;
newy := Y - factor;
if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
begin
go := false;
gothit := true;
X := newx;
Y := newy;
end
else
begin
//do nothing
end;
if go then
begin
gonow := true;
count := 0;
while (gonow) and (count < (factor * 2)) do
begin
count := count + 1;
newy := newy + 1;
if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
begin
X := newx;
Y := newy;
gonow := false;
gothit := true;
go := false;
end;
end;
end;
//Search from right to left.
if go then
begin
newx := X + factor;
newy := Y + factor;
if go then
begin
gonow := true;
count := 0;
while (gonow) and (count < (factor * 2)) do
begin
count := count + 1;
newx := newx - 1;
if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
begin
X := newx;
Y := newy;
gothit := true;
gonow := false;
go := false;
end;
end;
end;
end;
//Search from bottom to top.
if go then
begin
newx := X - factor;
newy := Y + factor;
if go then
begin
gonow := true;
count := 0;
while (gonow) and (count < (factor * 2)) do
begin
count := count + 1;
newy := newy - 1;
if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
begin
X := newx;
Y := newy;
gothit := true;
gonow := false;
go := false;
end;
end;
end;
end;
//Search from left to right.
if go then
begin
newx := X - factor;
newy := Y - factor;
if go then
begin
gonow := true;
count := 0;
while (gonow) and (count < (factor * 2)) do
begin
count := count + 1;
newx := newx + 1;
if (image1.canvas.pixels[newx,newy] = searchcolor) and ((newx >= 0) and (newx <= (image1.width - 1)) and (newy >= 0) and (newy <= (image1.height - 1))) then
begin
gothit := true;
X := newx;
Y := newy;
gonow := false;
go := false;
end;
end;
end;
end;
//Stop the loop is the entire image has been searched.
if (gothit = false) and (factor >= size) then
go := false;
end;
if gothit then
begin
image1.Canvas.FloodFill(X,Y,searchcolor,fssurface);
end;
showmessage('Process done.');
end;