Phil Pilgrim (PhiPi)
12-17-2009, 02:33 PM
Attached is a demo written for the new ColorPAL (http://www.parallax.com/Store/Sensors/ColorLight/tabid/175/ProductID/617/List/0/Default.aspx?SortField=ProductName,ProductName) RGB color sensor and the Propeller Demo Board. It displays color data and an interpretation of the color the ColorPAL sees on a VGA screen. Included with the demo program is a ColorPAL object that can be used with your own programs.
The first thing the demo program does when it starts is a white balance. This means that when the program starts, the ColorpAL needs to be looking at something white. If you save the demo in EEPROM, you can take a new white balance whenever you press the RESET button. By calibrating the ColorPAL to a known white color, each raw RGB component sensed afterward can be referenced to and corrected by the white components, as follows:
····CorrectedR,G,B = 255 * RawR,G,B / WhiteR,G,B
To keep things running smoothly, each color read is corrected to white and averaged over sixteen samples. The average RGB values are then displayed on the screen. Showing the actual RGB color on the screen is a bit more complicated. Although each sensed RGB color component can range from 0 to 255, each displayable color component can take on only one of the four values 0, 85, 170, or 255 ($00, $55, $AA, and $FF). The simplistic way to convert a sensed color to a displayed color would be to pick the value among the four displayable ones that's closest, for each RGB component. Unfortunately, this does not give the best results. Consider the color purple, as sensed by the ColorPAL: its RGB components are (76, 58, 86). Clearly, there's more red and blue than green. But the nearest VGA value to each of those is 85, and (85, 85, 85) is dark gray.
It turns out (after a lot of experimenting) that the simplest way to get a reasonable VGA color approximation to the sensed color is just to multiply the sensed components by each of $0.C0, $0.C1, ..., $1.3F, $1.40 (i.e. 0.75 to 1.25), convert each product that's no bigger than $FF by shifting right by 6 and pack the results into a 6-bit number to yield an index into the 64 VGA colors. Then the program keeps track of how many times each VGA color gets a "hit" over all the multipliers. The one that gets the most hits wins. The result is a pretty fair representation of the sensed color, to the extent that one of the available 64 colors can represent it.
Here's a photo of the ColorPAL looking at "Wasabi Green", one of my more troublesome colors:
http://forums.parallax.com/attachment.php?attachmentid=65945
Here's a representation of the VGA output screen:
http://forums.parallax.com/attachment.php?attachmentid=65946
BTW, in the spirit of full disclosure, I did photoshop this to match the color actually displayed on the VGA screen, rather than the washed-out color my camera recorded.
Anyway, if you have a ColorPAL (they're only $19.99, after all http://forums.parallax.com/images/smilies/smile.gif ), get some paint chips from your local hardware store, and give this program a try!
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 12/30/2009 5:16:59 AM GMT
The first thing the demo program does when it starts is a white balance. This means that when the program starts, the ColorpAL needs to be looking at something white. If you save the demo in EEPROM, you can take a new white balance whenever you press the RESET button. By calibrating the ColorPAL to a known white color, each raw RGB component sensed afterward can be referenced to and corrected by the white components, as follows:
····CorrectedR,G,B = 255 * RawR,G,B / WhiteR,G,B
To keep things running smoothly, each color read is corrected to white and averaged over sixteen samples. The average RGB values are then displayed on the screen. Showing the actual RGB color on the screen is a bit more complicated. Although each sensed RGB color component can range from 0 to 255, each displayable color component can take on only one of the four values 0, 85, 170, or 255 ($00, $55, $AA, and $FF). The simplistic way to convert a sensed color to a displayed color would be to pick the value among the four displayable ones that's closest, for each RGB component. Unfortunately, this does not give the best results. Consider the color purple, as sensed by the ColorPAL: its RGB components are (76, 58, 86). Clearly, there's more red and blue than green. But the nearest VGA value to each of those is 85, and (85, 85, 85) is dark gray.
It turns out (after a lot of experimenting) that the simplest way to get a reasonable VGA color approximation to the sensed color is just to multiply the sensed components by each of $0.C0, $0.C1, ..., $1.3F, $1.40 (i.e. 0.75 to 1.25), convert each product that's no bigger than $FF by shifting right by 6 and pack the results into a 6-bit number to yield an index into the 64 VGA colors. Then the program keeps track of how many times each VGA color gets a "hit" over all the multipliers. The one that gets the most hits wins. The result is a pretty fair representation of the sensed color, to the extent that one of the available 64 colors can represent it.
Here's a photo of the ColorPAL looking at "Wasabi Green", one of my more troublesome colors:
http://forums.parallax.com/attachment.php?attachmentid=65945
Here's a representation of the VGA output screen:
http://forums.parallax.com/attachment.php?attachmentid=65946
BTW, in the spirit of full disclosure, I did photoshop this to match the color actually displayed on the VGA screen, rather than the washed-out color my camera recorded.
Anyway, if you have a ColorPAL (they're only $19.99, after all http://forums.parallax.com/images/smilies/smile.gif ), get some paint chips from your local hardware store, and give this program a try!
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 12/30/2009 5:16:59 AM GMT