3

Well I'm working hard on my vehicle license plate detection algorithm, and need a little help with something simple.

Basically I'm trying to do the following, the code is self explanatory, I just can't find an example of what I'm trying to implement.

Thanks in advance

if (img.GetPixel(bottomRightc.X, y) <= Color.FromArgb(255, 255, 255, 255) 
    && 
    img.GetPixel(bottomRightc.X, y) >= Color.FromArgb(255, 166,166,166))
           {
               return false;
           }

EDIT:

Thanks for the replies everyone, I didn't put much thought into the comparison, and saw the problem with it after creating this thread. I think I'll go with brightness comparison since my image has been grayscaled and has a high contrast.

Ash
  • 3,494
  • 12
  • 35
  • 42
  • 1
    It's not that self explanatory - what if your pixel had an RGB value of 250,240,260 ? Should that match or not? – Rowland Shaw Jan 20 '11 at 20:00
  • Are you simply trying to measure albedo (brightness) or something more subtle, like color balance? – Chris B. Behrens Jan 20 '11 at 20:00
  • "Between" is rather undefined for colors. Like Rowland says, is blue "between" red and purple? How about magenta... is it between chartreuse and mauve? Instead of a code example, can you put into words what you're trying to accomplish? – James King Jan 20 '11 at 20:11

4 Answers4

2

Have you considered working in another color space? With HSV/HSB you could simply do something like

if (pixelColor.V <= 255 && pixelColor.V >= 166)
{
    return false;
}

Assuming min-max of Value/Brightness 0-255. And assuming you are trying to accomplish brightness comparison, which is not entirely clear to me.

Edit:

There are methods for this in System.Drawing.Color, and brightness is between 0.0 and 1.0. So the above would become ~something like this:

    if (pixelColor.GetBrightness() <= 1.0f && pixelColor.GetBrightness() >= 166.0f/255.0f)
triazotan
  • 2,192
  • 1
  • 22
  • 32
2

For proper comparison you will need to derive to a single value for each color. A good candidate is luminosity which is nicely covered here. (The wiki article on the topic uses a slightly different set of coefficients for calculations.)

Testing luminosity will allow you to compare the relative lightness/darkness of two colors. This could be very handy for your license plate detection algorithm since the plate is black and white.

Article's example of calculating a color's luminosity, or brightness:

private static int Brightness(Color c)
{
   return (int)Math.Sqrt(
      c.R * c.R * .241 + 
      c.G * c.G * .691 + 
      c.B * c.B * .068);
}

Trying to compare on the individual R, G and B values will most likely get you into trouble otherwise.

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
  • Interesting info, but this particular weighting really only makes sense if you're doing a task that requires interaction with human perception. For a machine recognition task, you're better off weighting based on the material/lighting properties of the object being viewed. For instance, if the text is always blue on a white background, illuminated in broad-spectrum light, using only the red and green components will generally give you a higher contrast for isolating the text. In most cases, the simple unweighted average works just fine; proper lighting is much more important than weighting. – Dan Bryant Jan 20 '11 at 21:15
  • @Dan: This question and my answer are a follow-up to this original question: http://stackoverflow.com/questions/4707607 And the reason why I think luminosity testing might be useful. – Paul Sasik Jan 20 '11 at 21:19
1

Comparison operators are not defined for System.Drawing.Color, so you have to implement your own comparison methods. I suggest using an extension method, for example:

static class ColorExtensions
{
    public static bool Between(this Color c, Color a, Color b)
    {
        /* insert comparison logic here */
    }

    public static bool LessOrEqual(this Color a, Color b)
    {
        /* insert comparison logic here */
    }

    public static bool MoreOrEqual(this Color a, Color b)
    {
        /* insert comparison logic here */
    }
}

so you can use

var color = img.GetPixel(bottomRightc.X, y);
if(color.LessOrEqual(Color.FromArgb(255, 255, 255, 255) &&
   color.MoreOrEqual(Color.FromArgb(255, 166, 166, 166)))
{
    return false;
}

or

if(img.GetPixel(bottomRightc.X, y).Between(
   Color.FromArgb(255, 166, 166, 166),
   Color.FromArgb(255, 255, 255, 255)))
{
    return false;
}
max
  • 33,369
  • 7
  • 73
  • 84
0

Here's my solution to compare colours:

public int Compare(Color x, Color y)
{
    if (x.ToArgb() == y.ToArgb())
        return 0;
    float hx, hy, sx, sy, bx, by;

    // get saturation values
    sx = x.GetSaturation();
    sy = y.GetSaturation();
    // get hue values
    hx = x.GetHue();
    hy = y.GetHue();
    // get brightness values
    bx = x.GetBrightness();
    by = y.GetBrightness();

    // determine order
    // 1 : hue
    if (hx < hy)
        return -1;
    else if (hx > hy)
        return 1;
    else
    {
        // 2 : saturation
        if (sx < sy)
            return -1;
        else if (sx > sy)
            return 1;
        else
        {
            // 3 : brightness
            if (bx < by)
                return -1;
            else if (bx > by)
                return 1;
            else
                return 0;
        }
    }
}

I suppose that you can modify to fit your specific needs! Basically it compares the colour by hue, then by saturation and at last by brightness! (I use this for sorting colours.)

Zolomon
  • 9,359
  • 10
  • 36
  • 49