I have a solution
The real colour is depend on clear value, I mean you can get correct (and more stable) colour value with the following calculation
tcs.getRawData(&r, &g, &b, &c);
multiplier = 255;
red = (r / c) * multiplier;
green = (g / c) * multiplier;
blue = (b / c) * multiplier;
I have implemented the formula below to get better solution
final_red = red / (red+green+blue)
final_green = green / (red+green+blue);
final_blue = blue / (red+green+blue)
Important note : Since the clear value is always bigger than raw colour, you may need to multiply by some value. In my case I multiplied every colour to 255 to get non zero value.
RGB values received from TCS34725
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- Systembolaget
- Posts: 336
- Joined: Wed Mar 08, 2017 1:01 pm
Re: RGB values received from TCS34725
Maybe useful for others using this sensor to sort and/or recognise also pastel and muddy colours:
1. Use a 5 - 15 mm high ultra-matt black shroud to eliminate all ingress of ambient light; a black v.e.l.v.e.t inner coating works wonders
2. Cut the shroud's top at an angle of 30° - 45° to eliminate specular LED reflections off of your sample to be measured
3. Hold the sample tight over the shroud or press the shroud down on the sample
4. Use an EMA to average as many readings as your time budget per measurement allows
5. Build an array with RGB triples {###, ###, ###} from all your colour samples ("train" or calibrate your code)
Then, you can enjoy reliable colour recognition over a far wider range of colours than most YouTube videos or Instructable tutorials suggest; this sensor is amazing value for money.
ps: Shiny or polished surfaces are difficult, even when angled 45° to avoid specular reflections from the LED back onto the sensor.
pps: Why is "v.e.l.v.e.t" a banned spam word?
1. Use a 5 - 15 mm high ultra-matt black shroud to eliminate all ingress of ambient light; a black v.e.l.v.e.t inner coating works wonders
2. Cut the shroud's top at an angle of 30° - 45° to eliminate specular LED reflections off of your sample to be measured
3. Hold the sample tight over the shroud or press the shroud down on the sample
4. Use an EMA to average as many readings as your time budget per measurement allows
5. Build an array with RGB triples {###, ###, ###} from all your colour samples ("train" or calibrate your code)
Then, you can enjoy reliable colour recognition over a far wider range of colours than most YouTube videos or Instructable tutorials suggest; this sensor is amazing value for money.
ps: Shiny or polished surfaces are difficult, even when angled 45° to avoid specular reflections from the LED back onto the sensor.
pps: Why is "v.e.l.v.e.t" a banned spam word?
- adafruit_support_mike
- Posts: 67454
- Joined: Thu Feb 11, 2010 2:51 pm
Re: RGB values received from TCS34725
Our spam filter keeps a running collection of words that have a high correlation to spam and a low correlation to normal posts. The specific words depend on who's trying to spam us at the moment.Systembolaget wrote:pps: Why is "v.e.l.v.e.t" a banned spam word?
- Systembolaget
- Posts: 336
- Joined: Wed Mar 08, 2017 1:01 pm
Re: RGB values received from TCS34725
That's funny... so that type of fabric is a favourite spam word right now... who would have thought!
-
By the way, when taking measurements with the TCS34725 for 10 minutes, the raw red, green, blue and clear values drift upwards quite a lot, even when the sensor and sample are in a tight ultra-matt black box and controlled temperature; for example clear goes from 12037 after 30 seconds to 14921 after 10 minutes.
This can be troublesome when one leaves the system on and takes colour readings only every minute.
Could it be that the COB LED heats up, thus the current rises, and thus its brightness? The thermal runway effect of non-heat-sinked LEDs?
If so, how could that be controlled? Or is something else the reason for the value drift?
Just found the image below from a popular instructable, where, without being discussed, one can see the values drifting upwards. They have the sensor in a black enclosure.
-
By the way, when taking measurements with the TCS34725 for 10 minutes, the raw red, green, blue and clear values drift upwards quite a lot, even when the sensor and sample are in a tight ultra-matt black box and controlled temperature; for example clear goes from 12037 after 30 seconds to 14921 after 10 minutes.
This can be troublesome when one leaves the system on and takes colour readings only every minute.
Could it be that the COB LED heats up, thus the current rises, and thus its brightness? The thermal runway effect of non-heat-sinked LEDs?
If so, how could that be controlled? Or is something else the reason for the value drift?
Just found the image below from a popular instructable, where, without being discussed, one can see the values drifting upwards. They have the sensor in a black enclosure.
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: RGB values received from TCS34725
As you suggest, it is likely due to heating of the LED. There will be some change in sensor responsivity with temperature also, but mostly in the near IR range.
A simple solution would be to turn off the LED between samples to allow it to cool.
Another approach is to calibrate against standard targets before each sample.
The ideal approach would be to use an external light source with a heat-sink and temperature sensors - plus periodic calibration to detect and correct for drift. On one medical instrumentation-grade spectrophotometer, we allowed the emitter temperature to stabilize for 15 minutes before initial calibration - and performed periodic full calibrations in addition to 1-point calibrations before each sample.
A simple solution would be to turn off the LED between samples to allow it to cool.
Another approach is to calibrate against standard targets before each sample.
The ideal approach would be to use an external light source with a heat-sink and temperature sensors - plus periodic calibration to detect and correct for drift. On one medical instrumentation-grade spectrophotometer, we allowed the emitter temperature to stabilize for 15 minutes before initial calibration - and performed periodic full calibrations in addition to 1-point calibrations before each sample.
- Systembolaget
- Posts: 336
- Joined: Wed Mar 08, 2017 1:01 pm
Re: RGB values received from TCS34725
Ok, thanks for your input... the LED, as I expected. See this half-hour test I ran over lunchtime; looks like the values would want to go higher still, if I would leave everything on for half a day or so.
With a shroud and controlled ambient temperature, I was happy to see results with 12 colours after just a minute, comparing the numbers read to the ones stored; it looked like even more successful than the 5-colour-candy colour sorters one finds on the WWW. I am testing flat matt powder-coated sheet metal samples, some pastel, some murky, some bright. I thought I was done.
But then, doing the same exercise 20 minutes or over an hour later, none of my samples was matched within +/- 5 units, because of the value drift, strongest with the blue value.
I really want to use the sensor with LED as it is. I don't need medical grade accuracy. So now my idea is to sample each sheet metal sample for 30 minutes, find the average for red, green and blue, and then use the red, green and blue percentage/ratio from that average for comparison. If I don't leave the setup powered for over half an hour, I assume I can get a good match?
That brings me to a question.
As a not-quite beginner anymore, I know I can store each sample's red, green and blue ratio-triple {0.48, 0.35, 0.17} in an array. Is there a more clever way to measure a sample and then have the serial monitor output "1021" (RAL colour number) instead of coding a long tail of manually fine-tuned if/else statements? Meaning how can I search with the sensor's output (converted to ratios) in the array? Or is a long tail of if/else statements like
the best way?
Maybe also the RAL number can be added to each sample's array entry to become a quadruple {0.48, 0.35, 0.17, 1021}?
Thanks in advance!
With a shroud and controlled ambient temperature, I was happy to see results with 12 colours after just a minute, comparing the numbers read to the ones stored; it looked like even more successful than the 5-colour-candy colour sorters one finds on the WWW. I am testing flat matt powder-coated sheet metal samples, some pastel, some murky, some bright. I thought I was done.
But then, doing the same exercise 20 minutes or over an hour later, none of my samples was matched within +/- 5 units, because of the value drift, strongest with the blue value.
I really want to use the sensor with LED as it is. I don't need medical grade accuracy. So now my idea is to sample each sheet metal sample for 30 minutes, find the average for red, green and blue, and then use the red, green and blue percentage/ratio from that average for comparison. If I don't leave the setup powered for over half an hour, I assume I can get a good match?
That brings me to a question.
As a not-quite beginner anymore, I know I can store each sample's red, green and blue ratio-triple {0.48, 0.35, 0.17} in an array. Is there a more clever way to measure a sample and then have the serial monitor output "1021" (RAL colour number) instead of coding a long tail of manually fine-tuned if/else statements? Meaning how can I search with the sensor's output (converted to ratios) in the array? Or is a long tail of if/else statements like
Code: Select all
if ((r > 1.4) && (g < 0.9) && (b < 0.9)) {
// Do some stuff
}
Maybe also the RAL number can be added to each sample's array entry to become a quadruple {0.48, 0.35, 0.17, 1021}?
Thanks in advance!
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: RGB values received from TCS34725
I'm not familiar with the RAL system. It seems to be closer to the HSV model than to RGB. There are algorithms for converting RGB to HSV: https://gist.github.com/fairlight1337/4 ... bcc1ba5c72
I see that there are plenty of RGB->RAL on-line converters. I suspect that somewhere there is a published algorithm for performing that conversion also.
I see that there are plenty of RGB->RAL on-line converters. I suspect that somewhere there is a published algorithm for performing that conversion also.
- Systembolaget
- Posts: 336
- Joined: Wed Mar 08, 2017 1:01 pm
Re: RGB values received from TCS34725
Luckily, I don't actually need to convert anything. The matching RAL number can be stored in the array, together with each sample's RGB ratio. The question is "only" how without an endless tail of if/else statements, I can do the following; it's really just one of those "colour sorters", but more accurate and with far more colours in the end. With the question from before, this is what I want to achieve:
A. Power up and wait an hour (LED settles, still open question)
B. Scan all colour samples -> obtain r, g, b, w (modified Adafruit tcs34725 sketch), i.e. {2774, 3288, 4329, 10595}
C. Values go into Excel (via CoolTerm) -> I get all r, g, b sums, i.e. {10391} -> I get all r, g, b ratios, i.e. {0.27, 0.32, 0.42}
D. Put all r, g, b ratio triples in an array
E. Put corresponding RAL number "1234" (int/float) into another array, or add to corresponding ratio triple
F. Put corresponding linear actuator distance "567" (int/float) into yet another array, or add to corresponding ratio quadruple
G. Result: one array with a quintuple {0.27, 0.32, 0.42, 1234, 567} for each colour
1. Power up and wait an hour (LED settles, still open question)
2. Put a sample on the sensor shroud -> obtain r, g, b, w (don't really need w for colour sorting application)
3. Compare value triple (or quadruple) with those in array -> The colour gets identified
4. Output "1234" on a large OLED display and move linear actuator
5. Go to 2. after 1-5 minutes and read another sample...
My main problem, as a sort of beginner, is "only" at 3. (coding issue) and at A./1. (physical issue) which is where I wonder how those simple colour sorter or even simpler colour servo indicator projects work, where users also must have LED thermal runway and uptime value drift issues, but those are never mentioned in any project I reviewed on the WWW.
A. Power up and wait an hour (LED settles, still open question)
B. Scan all colour samples -> obtain r, g, b, w (modified Adafruit tcs34725 sketch), i.e. {2774, 3288, 4329, 10595}
C. Values go into Excel (via CoolTerm) -> I get all r, g, b sums, i.e. {10391} -> I get all r, g, b ratios, i.e. {0.27, 0.32, 0.42}
D. Put all r, g, b ratio triples in an array
E. Put corresponding RAL number "1234" (int/float) into another array, or add to corresponding ratio triple
F. Put corresponding linear actuator distance "567" (int/float) into yet another array, or add to corresponding ratio quadruple
G. Result: one array with a quintuple {0.27, 0.32, 0.42, 1234, 567} for each colour
1. Power up and wait an hour (LED settles, still open question)
2. Put a sample on the sensor shroud -> obtain r, g, b, w (don't really need w for colour sorting application)
3. Compare value triple (or quadruple) with those in array -> The colour gets identified
4. Output "1234" on a large OLED display and move linear actuator
5. Go to 2. after 1-5 minutes and read another sample...
My main problem, as a sort of beginner, is "only" at 3. (coding issue) and at A./1. (physical issue) which is where I wonder how those simple colour sorter or even simpler colour servo indicator projects work, where users also must have LED thermal runway and uptime value drift issues, but those are never mentioned in any project I reviewed on the WWW.
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: RGB values received from TCS34725
There is no need for endless if/else statements. If you build such an array, you can iterate though it in a loop to do the comparisions. Your comparison routine will probably need a 'tolerance factor', since the a 100% match is not likely.
Since RAL seems to bin colors primarily by hue, you might consider converting the RGB to HSV first to narrow your search.
Since RAL seems to bin colors primarily by hue, you might consider converting the RGB to HSV first to narrow your search.
- Systembolaget
- Posts: 336
- Joined: Wed Mar 08, 2017 1:01 pm
Re: RGB values received from TCS34725
Thanks, but that is exactly the question, how I could loop through an array of triples or, rather, quintuples - and how to bring sufficient tolerance into play.If you build such an array, you can iterate though it in a loop to do the comparisions. Your comparison routine will probably need a 'tolerance factor', since the a 100% match is not likely.
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: RGB values received from TCS34725
Assuming you have a table of RGB tuples, you could start by looping down through the 'R" column until you find the first value that matches within the tolerance band.
If the G and B columns are also within the tolerance band, you have a match. If not, you move on to the next row with a matching R value.
If the G and B columns are also within the tolerance band, you have a match. If not, you move on to the next row with a matching R value.
- Systembolaget
- Posts: 336
- Joined: Wed Mar 08, 2017 1:01 pm
Re: RGB values received from TCS34725
Alright, looping through the "r", then "g", then "b"... sort of a cascade by the sound of it.
Do you happen to know some online resource where one can learn about such more complex constructions? My C book for Arduino is not going too deep into things like finding matching data in arrays.
Or maybe these constructions have a name in the professional community, something I could then search for.
Do you happen to know some online resource where one can learn about such more complex constructions? My C book for Arduino is not going too deep into things like finding matching data in arrays.
Or maybe these constructions have a name in the professional community, something I could then search for.
- adafruit_support_bill
- Posts: 88096
- Joined: Sat Feb 07, 2009 10:11 am
Re: RGB values received from TCS34725
Assuming you have defined a structure called rgbSample and have defined a table full of them:
Code: Select all
int SearchTable(rgbSample sample)
{
for (int i = 0; i < tableSize; i++)
{
if (abs(table[i].r - sample.r) <= tolerance)
{
if (abs(table[i].g - sample.g) <= tolerance)
{
if (abs(table[i].b - sample.b) <= tolerance)
{
return i; // this is a match
}
}
}
}
return -1; // failed to find a match
}
- Systembolaget
- Posts: 336
- Joined: Wed Mar 08, 2017 1:01 pm
Re: RGB values received from TCS34725
Thanks, that's quite some cascade to get me started ; ) I'm reading array book chapters to understand your suggestion; I don't want to just copy and paste code without really understanding what is what.
This is the array with 12 colours to begin with:Where the values are:
Later, I will add more.
If I pre-sort (hard-code) the array for r in Excel, there are five "close calls" to cater to:
1 and 12 differ sufficiently (> 0.02) first in w
2 and 4 differ sufficiently (> 0.02) already in g
5 and 11 differ sufficiently (> 0.02) already in g
6 and 9 differ sufficiently (> 0.02) already in g
6 and 7 differ sufficiently (> 0.02) first in w
It looks that testing for b is maybe not necessary, but testing for w; so w needs to go in the array, too.
So, now I have to dig in!
This is the array with 12 colours to begin with:
Code: Select all
const float SAMPLES[][5] = { // See initial colour training approach
{0.47, 0.35, 0.18, 10},
{0.62, 0.24, 0.14, 20},
{0.64, 0.18, 0.18, 30},
{0.60, 0.17, 0.22, 40},
{0.42, 0.26, 0.32, 50},
{0.27, 0.32, 0.42, 60},
{0.29, 0.33, 0.38, 70},
{0.18, 0.37, 0.45, 80},
{0.26, 0.45, 0.30, 90},
{0.35, 0.43, 0.23, 100},
{0.42, 0.40, 0.18, 110},
{0.48, 0.35, 0.17, 120},
};
Code: Select all
{red, green, blue, ralNumber, actuatorMovement}
If I pre-sort (hard-code) the array for r in Excel, there are five "close calls" to cater to:
1 and 12 differ sufficiently (> 0.02) first in w
2 and 4 differ sufficiently (> 0.02) already in g
5 and 11 differ sufficiently (> 0.02) already in g
6 and 9 differ sufficiently (> 0.02) already in g
6 and 7 differ sufficiently (> 0.02) first in w
It looks that testing for b is maybe not necessary, but testing for w; so w needs to go in the array, too.
So, now I have to dig in!
- mirz11
- Posts: 2
- Joined: Fri Sep 21, 2018 2:52 am
Re: RGB values received from TCS34725
Hi mate, what method do you use to convert the raw color values to 0-255?Systembolaget wrote:That's funny... so that type of fabric is a favourite spam word right now... who would have thought!
-
By the way, when taking measurements with the TCS34725 for 10 minutes, the raw red, green, blue and clear values drift upwards quite a lot, even when the sensor and sample are in a tight ultra-matt black box and controlled temperature; for example clear goes from 12037 after 30 seconds to 14921 after 10 minutes.
This can be troublesome when one leaves the system on and takes colour readings only every minute.
Could it be that the COB LED heats up, thus the current rises, and thus its brightness? The thermal runway effect of non-heat-sinked LEDs?
If so, how could that be controlled? Or is something else the reason for the value drift?
Just found the image below from a popular instructable, where, without being discussed, one can see the values drifting upwards. They have the sensor in a black enclosure.
Thank you!
Please be positive and constructive with your questions and comments.