Color Sensor Gives The RGB Values Of Anything

[Rick Osgood] wanted to build a color sensor that could be held up to any object to get RGB color values. He originally started with a photoresistor and a few LEDs, but couldn’t get that to work reliably. [Rick] finally completed his color sensor after finding a digital luminosity sensor on Adafruit, ending up with a pretty accurate piece of hardware to judge the color of something.

The idea behind the color sensor is to light up red, green, and blue LEDs and see how much light is reflected back from the object with a luminosity sensor. [Rick] chose an Arduino to do all the heavy lifting for the light sensor and activating the LEDs.

After a few tests [Rick] got his color sensor working, but it’s not up to par with what he had expected. This isn’t really a problem: the LEDs probably don’t have the same brightness and the luminosity sensor doesn’t respond evenly across the entire rainbow. Those things can always be fixed in software, though. It’s a nice project that could serve as part of a prototype for this color picker pen.

28 thoughts on “Color Sensor Gives The RGB Values Of Anything

  1. This can’t be fixed in software, unfortunately. Humans don’t just see the three discrete wavelengths of light emitted by the LEDs. You could have a surface which appears yellow in natural light, for instance, which does not reflect any red or green light.

    1. Sure but when the goal is to get the best RGB value, the best set of values for emulating the color on a display that only is capable of red, green and blue does this make a difference?

      1. It does make a difference. Even been under a sodium street lamp? These emit a specific wavelength of yellow. Yet you cannot see any red or green under them because true yellow is not red+green.
        What this needs is a full-spectrum light source and colour filters that have overlaps peaking in Red ending in Green (R), starting in red peaking in green ending in blue (G), starting in green peaking in blue (B). Maybe the B could end in R to get purple form violet.

  2. First of all, awesome idea, keep plugging away.

    Secondly, I’m immediately thinking this could be used for LCD screen calibration. You could, for example, calibrate your screen to your printer.

    More importantly for me, calibrate my screen to the photo processing shop I use to print my photos.

    I think there are commercial screen calibration devices but I haven’t seen one that can measure any color.

    Here’s an idea: instead of changing the light color, what about using a full spectrum light and three sensors with color filters on them? Or one sensor with a changeable filter?

    Cool stuff.

    1. Emissive screens require an emissive colorimeter, not reflective. Emissive colorimeters don’t need an illuminating source because the screen is providing the light. BTW, as you suggested, emissive colorimeters use filters over the sensors to obtain color selectivity.

  3. The offset on the green part is a typically problem.
    Thats why they put more green receivers on a ccd or cmos-chip.
    Also most of the lcd screens have 2 parts green and 1 part red and 1 part blue.
    Try doubling the amount of green light. Also look at the data sheet of the led’s. Try to find the most greenish led, because a lot of green LED’s are shifted to the yellowish side especially if you try to make them really bright.

    This is a wild guess but maybe try lasers.

  4. Nice work, Rick- looking forward to seeing it!

    As for the comments regarding human perception- I don’t think the intent here is to replicate human-eye response, so actually, a lot of normalization can be done in software.

    I think you could get a good start on calibrating your rig by taking some color samples to a paint store and having them analyzed. Most paint stores have a colorimeter that can provide a variety of industry standard color formats that can be translated to RGB values (if they are not provided directly). Once you have some known colorimetric values, you can start tweaking the software response of your colorimeter.

    One other thing- you’ll get more consistent readings if the light source is highly diffuse and even. The idea is to reduce the amount of shadowing created by surface textures, which can give rise to false values.

  5. Thanks for featuring my post. I actually just published another post about this same project. I have tweaked the code a bit and I was able to make darker colors read more accurately at the expense of brighter colors appearing as white: http://www.richardosgood.com/2012/02/07/tweaked-the-color-sensor-code/

    Again it’s not perfect but I’m still trying to learn how this thing responds in different situations to try and write code that is the most accurate all around.

    Bunedoggle, I did think about using three different sensors with filters instead of three LEDs. I just thought it would be less expensive to use only one sensor. That being said, I would like to experiment with using filtered sensors some day to see the difference.

    Laura, I never even thought of diffusing the light. I’ll have to give that a go and see if it helps any.

    1. Not to discourage you from pursuing the current method to it’s perfection but if you did want to try the colored lenses method maybe you can have one sensor behind a motorized wheel with all three lenses embedded in the wheel.

      Or… to keep things really simple while sacrificing ease of use just one filter at a time. You have to measure 3 times, each with a different filter and then it calculates the final value.

    2. you have to calibrate your divice also on how dark or light your sample is.
      First shine with a white light source on your sample and get basic readout on your light sensor.
      Then you use that brightness on all of your 3leds. This will probably get a better result with darker or lighter colours.

      1. This is a fantastic idea. I don’t know why I didn’t think of it. I did think I could have some sort of toggle for “dark colors” and “light colors” but this would be a perfect way to automate that sort of thing. Thank you for the suggestion. I definitely plan to test this out as soon as I have time this week and see if I can make it work.

  6. Alternatively you can use TCS3200 Programmable sensor with white LED. This sensor has 3 banks of 16 individually filtered photo sensors (red, green, blue) and one bank of clear photo sensor: TCS3200-E11.pdf

    The advantage of this sensor is that you can detect color on luminous surfaces such as LCD screens.

    1. Agreed. It isn’t easy to match the color matching functions to the human eye or CIE standards, much less to random displays.

      Also, as with the last HAD project that used this sort of measurement: it can’t measure surfaces that have any fluorescence. Think about a red fluorescent surface: it reflects a little under the red LED, none under green, but produces a lot of light under the blue LED. So you’d measure it as being much bluer than it really is.

      If you’d like to learn more, try these books (not for the faint of heart):
      http://www.amazon.com/Measuring-Colour-Imaging-Science-Technology/dp/1119975379/ref=sr_1_1?ie=UTF8&qid=1328668112&sr=8-1
      http://www.amazon.com/Reproduction-Colour-Imaging-Science-Technology/dp/0470024259/ref=pd_sim_b_4
      http://www.amazon.com/Color-Science-Concepts-Quantitative-Formulae/dp/0471399183/ref=pd_sim_b_2

  7. Have you looked at the spectral curve published for your photo transistor?
    I would not expect equal sensitivity across the spectrum.
    Photo transisitors are sensitive to infrared.
    I understand LED’s are photo sensitive too.
    Photo resitors (I believe) are commonly sensitive to yellow-green spectrum.
    If you’re putting a reference device in the cluster, add a infrared sensor too.
    Or, try infrared filters on your sensors.
    Halogen lights before they produce white light are rich in infrared.
    From what I’ve read on blue LED’s, the light starts out as another color and is converted to make blue.

    Just saying lights sources may not be all what you expect, a white light reference might be saturated in IR.

    Be gentle on correcting me…

    1. I’m actually not using a photo transistor. I’m using a digital luminosity sensor. This sensor has the capability of measuring only infrared light or all light (including infrared). You can subtract the infrared values from the total value to get the measurement of total visible light. That is what I am doing with this project so there should be no infrared light affecting my readings.

  8. Hi,
    That’s a interresting novelty, and something alike can be archieved with cheaper components like a CdS and 2 RGB led. I found a instructables about that 2 months ago and made mine. It works not bad although not as good as the presented project here, but it’s sensibly cheaper.
    If you’re curious, the original instructables and my humble rendition.

  9. I remember a product from wowwee from last years toy fair in Nurnberg that did the same thing.
    Check out their litesprites, it has a wand with which you can pick up any color from any surface and let the sprites light up with the same color.
    See litesprites.com to check it out. That wand might give away some clues to how they did it.

    1. Hi rick,

      I think I have a idea why you never get a 0 255 0 reading with green or a 0 255 255 for Cyan as it should.
      You should try to pwm your led’s, and dim them a bit. Also try to diffuse your light. All the light meters and colorimeters I used diffuse the light.
      Even on full brightness a led on a piece of black paper you will get some readings.
      Especially with the lighter colours this will give you problems.
      I have two possible solutions:
      1: Try to make a reading on different led brightness levels. Start with white paper shine on it with a dimmed red light, turn up the brightness of the red led untill you get a 255 readout on red. Leave the red brightness on that level.
      Repeat this for green and blue.
      And hopefully you will see a better readout.
      2: Or instead of compairing with a reading of white and black, try a readout from a mid grey color, compaire this with every other readout.
      It will make your code simpler and probably give you beter values.

      Maybe this is of any help. I think this is a really nice project.
      thanks for the reference in your post.

Leave a Reply to Justin CaseCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.