One of the techniques to find an object in a picture is by searching for its color. This sounds easy, as for a human we can easily see what is red or blue or any other color. But for a computer it is not that easy. What is red? Or blue?
Looking for a green object in a picture cannot be done by looking for the RGB value 00FF00. There are many shades of green that we as a human consider green. It may be lighter, darker, warmer, colder, etc.
So we need to find another approach. This is where HSV comes in. HSV stands for Hue, Saturation, and Value. If we can convert our color to those values, we can then build a range which we will consider as ‘the green’ ones.
Let’s dive into the code.
Create a class Blob with the following properties. This will simply hold our result pictures:
MyPic as picture MyRealPic as picture
Now, we are going to find the blob of our desired color in the function GetBlobFromPic().
For this tutorial I’ll created the ranges for Red, Green, Blue and Yellow objects. We first convert the RGB pixel to it’s HSV values. To do this I used some math functions I found in a math article on the internet. I can’t recall which one, but I’ll try to find it back so I can post it here.
Once we have our HSV values, we’ll compare if they fall within the range we are looking for. If so, we mark it in our blob by setting the pixel to &C000001. You can also do this in a table, but for the purpose of this tuorial I also want to show the result of this search (shown in canvas2).
Here is the main part from this function:
' these values are precaulculated select case FindColor case &c00FF00 ' green minH = 48 maxH = 120 minS = 40 maxS = 255 case &cFF0000 ' red minH = 236 maxH = 14 minS = 40 maxS = 255 case &cFFFF00 ' yellow minH = 25 maxH = 47 minS = 100 maxS = 255 case &c0000FF 'blue minH = 121 maxH = 170 minS = 40 maxS = 255 end select ' search for the color within our range for ax = 0 to SrcPic.Width - 1 for ay = 0 to SrcPic.Height - 1 C = SrcRGB.Pixel(ax,ay) H = C.Hue * 255 V = C.Value* 255 S = C.Saturation * 200 minV = 50 - (30/215 * (S - 40)) maxV = 170 + (70/215 * (S - 40)) if minH - MaxH < 0 then if H >= MinH and H <= maxH and S >= minS and S <= maxS and V >= minV and S <= maxV then TgtRGB.Pixel(ax,ay) = &c000001 end if else if (h >= minH or H <= maxH) and S >= minS and S <= maxS and V >= minV and S <= maxV then TgtRGB.Pixel(ax,ay) = &c000001 end if end if next next
Then, we do some cleanup. If more than half the pixels surrounding our found pixel are not marked, unmark it (&cFFFFFF). We’ll search like this:
AAA AXA AAA
Where X is our marked pixel we want to check and A the ones around it. For speed, I also check X itself so I don’t have to use an IF in the loop.
Here is the code that does this:
for ax = 0 to tgtPic.Width - 1 for ay = 0 to tgtPic.Height - 1 Teller = 0 for zx = ax - 1 to ax + 1 for zy = ay - 1 to ay + 1 if TgtRGB.Pixel(zx,zy) <> &c000001 then Teller = Teller + 1 end if next if Teller > 4 then TgtRGB.Pixel(ax,ay) = &cFFFFFF end if next next next
Last, We’ll use our ‘map’ with marked pixels to get the original pixels that we can show in Canvas3:
for ax = 0 to tgtPic.Width - 1 for ay = 0 to tgtPic.Height - 1 if TgtRGB.Pixel (ax,ay) = &c000001 then realRGB.Pixel(ax,ay) = OrigRGB.Pixel(ax,ay) end if next next
To make this even better, you can first do a Gaussian Blur on the picture so most of the holes in the found object are closed. The gaussian blur is not in this tutorial, but a quick seach on the internet will give you several sites where this is explained.
I hope this explained a little bit how we can do a fast search of an colored object in a photo.
The source code for this project: http://www.gorgeousapps.com/Findcolor.zip
Keep on programming!