Go Down

Topic: Using the TCS34725 to get HSL values from RGB data (Read 548 times) previous topic - next topic

LuciusMaximus

I bought the TCS34725 to get HSL values from the RGB data. I move the sensor with an accelerating speed across a perfect rainbow. Using the raw data from the RGB sensor I tried to convert the values to HSL. The main thing that I am interested in, is the Hue. I wish to know the exact position of the sensor using the rainbow. I used the github RGBconverter to do this, but it seems that there is a wobble in my graph line. I doubt that it is because of the rainbow might be imperfect, or that the sensor might be giving me wrong values. What I want is a linear graph line without the wobble. I put the arduino code, RGB values and Hue values in the description.

jremington

#1
Nov 15, 2018, 04:31 pm Last Edit: Nov 15, 2018, 04:42 pm by jremington
Please use code tags to post your code, as described in "How to use this forum".
Code: [Select]
#include <Wire.h>
#include "Adafruit_TCS34725.h"

float red;
float green;
float blue;
float Maximum;
float Minimum;
float rd;
float gd;
float bd;



Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_2_4MS, TCS34725_GAIN_16X);
 
void setup(void) {
Serial.begin(115200);

}

void loop(void) {
uint16_t r, g, b, c;

tcs.getRawData(&r, &g, &b, &c);
red=r;
green=g;
blue=b;

rd=red/255;
gd=green/255;
bd=blue/255;

Maximum= max(rd,gd);
Maximum=max(Maximum,bd);
Minimum= min(rd,gd);
Minimum=min(Minimum,bd);

float h, s, l = (Maximum + Minimum) / 2;

if (Maximum == Minimum) {
    h = s = 0; // achromatic
} else {
    double d = Maximum - Minimum;
    s = l > 0.5 ? d / (2 - Maximum - Minimum) : d / (Maximum + Minimum);
    if (Maximum == rd) {
        h = (gd - bd) / d + (gd < bd ? 6 : 0);
    } else if (Maximum == gd) {
        h = (bd - rd) / d + 2;
    } else if (Maximum == bd) {
        h = (rd - gd) / d + 4;
    }
    h /= 6;
}


//Serial.print((h),10);Serial.print(" ");//Serial.print(lap);
Serial.print(b);Serial.print(" ");Serial.print(r);Serial.print(" ");Serial.print(g);Serial.print(" ");
Serial.println(" ");

}


The color sensor needs to be calibrated for your particular input in order for the numbers it outputs to mean much. Google "tcs34725 calibrate" for lots of ideas.
No PM's please.

LuciusMaximus

Thank you for your response,

The thing is that I havent found a proper way to calibrate the sensor yet.
Some say, just make the maximum value of the RGB values a constant maximum, but this does not work properly when converting to HSL values. So I am searching for a way to calibrate the sensor the correct way.

jremington

#3
Nov 21, 2018, 04:13 pm Last Edit: Nov 21, 2018, 04:50 pm by jremington
You haven't clearly described your input, so anyone would be just guessing what the real problem is. The graphs don't mean anything to me.

If the input source is a rainbow printed on a piece of paper, and you want a linear position output, the obvious thing to do is to collect a bunch of raw data, as a function of position, as you move the sensor across the paper.

It might be possible to a curve to the set of 3D points that emerge, and use that curve to get the position. Or just use a lookup table.

Why on earth would you use an "accelerating speed" to move the sensor?
No PM's please.

LuciusMaximus

The rainbow is printed on a straight line of paper (It is precisely like the rainbow in the link). The input of the sensor is the color that is being reflected by the rainbow at that point of the line. When I move the sensor from the left side of the rainbow to the right side of the rainbow I want to know the distance that the sensor has traveled with an accuracy of 0.1 millimeters (which should be possible). I convert the RGB values to HSL because it would be the easiest way to convert the values to an angle and then in my case to a position. That is why I am interested in the Hue. But even when I move the sensor at a constant speed across the rainbow, there are still points where the Hue does not follow the constant increase in position. That is why I am surprised that the Hue values that i uploaded earlier are not following a linear line, but more like an angular sine. I want that line to be a constant increasing line, because the travel speed of the sensor is constant.
The reason why I am doing this is because I was asked to.

jremington

#5
Nov 21, 2018, 05:27 pm Last Edit: Nov 22, 2018, 01:24 am by jremington
Quote
The reason why I am doing this is because I was asked to.
If you want to actually solve this problem, you will need to use your imagination, and not rely on poorly thought out, possibly unworkable instructions.

Quote
I am surprised that the Hue values that i uploaded earlier are not following a linear line
For an uncalibrated sensor, that should surprise no one. The PRINTER is not calibrated, either. One sensor calibration approach would be to print out a red, green and blue squares at full intensity and saturation. Take readings off of several points on each square, average them and scale the R, G and B outputs so that the values produced are equal.

For the concept of hue to work, the fractional amounts of red, green and blue in the samples should always add up to 1.

Quote
The rainbow is printed on a straight line of paper
How was the rainbow generated? Was only the hue value changed, from one end to the other?
No PM's please.

LuciusMaximus

I have been unsuccessful in generating the perfect gradient between the Hue values in a rainbow ring. The best result I got came from an image printed on glossy paper with a resolution of 200 ppi. I removed the remaining error using polynomial transfer characteristics with a resolution of 1200 data points in its lookup table. The offset of the TCS34725 is now less than 0.1 mm. The calibration was performed in a dark, closed of environment so that there is none, to little noise from the surrounding light.

wvmarle

Printed (reflected) colour is different from transmissive colours. Certain colours such as bright greens and oranges you can display on your computer monitor (in RGB) can not be printed (in CMYK). Likewise there are print colours that can't be reproduced on the monitor. If you display this rainbow on your monitor and use that for your sensor you are likely to have a very different result.

That's the first problem you have to solve as you're working with an RGB sensor to look at CMYK (printed) colours, as you CAN NOT print RGB (you may think you can - RGB images are simply converted by your printer driver to the closest CMYK equivalent...)
Quality of answers is related to the quality of questions. Good questions will get good answers. Useless answers are a sign of a poor question.

Go Up