1

I am trying to create a program about non-linear regression. I have three parameters [R,G,B] and I want to obtain the temperature of any pixel on image with respect to my reference color code. For example:

Reference Files R,G,B,Temperature = [(157,158,19,300),(146,55,18,320),(136,57,22,340),(133,88,25,460),(141,105,27,500),(210,195,3,580),(203,186,10,580),(214,195,4,600),(193,176,10,580)]

You can see above, all RGB values change as non-linear. Now, I use "minimum error algorithm" to obtain temperature w.r.t. RGB color codes but I want to obtain a value that not exist in the reference file (i.e. If I have (155,200,40) and it is not exist in reference file, I must obtain this three codes is equal to which temperature).

Here is the code to select the closest reference temperature given a RGB value:

from math import sqrt

referenceColoursRGB =[(157,158,19),
(146,55,18),
(136,57,22),
(133,88,25),
(141,105,27),
(203,186,10),
(214,195,4)]


referenceTemperatures = [
300,
320,
340,
460,
500,
580,
600]

def closest_color(rgb):
    r, g, b = rgb
    color_diffs = []
    counter = 0
    for color in referenceColoursRGB:
        cr, cg, cb = color
        color_diff = sqrt(abs(r - cr)**2 + abs(g - cg)**2 + abs(b - cb)**2)
        color_diffs.append((color_diff, color))
        minErrorIndex =color_diffs.index(min(color_diffs))
    return minErrorIndex

temperatureLocation = closest_color((149, 60, 25))
print("Temperature : ", referenceTemperatures[temperatureLocation])
# => Temperature :  320

temperatureLocation = closest_color((220, 145, 4))
print("Temperature : ", referenceTemperatures[temperatureLocation])

# => Temperature :  580

I really want to calculate temperature values that don't appear in the reference list, but I am having problems using all RGB values and calculating/predicting reasonable/accurate temperatures from them.

I tried to obtain 1 parameter after that used polyfit but there is some problem because every variable have same effect on this one parameter. Therefore I can't realize which color code is highest (i.e. "oneParameter = 1000 *R + 100 *G + 10 *B" , in this situation if I have a parameter that color code is (2,20,50) and another color code is (2,5,200). As a result they are equal w.r.t. "oneParameter" equation)

I hope I explain my problem clearly. I am waiting for your helps !

Thank you.

rickhg12hs
  • 10,638
  • 6
  • 24
  • 42
  • does this help you ? https://stackoverflow.com/questions/13552907/way-to-pass-multiple-parameters-to-a-function-in-python. example: `def func(parameter): r,g,b = parameter` `param = (2,20,50)` `func(param)`. You don't need to compute "1 parameter" to pass to function, if you need to pass everything at once, put them into a tuple or a list instead. – AcaNg Sep 16 '21 at 07:13
  • It is hard for us to say what the problem with your code is without seeing the code. – BoarGules Sep 16 '21 at 07:15
  • I used this "https://stackoverflow.com/questions/54242194/python-find-the-closest-color-to-a-color-from-giving-list-of-colors". I changed colour names with temperature in this example and when send RGB codes to this function, it returns temperature in reference file. But I want to obtain a parameter that is not in the reference file with an interpolation-like method. – Neo Aerospace Sep 16 '21 at 07:43
  • You don't provide the minimal code or math needed to for us to understand how you're doing the various things you tried or what you want. What's your "minimum error algorithm" to get temperature from RGB values? `oneParameter` looks like a linear function of 3 RGB variables, but you say you used a polynomial fit which only deals with a function of 1 variable. It's just not explained clearly at all. – BatWannaBe Sep 16 '21 at 09:04
  • I submitted my code, you can see it below. It works fine but it is not sufficient for me. I want to obtain more sensitive temperature w.r.t. RGB codes. You see in code, I can not obtain the "315.25 celsius" because it is not exist in "referenceTemperatures" list. But if I can write an equation from this datas, I can obtain whatever temperature in "300-600 celsius". Inputs of this equation will be the RGB and output is specific temperature – Neo Aerospace Sep 16 '21 at 11:03

2 Answers2

0
from math import sqrt

referenceColoursRGB =[(157,158,19),
(146,55,18),
(136,57,22),
(133,88,25),
(141,105,27),
(203,186,10),
(214,195,4)]


referenceTemperatures = [
300,
320,
340,
460,
500,
580,
600]

def closest_color(rgb):
    r, g, b = rgb
    color_diffs = []
    counter = 0
    for color in referenceColoursRGB:
        cr, cg, cb = color
        color_diff = sqrt(abs(r - cr)**2 + abs(g - cg)**2 + abs(b - cb)**2)
        color_diffs.append((color_diff, color))
        minErrorIndex =color_diffs.index(min(color_diffs))
    return minErrorIndex

temperatureLocation = closest_color((149, 60, 25))
print("Temperature : ", referenceTemperatures[temperatureLocation])
# => Temperature :  320

temperatureLocation = closest_color((220, 145, 4))
print("Temperature : ", referenceTemperatures[temperatureLocation])

# => Temperature :  580
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-ask). – Community Sep 16 '21 at 11:28
  • I think you want to add this "answer" as an edit to your question. I.e., this is your current approach to select the closest color/temp from your reference. If I understand your question, you are seeking a function that takes an arbitrary RGB color and calculates the temperature, yes? – rickhg12hs Sep 17 '21 at 02:28
  • Absolutely @rickhg12hs – Neo Aerospace Sep 17 '21 at 17:46
  • @NeoAerospace Will you edit your original question to include your code, or would you like me to edit it? – rickhg12hs Sep 17 '21 at 22:14
0

N.B.: I can't vouch for the physical accuracy of this prediction, but this might be along the lines of what you're looking for. I.e., this makes the predictions match your reference data exactly, but I have no idea how accurate the temperature predictions might be for non-reference RGB colors. If I knew the exact physics of the mapping from RGB to temperature, I'd use that.

Bad Model 1

One simple way to do nonlinear regression is to preprocess your data so that you have nonlinear terms for your regression. sklearn has a builtin preprocessing function to do this by generating powers and interactions of the original input data.

referenceColoursRGB =[(157,158,19),
(146,55,18),
(136,57,22),
(133,88,25),
(141,105,27),
(203,186,10),
(214,195,4)]

referenceTemperatures = [
300,
320,
340,
460,
500,
580,
600]

from sklearn import linear_model
from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(degree=2)
poly_RGB = poly.fit_transform(referenceColoursRGB)

ols = linear_model.LinearRegression()
ols.fit(poly_RGB, referenceTemperatures)

ols.predict(poly_RGB)
# array([300., 320., 340., 460., 500., 580., 600.])

To make non-reference RGB predictions, you would do something like:

ols.predict(poly.transform([(149, 60, 25)]))
# array([369.68980598])

ols.predict(poly.transform([(220, 145, 4)]))
# array([949.34548347])

EDIT: Bad Model 2

So, before I picked something simple to implement a nonlinear fit using PolynomialFeatures without regard to any real physics that might be going on at the RGB sensor. You can decide if it fits your needs. Well, here's another model that uses RGB ratios without any regard to whatever physics is happening. Again, you can decide if this model is appropriate.

rat_RGB = [(r, g, b, r/g, r/b, g/r, g/b, b/r, b/g) for r,g,b in referenceColoursRGB]
rat_ols = linear_model.LinearRegression()
rat_ols.fit(rat_RGB, referenceTemperatures)
rat_ols.predict(rat_RGB)
# array([300., 320., 340., 460., 500., 580., 600.])

You can see that this model can also be fit perfectly to the reference data. It's interesting, and probably important to note that the other example predictions produce different temperatures with this model.

rat_ols.predict([(r, g, b, r/g, r/b, g/r, g/b, b/r, b/g) for r,g,b in [(149, 60, 25)]])
# array([481.79424789])

rat_ols.predict([(r, g, b, r/g, r/b, g/r, g/b, b/r, b/g) for r,g,b in [(220, 145, 4)]])
# array([653.06116368])

I hope you can find/develop a RGB/temp model that is physics based. I am wondering if the manufacturer of your RGB sensor has some specifications and/or engineering notes that might help.

rickhg12hs
  • 10,638
  • 6
  • 24
  • 42
  • Thank you for your answer. You stated in your answer that you are not sure of its accuracy. But accuracy becomes a really important factor. How can I check the correctness of this code? I don't know how to switch from RGB to temperature and I'm trying to find a way. I hope your answer will work. Finally, in the code you wrote, does sklearn perform a curve fitting by using RGB codes (3 different parameters) at the same time? – Neo Aerospace Sep 17 '21 at 17:53
  • @NeoAerospace The code uses all `referenceColoursRGB` (and their squares because of `PolynomialFeatures(degree=2)`) with all `referenceTemperatures` to fit a linear model. You can read about `sklearn`'s `linear_model.LinearRegression()` to see how it's done. You can also look at `ols.coef_` to see the fitted coefficients. You could check the accuracy with either more reference RGB/temp pairs or possibly only use some of the current reference pairs to do a fit and then check the accuracy with the remaining pair(s). To have high confidence in the RGB/temp model, more references would be ideal. – rickhg12hs Sep 17 '21 at 22:09
  • @NeoAerospace Edit my above comment ... "The code uses all `referenceColoursRGB` (and their squares *_and interactions_* because of `PolynomialFeatures(degree=2)`) with all `referenceTemperatures` ..." I.e., the input `(R,G,B)` is transformed into `(1,R,G,B,R*R,R*B,R*G,G*G,G*B,B*B)`. – rickhg12hs Sep 18 '21 at 01:35
  • @NeoAerospace I added another model that can fit the reference data exactly. With more parameters than references, there are probably an infinite number of models that will fit the reference data exactly. I think my willy-nilly data munging may be detrimental to your project's success. Please seek a physics based model so that your temperature predictions are based on something worthwhile and convincing. – rickhg12hs Sep 18 '21 at 02:50
  • Excellent job! Your results seem more appropriate than I do :) . I am searching about RGB/temp relationship but it has not standard progress, especially in my situation. I have obtained some information about "wavelength". In this method, we use HSV codes instead of RGB codes. After, switch the H code to wavelength (because of the every color has different wave length). But there is an important problem: My colors H code is generally same, sometimes change only S or V value. As a result I could not use this method. – Neo Aerospace Sep 18 '21 at 07:28
  • I have one more problem. My data package includes limited number of data about 54. I try your code on my reference RGB codes but it works about %15 correctness. How can I improve this result ? @rickhg12hs – Neo Aerospace Sep 18 '21 at 17:09
  • @NeoAerospace You need a reasonable physical model of how your RGB sensor reacts to imaging your heat source so that an accurate temperature can be determined. All I did was make up two arbitrary models that could exactly match the reference RGB/temp data from your Python code. I could make many more models that do the same, but I have little clue what the *proper* physical model should be. Maybe searching for question/answers, or posting a new question at https://physics.stackexchange.com/ might help. – rickhg12hs Sep 19 '21 at 06:00