Calculer une équation de stimulus pour un capteur de couleur — Les-mathematiques.net The most powerful custom community solution in the world

Calculer une équation de stimulus pour un capteur de couleur

Bonjour
Je cherche à créer un programme (c#, java, C, ...) pour créer une équation de stimulus XYZ CIE 1931 pour un capteur de couleur, et surtout j'ai besoin d'aide car je ne suis pas super bon en mathématique.
Donc je cherche une fonction qui me permettrait de calculer l'équation de stimulus suite à un étalonnage du capteur de couleur.
Je sais qu'il faut des données d'entrées pour définir la formule mathématique exacte et donc le code informatique de cette fonction.
Voici donc les données.
Je veux utiliser un capteur AS7341, ce capteur à 8 canaux sur différentes longueurs d'ondes (souvent les capteurs simple ont juste du Rouge, Vert et bleu).
Je vais faire l'étalonnage avec plusieurs sources de lumières dont voici la liste
- Lampe à filament 2700K
- Lampe basse conso 2700K
- Lampe LED 3000K
- Lampe LED 4000K
- Lampe basse conso 5500K
- Lampe basse conso 6400K
- Lumière du jour par temps nuageux
- Lumière du jour par temps ensoleillé
- Lumière du jour par temps au coucher
Cela fait donc un tableau / liste de valeurs pour ce capteur de 9 lignes (les sources) par 10 colonnes (8 Colonnes pour chaque canal correspondant à une longueur d'onde du capteur + une colonne correspondant à la température de couleur de la source lumineuse + une colonne correspondante à son éclairement en LUX / luminance).
Je souhaiterais donc de l'aide pour savoir comment calculer les valeurs de mon équation de stimulus, enfin, la formule pour calculer / créer l'équation de stimulus.
Pour ceux qui ne savent pas, voici ce qu'est une équation de stimulus CIE XYZ de colorimétrie :
\begin{array}{lccccccc}
&F_1& F_2& F_3& F_4& F_5& F_6& F_7& F_8\\
&410& 440& 470& 510& 550& 583& 620& 670\\
X& 0,39814& 1,29540 &0,36956 &0,10902 &0,71942& 1,78180 &1,10110 &-0,03991\\
Y& 0,01396& 0,16748& 0,23538& 1,42750& 1,88670& 1,14200 &0,46497& -0,02702\\
Z& 1,95010& 6,45490& 2,78010& 0,18501& 0,15325& 0,09539& 0,10563 &\hphantom{-}0,08866
\end{array}
Il me manque donc l'étape entre les valeurs de mon tableau que j'aurais relevées avec le plus de précision possible et cette équation de stimulus.
NB.  N'étant pas expert en math, ce n'est pas vraiment l'équation mathématique pure que je recherche mais plutôt une traduction fonctionnelle de celle-ci dans un un langage informatique.
J'espère que vous pourrez m'aider.
Mots clés:

Réponses

  • Modifié (9 Feb)
    Bonjour, Thierry,
    Pourrais-tu revoir la formulation de ta question : sur Google, l'expression "équation de tristimulus" ne renvoie que 3 occurrences, toutes liées à la présente discussion, ce qui veut dire que cette expression ne signifie rien, sauf pour toi ... Donc il te faut l'expliciter, mieux qu'avec ton exemple où je ne vois qu'un tableau de nombres ...
    Pour la modération : je suggère de déplacer cette discussion dans le sous-forum "Mathématiques et Physique", car c'est de la colorimétrie.
    Bien cordialement, JLB
  • Modifié (9 Feb)
    Bonjour et merci de votre retour.
    Effectivement, tristimulus s'applique pour un capteur de trois longueurs d'ondes : RGB (d'ou le "TRI").
    C'est donc de pouvoir calculer les valeurs d'une équation de stimulus (sans le TRI) d'un capteur à 8 longueurs d'ondes et, pour trouver les bonnes valeurs de calibration du capteur, en notant les valeurs des 8 longueurs d'ondes du caoteur pour chaque source de lumière.
    Donc mon capteur a 8 longueurs d'ondes : 410 440 470 510 550 583 620 670nm
    je vais faires les mesures de ces 8 valeurs pour 9 sources de lumières (+ la valeur de luminance en LUX + la température de couleur en Kelvin).

    Et ce qui me manque, c'est la formule /code informatique, pour, depuis toutes ces valeurs, déterminer les bonnes valeurs que je vais mettre dans mon équation de stimulus.
    Déterminer les valeurs à mettre dans cette équation permet de calibrer le capteur pour ensuite faire des mesures de lumières avec celui-ci.
    Puis une fois calibré, voici un exemple de code C quo permet de déterminer la température et la luminance de n'importe quel source de lumière :
    Stimulus Function
    float[] Fx={0.07763, 0.34806, 0.09564, 0.02910, 0.51205, 1.02630, 0.64240, 0.04677};
    float[] Fy={0.00218, 0.02980, 0.13902, 0.60820, 1.00000, 0.75700, 0.26500, 0.01700};
    float[] Fz={0.37130, 1.78260, 0.81295, 0.11170, 0.00575, 0.00110, 0.00005, 0.00000};
    /*Color Temperaure*/
      float X,Y,Z,x,y,n,temp;
      X=(data[0]*Fx[0] + data[1]*Fx[1] + data[2]*Fx[2] + data[3]*Fx[3] + data[4]*Fx[4] + data[5]*Fx[5] + data[6]*Fx[6] + data[7]*Fx[7]);//20/1000;//20 is the interval of integration. 1000 is used to converted the value into a real number between 0~1 
      Y=(data[0]*Fy[0] + data[1]*Fy[1] + data[2]*Fy[2] + data[3]*Fy[3] + data[4]*Fy[4] + data[5]*Fy[5] + data[6]*Fy[6] + data[7]*Fy[7]);//20/1000;//But it is meaningless to multiply this number here since it will be reduced in the next step
      Z=(data[0]*Fz[0] + data[1]*Fz[1] + data[2]*Fz[2] + data[3]*Fz[3] + data[4]*Fz[4] + data[5]*Fz[5] + data[6]*Fz[6] + data[7]*Fz[7]);//20/1000;
      x=X/(X+Y+Z);
      y=Y/(X+Y+Z);
      n=(x-0.3320)/(0.1858-y);
      temp=437*n*n*n+3601*n*n+6831*n+5517;
      print(temp);
      println("K\n");
    int LUX = (int)Y;
    print(LUX );
      println("Lx\n");
  • Modifié (11 Feb)
    [Restons dans ta précédente discussion pour donner le contexte. AD]

    Je souhaite obtenir la méthode (en langage C, C#, Java, ...) pour obtenir l'équation d'interpolation à partir de données d'entrée.
    Voici ce que je voudrais obtenir :
    float[] X = { 0.27763F, 0.84806F, 0.39564F, 0.03110F, 0.52205F, 1.21630F, 1.04240F, 0.14677F };
    float[] Y = { 0.40218F, 0.32980F, 0.33902F, 1.01820F, 1.31000F, 0.85700F, 0.26500F, 0.01700F };
    float[] Z = { 1.67130F, 2.78260F, 2.21295F, 0.12170F, 0.10575F, 0.05110F, 0.00005F, 0.00000F };
    C'est donc une matrice de 3 * 8 en sortie
    3 étant la valeur de sortie XYZ dans l'espace colorimétrique CIE 1931
    8 étant le nombre de canaux de mon capteur de lumière
    Pour info, toutes les valeurs que je donne sont fausses, c'est juste pour vous donner un exemple.
    Pour les données d'entrées, j'ai deux matrices :
    la première est une matrice de 6 * 8 :
    6 étant le nombre de sources de lumière que je mesure
    8 étant les valeurs de chaque canal de mon capteur de lumière de cette source lumière
    // Données d'entrée
    double[,] channels = {
    { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8/* Valeurs des canaux pour la source de lumière 1 */ },
    { 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85/* Valeurs des canaux pour la source de lumière 2 */ },
    { 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85/* Valeurs des canaux pour la source de lumière 3 */ },
    { 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85/* Valeurs des canaux pour la source de lumière 4 */ },
    { 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85/* Valeurs des canaux pour la source de lumière 5 */ },
    { 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85/* Valeurs des canaux pour la source de lumière 6 */ }
    la deuxième matrice de 3 * 6 est le résultat que je devrais obtenir en XYZ pour chaque source lumière (donc chaque colonne de ma première matrice d'entrée :
    3 étant la valeur d'entrée XYZ dans l'espace colorimétrique CIE 1931 de la source mesurée
    6 étant le nombre de source lumière que je mesure
    double[] Xinput = { 110, 115, 120, 115, 110, 105/* Valeurs X pour chaque source de lumière */ };
    double[] Yinput = { 90, 95, 90, 95, 80, 75/* Valeurs Y pour chaque source de lumière */ };
    double[] Zinput = { 90, 95, 105, 110, 105, 105/* Valeurs Z pour chaque source de lumière */ };
    donc, pour résumer, j'ai deux matrices et je souhaite avoir la matrice d’interpolation finale en code informatique pour calibrer mon capteur.
    Donc, pour exemple, lorsque je mesure une source de lumière (la première sur les 6 par exemple),
    je note les valeurs des 8 canaux que je mets dans : channels[0][0], channels[0][1], channels[0][2], channels[0][3], ...
    et je mets aussi les valeurs XYZ de cette source de lumière dans Xinput[0], Yinput[0] et Zinput[0] (pour la première source de lumière).
    Je n'ai pas assez de connaissance en mathématique pour réussir à obtenir le code informatique pour, depuis mes valeurs mesurées, obtenir l'équation finale avec les bonnes valeurs pour calibrer mon capteur.
    En faisant des recherches sur chatgpt (qui n'a pas réussi à me donner un code fonctionnel), 
    il a l'air de vouloir utiliser des polynômes et des systèmes linéaires.
    Exemple qui ne fonctionne pas (erreur sur cette ligne var QR = A.QR(); => Matrix dimensions must agree: 6x8) :
    using MathNet.Numerics;
    using MathNet.Numerics.LinearAlgebra;
    using MathNet.Numerics.LinearRegression;
    // Créer une matrice pour les valeurs des canaux (8x6)
    var matrixChannels = Matrix<double>.Build.DenseOfArray(channels);
    // Créer une matrice pour les valeurs XYZ (3x6)
    var matrixXYZ = Matrix<double>.Build.DenseOfColumnArrays(Xinput, Yinput, Zinput);
    // Résoudre le système linéaire pour obtenir les coefficients du polynôme
    var coefficients = SolveLinearSystem(matrixChannels, matrixXYZ);
    // Afficher l'équation d'interpolation pour chaque composante XYZ
    Console.WriteLine("\nÉquation d'interpolation : ");
    for (int i = 0; i < 3; i++)
    {
        Console.WriteLine(GetEquation(coefficients.Column(i), i));
    }
    // Fonction pour obtenir les coefficients du polynôme
    static Matrix<double> SolveLinearSystem(Matrix<double> A, Matrix<double> B)
    {
        var QR = A.QR();
        var Q = QR.Q;
        var R = QR.R;
        // Transposer B avant la multiplication
        var QtB = Q.TransposeThisAndMultiply(B);
        return R.Solve(QtB);
    }
    // Fonction pour obtenir l'équation sous forme de texte
    static string GetEquation(Vector<double> coefficients, int index)
    {
        var equation = "XYZ"[index] + " = ";
        for (int i = 0; i < coefficients.Count; i++)
        {
            equation += $"{coefficients[i]:0.0000} * Channel{i + 1}";
            if (i < coefficients.Count - 1)
                equation += " + ";
        }
        return equation;
    }
    J'espère que je trouverais une bonne âme pour m'aider.
  • Modifié (11 Feb)
    Tu ne donnes aucune information qui permettrait de savoir comment varie la sortie que tu espères en fonction de l'entrée !
    Ta question a pour l'instant à peu près autant de sens que la question : "Pouvez-vous trouver une interpolation (le mot est là juste pour faire joli mais il ne signifie rien dans ce contexte) qui calcule l'âge du capitaine en fonction du nombre de jours sans se couper les ongles de chacun de ses matelots ?"
    Si ça se trouve, il y a même bêtement une relation physique qui donne directement l'équation que tu sembles chercher... mais nous sommes sur un forum de maths, pas sur un forum de devinettes !
  • Modifié (11 Feb)
    Bonjour,
    Je vais essayer de répondre à votre question.
    une fois cette équation d'interpolation établit, cela permet de connaitre la température de couleur d'une source de lumière par rapport aux 8 canaux.
    Voici donc la suite pour avoir cette température de couleur de couleur 

    F0 à F7 étant les valeurs lu par le capteur à un instant T : F0=0.1, F1=0.2, F2=0.3, F3=0.4, F4=0.5, F5=0.6, F6=0.7, F7=0.8
    float[] Fx = { 0.39814F, 1.29540F, 0.36956F, 0.10902F, 0.71942F, 1.781800F, 1.10110F, -0.039905F, -0.27597F, -0.0234700F };
    float[] Fy = { 0.01396F, 0.16748F, 0.23538F, 1.42750F, 1.88670F, 1.142000F, 0.46497F, -0.027018F, -0.24468F, -0.0199260F };
    float[] Fz = { 1.95010F, 6.45490F, 2.78010F, 0.18501F, 0.15325F, 0.095394F, 0.10563F, 0.088661F, -0.61140F, -0.0093845F };
    float X, Y, Z, x, y, n, temp;
    X = (F0 * Fx[0] + F1 * Fx[1] + F2 * Fx[2] + F3 * Fx[3] + F4 * Fx[4] + F5 * Fx[5] + F6 * Fx[6] + F7 * Fx[7]);
    Y = (F0 * Fy[0] + F1 * Fy[1] + F2 * Fy[2] + F3 * Fy[3] + F4 * Fy[4] + F5 * Fy[5] + F6 * Fy[6] + F7 * Fy[7]);//20/1000;
    Z = (F0 * Fz[0] + F1 * Fz[1] + F2 * Fz[2] + F3 * Fz[3] + F4 * Fz[4] + F5 * Fz[5] + F6 * Fz[6] + F7 * Fz[7]);//20/1000;
    XYZ.X = X;
    XYZ.Y = Y;
    XYZ.Z = Z;
    MyXYZ[0] = X;
    MyXYZ[1] = Y;
    MyXYZ[2] = Z;
    x = X / (X + Y + Z);
    y = Y / (X + Y + Z);
    n = (x - 0.3320F) / (0.1858F - y);
    temp = 437 * n * n * n + 3601 * n * n + 6831 * n + 5517;
    Donc l'équation Fx +Fy + Fz sert pour calibrer le capteur suivant les valeurs des 8 canaux qui vont du bleu en passant par le vert au rouge.
    Lors de l'étalonnage, je connais pour une source de lumière défini les valeurs des 8 canaux : double[,] channels
    je connais aussi les valeurs que je devrais avoir pour XYZ : Xinput, Yinput , Zinput pour cette source de lumière défini.
    C'est donc une sorte de régression inverse que je cherche (je ne sais pas si c'est le bon terme), pour connaitre les valeurs de la suite Fx, Fy et Fz.
    J'espère que cela répond à votre question et permettra de m'aider à trouver comment faire.
  • Si on oublie les notions de mathématiques pour faire une interpolation à partir de deux valeurs, la première approche consiste à faire une moyenne,  valeur minimale et maximale,entre les deux  (max + min)/2. Ensuite, si tu sais comment se comporte ton système en général, tout ce qui est physique, tu as une meilleure approche avec une équation du second degré. Tu peux obtenir les coefficients à partir d'une courbe, c'est relativement trivial. Par contre, là où cela pèche, c'est tout ce qui est interpolé par prolongement. En gros, le bord des courbes, c'est un peu comme tu veux, ou en gros a l’arrache.
  • Modifié (12 Feb)
    Afin d'essayer de donner de l'eau au moulin (si c'est possible bien sûr.
    Je vais donner un exemple concret avec des valeurs que j'ai relevé.

    Donc j'ai mesuré 7 sources de lumières pour avoir les valeurs des 8 canaux (violet, bleu, bleu clair, vert, vert, jaune, orange, rouge).
    Les valeurs du capteur pour les 7 sources
    double[,] channels = {
        { 1237.426, 1864.053, 2147.106, 4761.622, 10118.21, 16753.2, 12064.2, 4395.701 }, // Valeurs canal pour la source de lumière 1 Basse conso 2500K
        { 7415.244, 9258.813, 12238.32, 17798.82, 22212.21, 31534.34, 46055.7, 62565.89 }, // Valeurs canal pour la source lumière 2 Incandescent 2700K
        { 1608.002, 5131.267, 5826.795, 12001.82, 21749.46, 30057.62, 26775.51, 9321.196 }, // Valeurs canal pour la source de lumière 3 LED 3000K
        { 1200.182, 5554.915, 4816.557, 9584.696, 13611.68, 15029.74, 14831.42, 7489.731 }, // Valeurs canal pour la source de lumière 4 LED 4000K
        { 3125.687, 6535.358, 6702.024, 10768.12, 10125.66, 16829.55, 8288.611, 3672.24 }, // Valeurs canal pour la source de lumière 5 Basse conso 5500K
        { 3058.648, 6859.38, 7415.244, 11834.22, 10434.79, 15551.16, 8240.194, 3569.82 }, // Valeurs canal pour la source de lumière 6 Basse conso 6500K
        { 667.5954, 1009.075, 1293.524, 1385.47, 1374.53, 1434.12, 1529.79, 1819.36 } // Valeurs canal pour la source de lumière 7 Lumière du jour
    };
    les valeurs que je devrais avoir en sortie XYZ de la fonction que je cherche:
    double[,] XYZ = {
        { 1.162468, 1, 0.251689 }, // Valeurs des canaux pour la source de lumière 1
        { 1.114126, 1, 0.325842 }, // Valeurs des canaux pour la source de lumière 2
        { 1.088158, 1, 0.377850 }, // Valeurs des canaux pour la source de lumière 3
        { 1.002977, 1, 0.684218 }, // Valeurs des canaux pour la source de lumière 4
        { 0.977583, 1, 0.913072 }, // Valeurs des canaux pour la source de lumière 5
        { 0.971597, 1, 1.023582 }, // Valeurs des canaux pour la source de lumière 6
        { 0.967904, 1, 1.209917 } // Valeurs des canaux pour la source de lumière 7
    };
    Ces valeurs XYZ correspondent aux températures de couleur des lumières mesurées dans la suite suivante:
    double[] temperatureValues = { 2450, 2740, 2940, 4170, 5260, 5880, 7140 };


    Maintenant pour expliquer comment, lors d'une utilisation normale (mesure d'une source à un instant T une fois le capteur bien étalonné), on détermine la température de couleur d'une source de lumière :

    Voici la mauvaise équation car les valeurs de cette matrice ne sont pas bonnes mais cela permet de comprendre à quoi elle sert :
    float[] Fx = { 0.27763F, 0.84806F, 0.39564F, 0.03110F, 0.52205F, 1.21630F, 1.04240F, 0.14677F };
    float[] Fy = { 0.40218F, 0.32980F, 0.33902F, 1.01820F, 1.31000F, 0.85700F, 0.26500F, 0.01700F };
    float[] Fz = { 1.67130F, 2.78260F, 2.21295F, 0.12170F, 0.10575F, 0.05110F, 0.00005F, 0.00000F };

    //Récupère à un instant T les valeurs que le capteur renvoi
    float F0 = canal1; F1 = canal2; F2 = canal3; F3 = canal4; F4 = canal5; F5 = canal6; F6 = canal7; F7 = canal8;
    //Calcul de la température de couleur de la source de lumière en Kelvin : K
    float X = (F0 * Fx[0] + F1 * Fx[1] + F2 * Fx[2] + F3 * Fx[3] + F4 * Fx[4] + F5 * Fx[5] + F6 * Fx[6] + F7 * Fx[7]);
    float Y = (F0 * Fy[0] + F1 * Fy[1] + F2 * Fy[2] + F3 * Fy[3] + F4 * Fy[4] + F5 * Fy[5] + F6 * Fy[6] + F7 * Fy[7]);
    float Z = (F0 * Fz[0] + F1 * Fz[1] + F2 * Fz[2] + F3 * Fz[3] + F4 * Fz[4] + F5 * Fz[5] + F6 * Fz[6] + F7 * Fz[7]);
    float x = X / (X + Y + Z);
    float y = Y / (X + Y + Z);
    n = (x - 0.3320F) / (0.1858F - y);
    float temperaure = 437 * n * n * n + 3601 * n * n + 6831 * n + 5517; //Température en Kelvin

    Voilà donc à quoi sert cette matrice, à calibrer / transposer les lectures du capteur pour quelles correspondent au mieux à une température de couleur d'une source lumineuse.
    Cette méthode n'est pas parfaite puisque c'est une matrice d'interpolation, appelé aussi matrice stimulus.
    C'est donc une façon de s'approcher le plus près possible de la bonne valeur de température, ce qui,
    pour mon besoin, est suffisant car je ne suis pas à 10-30 Kelvin près.
    Je souhaites mesurer des sources comprises entre 2500K et 10000 - 12000K (ce que peux faire un appareil photo en balance des blancs)

    Mon problème est donc de déterminer les bonnes valeurs de cette matrice ("reverse" mathématique).
    Je connais donc les données d'entrées de la matrice à un instant T : double[,] channels = { .....
    Je connais les données de sortie de cette matrice : double[,] XYZ = { .......
    Chaque triplet XYZ, correspond aux valeurs de la liste double[] temperatureValues = {  .......

    Mais je ne suis pas assez compétent en mathématique pour faire du "reverse" sur des matrices de corrélation, appelé aussi matrice stimulus (sans doute car elles sont utilisés dans le domaine de la lumière).

    J'espère avoir donné suffisamment de détails pour bien expliquer mon souhait et mon besoin.
    J'espère qu'une bonne âme pourra m'aider à résoudre l'inverse d'une matrice et me permettre de trouver les bonnes valeurs.
    Mais peut être que mathématiquement ce n'est pas possible, je n'en sais rien, je n'ai pas les connaissances mathématiques pour.
    Par contre, pour chaque capteur, il existe des matrices, donc on doit bien pouvoir les générer / calculer via des données de calibration.
  • Modifié (12 Feb)
    Salut,
    J'ai regardé ton dernier post en diagonale et il y a au moins un truc que je ne comprends pas.
    Si j'ai bien compris, tu cherches les coeff. de ton vecteur Fx de façon à ce que le calcul de F0 * Fx[0] + . . . + F7 * Fx[7] te donne la valeur X du tableau XYZ pour les "valeurs test".  Sauf que des inconnues dans Fx, il y en a 8 alors que des valeurs tests, tu n'en a que 7.  Donc non seulement il n'y a rien à "interpoler", mais tu n'as surtout pas assez de données pour calibrer quoi que ce soit (ou alors il faut choisir un des coeff. au pif).
  • Modifié (12 Feb)
    j'ai besoin de connaitre les valeurs de Fx, de Fy et Fz.
    J'ai mesuré 7 sources qui couvrent à peu près l'ensemble de la plage de température et des sources différentes LED, jour, Basse conso.
    par contre, pour chaque mesure (les 7) , il a y systématiquement 8 valeurs (les canaux du capteur) et en sortie il y a les 7 résultats des 7 sources (XYZ)
    J'ai donc bien 8 valeurs d'entrée (les 8 canaux) et j'ai bien 3 valeurs de sortie (les XYZ)
  • Modifié (12 Feb)
    Alors j'aimerais bien que tu m'expliques comment, partant de 7 égalités (tes 7 résultats) tu penses que nous, matheux, on va procéder pour au final en obtenir 8 (qui donnerons les valeurs de Fx) ?
    Tu as peut être une grande confiance dans les mathématiques, mais pour les miracles, style multiplication des petits pains, j'ai un peu peur que tu te sois trompé de crèmerie.
    À mon sens, le seul truc simple à faire si tu ne veux pas augmenter ta batterie de test, c'est de dire qu'il y a un des capteurs que tu n'utilises pas.
  • Modifié (12 Feb)
    Si besoin, et si mathématiquement il faut 8 valeurs de mesure, je veux bien en faire une autre ...
    Mais dans ce cas, ce que je voudrais savoir c'est comment faire pour avoir les valeurs de Fx, Fy et Fz.
    Le fabriquant de ce capteur (AS7341) propose un kit à 650 Euros avec un logiciel pour calibrer ce capteur et avoir la matrice stimulus.
    https://ams.com/documents/20143/36005/AS7341_AN000633_2-00.pdf
    Dans ce document, en page 21, le fabricant donne un exemple de matrice calculée.
    Cette matrice a été calculé par le logiciel, on voit en page 18, un print du logiciel avec les valeurs des canaux du capteur durant la calibration.
    Donc, mathématiquement, on peut bien déterminer la matrice d'interpolation d'un capteur par rapport à des sources lumineuses.
    Il ne parle pas d'ailleurs, d'un nombre de sources neccessaires.
    Mais si il faut 8 sources, aucun soucis, par contre j'aimerais bien la formule sous forme de code ou pseudo code car je ne suis pas familier avec les notations mathématiques pour obtenir le résultat que je souhaite

    Si il faut 8 sources et bien voila 8 sources 

    liste des données d'entrée
    double[,] channels = {
        { 1237.426, 1864.053, 2147.106, 4761.622, 10118.21, 16753.2, 12064.2, 4395.701 }, // Valeurs des canaux pour la source de lumière 1
        { 7415.244, 9258.813, 12238.32, 17798.82, 22212.21, 31534.34, 46055.7, 62565.89 }, // Valeurs des canaux pour la source de lumière 2
        { 1608.002, 5131.267, 5826.795, 12001.82, 21749.46, 30057.62, 26775.51, 9321.196 }, // Valeurs des canaux pour la source de lumière 3
        { 1200.182, 5554.915, 4816.557, 9584.696, 13611.68, 15029.74, 14831.42, 7489.731 }, // Valeurs des canaux pour la source de lumière 4
        { 3125.687, 6535.358, 6702.024, 10768.12, 10125.66, 16829.55, 8288.611, 3672.24 }, // Valeurs des canaux pour la source de lumière 5
        { 3058.648, 6859.38, 7415.244, 11834.22, 10434.79, 15551.16, 8240.194, 3569.82 }, // Valeurs des canaux pour la source de lumière 6
        { 667.5954, 1009.075, 1293.524, 1385.47, 1374.53, 1434.12, 1529.79, 1819.36 } // Valeurs des canaux pour la source de lumière 7
    { 2836.931, 21677.06, 17821.75, 22040.77, 25241.41, 22331.74, 21458.84, 10765.79 } // Valeurs des canaux pour la source de lumière 8
    };

    liste des données de sortie
    double[,] XYZ = {
        { 1.162468, 1, 0.251689 }, // Valeurs des canaux pour la source de lumière 1
        { 1.114126, 1, 0.325842 }, // Valeurs des canaux pour la source de lumière 2
        { 1.088158, 1, 0.377850 }, // Valeurs des canaux pour la source de lumière 3
        { 1.002977, 1, 0.684218 }, // Valeurs des canaux pour la source de lumière 4
        { 0.977583, 1, 0.913072 }, // Valeurs des canaux pour la source de lumière 5
        { 0.971597, 1, 1.023582 }, // Valeurs des canaux pour la source de lumière 6
        { 0.967904, 1, 1.209917 } // Valeurs des canaux pour la source de lumière 7
    { 0.970943, 1, 1.420534 } // Valeurs des canaux pour la source de lumière 8
    };
  • Modifié (12 Feb)
    Si tu as exactement 8 valeurs, alors ce dont tu as besoin, c'est d'une simple inversion de matrice vu que ton système est linéaire.
    Mais si tu veux mon avis, "calibrer" un truc avec pas plus de valeur de test qu'il n'y a de données, c'est bof bof : la moindre parcelle d'erreur lors de la batterie de test va f... un bordel monstre et il va être impossible de la détecter.
    Donc ça me semblerait judicieux d'avoir (bien) plus de valeur de test que d'inconnues dans le système puis d'utiliser une méthode de régression linéaire pour déterminer les coeff.
  • Modifié (12 Feb)
    Ok,
    si il faut je pourrais ajouter d'autres sources (tube néon, lumière du jour au coucher du soleil, nuageux, d'autres lampes ayant des températures différentes, .....
    Ce n'est pas un problème.
    Mais, mais, mais.
    Comment fait-on pour faire une régression linéaire dans mon cas et en m'expliquant plutôt sous forme informatique que représentation mathématique et explication théorique ?
    Comment fait-on une inversion de matrice comme la mienne ?
  • Modifié (12 Feb)
    Si tu cherches un truc spécifiquement pour l'utiliser en informatique, ça me semblerait plus judicieux de chercher sur un site qui parle (sérieusement) d'informatique : tu y trouveras forcément des rubriques dédiées à : 
    1) La résolution d'un système linéaire (c'est-à-dire l'inversion d'une matrice) et dans ton cas, ne regarde pas les méthodes compliquées : ta matrice à inverser va être du 8x8 (même si tu as 50 tests) et, à mon avis, même un simple pivot de Gauss suffirait.
    2) La méthode des moindres carrés pour faire une régression linéaire (à part l'inversion finale du système via le 1), c'est on ne peut plus simple : juste des covariances à calculer).
  • Je comprends que cela soit simple pour un mathématicien mais pour moi : "un simple pivot de Gauss", "méthode des moindres carrés pour faire une régression linéaire", .... 
    tout ça c'est du chinois.
    Si me me suis inscrit sur un forum de mathématique, c'est justement parce que mon problème est un problème de mathématique et pas d'informatique.
    Je sais aligner des lignes de code dans beaucoup de langages informatiques, mais je n'ai pas de connaissance en mathématique.
    Voilà donc pourquoi je pose ma question ici, mais aussi pourquoi j'ai eu beaucoup de mal à expliquer mon problème à des mathématiciens.
    C'est donc bien l'aide d'un mathématicien dont j'ai besoin.
  • Modifié (13 Feb)
    Laisse tomber, tu n'auras pas de réponse. Je n'ai pas tout compris, mais dans...
        { 1.162468, 1, 0.251689 }, // Valeurs des canaux pour la source de lumière 1
        { 1.114126, 1, 0.325842 }, // Valeurs des canaux pour la source de lumière 2
        { 1.088158, 1, 0.377850 }, // Valeurs des canaux pour la source de lumière 3
        { 1.002977, 1, 0.684218 }, // Valeurs des canaux pour la source de lumière 4
        { 0.977583, 1, 0.913072 }, // Valeurs des canaux pour la source de lumière 5
        { 0.971597, 1, 1.023582 }, // Valeurs des canaux pour la source de lumière 6
        { 0.967904, 1, 1.209917 } // Valeurs des canaux pour la source de lumière 7
    { 0.970943, 1, 1.420534 } // Valeurs des canaux pour la source de lumière 8
    };

    Tu vires le 1 du milieu, tu prends Gnuplot, tu traces une courbe, et tu recherches une équation du premier ou deuxième degré qui passe par ces points.À l'arrivée, ton équation te donne ton interpolation en première approximation, bien sûr, et sur ce domaine de définition. Je rajoute que les méthodes que tu as évoquées servent à définir les paramètres de ton équation. Voir ChatGPT pour savoir si cela vaut le coup de s'y investir.

  • Modifié (13 Feb)
    Par curiosité, j'ai demandé à la nouvelle IA de Google. voir directement l'exemple

    Méthode de calcul des coefficients par les moindres carrés

    La méthode des moindres carrés est une technique statistique utilisée pour trouver la droite de régression qui minimise la somme des distances verticales entre les points de données et la droite. Cette droite est appelée la droite d'ajustement.

    Voici les étapes pour calculer les coefficients de la droite d'ajustement par la méthode des moindres carrés:

    1. Calculer la moyenne des valeurs de x et de y:

    x̄ = Σx_i / n
    ȳ = Σy_i / n
    

    où :

    • est la moyenne des valeurs de x
    • est la moyenne des valeurs de y
    • Σ est le symbole de la somme
    • x_i est la ième valeur de x
    • y_i est la ième valeur de y
    • n est le nombre de points de données

    2. Calculer la covariance entre x et y:

    σxy = Σ(x_i - x̄)(y_i - ȳ) / (n - 1)
    

    où :

    • σxy est la covariance entre x et y

    3. Calculer la variance de x:

    σ^2_x = Σ(x_i - x̄)^2 / (n - 1)
    

    où :

    • σ^2_x est la variance de x

    4. Calculer le coefficient de pente (a):

    a = σxy / σ^2_x
    

    5. Calculer le coefficient d'ordonnée à l'origine (b):

    b = ȳ - a * x̄
    

    6. Écrire l'équation de la droite d'ajustement:

    y = a * x + b
    

    Exemple:

    Supposons que nous avons les points de données suivants :

    (1, 2), (2, 4), (3, 6), (4, 8)
    

    1. Calculer la moyenne des valeurs de x et de y:

    x̄ = (1 + 2 + 3 + 4) / 4 = 2.5
    ȳ = (2 + 4 + 6 + 8) / 4 = 5
    

    2. Calculer la covariance entre x et y:

    σxy = ((1 - 2.5)(2 - 5) + (2 - 2.5)(4 - 5) + (3 - 2.5)(6 - 5) + (4 - 2.5)(8 - 5)) / (4 - 1) = 2.5
    

    3. Calculer la variance de x:

    σ^2_x = ((1 - 2.5)^2 + (2 - 2.5)^2 + (3 - 2.5)^2 + (4 - 2.5)^2) / (4 - 1) = 2.5
    

    4. Calculer le coefficient de pente (a):

    a = σxy / σ^2_x = 2.5 / 2.5 = 1
    

    5. Calculer le coefficient d'ordonnée à l'origine (b):

    b = ȳ - a * x̄ = 5 - 1 * 2.5 = 2.5
    

    6. Écrire l'équation de la droite d'ajustement:

    y = x + 2.5
    

    Interprétation des coefficients:

    • Le coefficient de pente (a) indique la variation de y pour une variation d'une unité de x. Dans cet exemple, pour chaque augmentation de 1 unité de x, y augmente en moyenne de 1 unité.
    • Le coefficient d'ordonnée à l'origine (b) indique la valeur de y lorsque x est égal à 0. Dans cet exemple, lorsque x est égal à 0, y est égal à 2.5.

    Avantages de la méthode des moindres carrés:

    • Simple à utiliser
    • Permet de trouver une droite d'ajustement qui minimise la somme des distances entre les points de données et la droite
    • Offre une estimation précise de la relation entre x et y

    Limites de la méthode des moindres carrés:

    • Suppose que la relation entre x et y est linéaire
    • Ne prend pas en compte les valeurs aberrantes
    • Ne s'applique pas aux données non linéaires

    cool

  • Modifié (13 Feb)
    Merci pour votre réponse.
    je vais essayer de regarder cela à tête reposée.
    Mais.
    J'ai l'impression que ce que vous donnez c'est pour résoudre une équation d'une fonction représentée par une courbe, non ?
    Moi c'est pas juste une fonction mais une matrice.
    Ce que vous me donnez me permettra d'"inverser" (est ce le non terme ??) une matrice de 3 x 8, depuis les valeurs de sortie et les valeurs d'entrée, et trouver les bonnes valeurs de cette matrice ?
    D'après Ben314159, Il me faut autant de mesures que la taille des colonnes de ma matrice, donc 8 mesures.
    donc 8 mesures de 8 canaux pour résoudre les valeurs d'une matrice de 3 x 8 avec les données de sortie (8 mesures de 3 valeurs)
  • Ce que je te propose, c'est pour calculer des valeurs intermédiaires ou pour ajouter des valeurs. Rien à voir avec l'inversion de la matrice.
  • et avec ce que vous me proposez, je vais pouvoir avoir les valeurs qui vont dans cette matrice ?
    float[] Fx = { 0.27763F, 0.84806F, 0.39564F, 0.03110F, 0.52205F, 1.21630F, 1.04240F, 0.14677F };
    float[] Fy = { 0.40218F, 0.32980F, 0.33902F, 1.01820F, 1.31000F, 0.85700F, 0.26500F, 0.01700F };
    float[] Fz = { 1.67130F, 2.78260F, 2.21295F, 0.12170F, 0.10575F, 0.05110F, 0.00005F, 0.00000F };
  • Modifié (13 Feb)
    Si c'est un problème de cours, la réponse est dedans. Sinon, oui, tu peux travailler avec les moindres carrés sur un plan ou sur 3 axes, mais avant, fais un petit tour d'horizon avec cela.
    Sinon, ton éventuel  prof risque d'être surpris Cela m'étonnerait que l'on te demande de les utiliser sur un plan. 
    Mes 3 centimes d'euro
  • Modifié (13 Feb)
    Alors je crois qu'il y a toujours une incompréhension de ma question initiale et de mon besoin.
    Et... je n'ai pas de connaissance en mathématique (mes derniers cours date d'il y a plus de 30 ans).
    Ainsi, cela ne veut rien dire pour moi : σxy = Σ(x_i - x̄)(y_i - ȳ) / (n - 1)
    Le Σ, je ne saurais le mettre sous la forme de : ((F0 x Fx) + (F1 x Fy)) / toto
    Me renvoyer vers des sites ou des liens expliquant la théorie ne pourra pas non plus m'aider car je n'ai pas les bases mathématiques.
    Je souhaite juste que l'on me donne la méthode pour résoudre mon problème de façon pratique et non théorique (c'est pour cela que je demandais cela sous forme de code informatique, ou pseudo code informatique
    Donc, ce que je demande c'est une mise en forme pour un novice.
    Exemple de la forme que j'aimerais avoir :
    float x = X / (X + Y + Z);
    float y = Y / (X + Y + Z);
    n = (x - 0.3320F) / (0.1858F - y);
    float temperaure = 437 * n * n * n + 3601 * n * n + 6831 * n + 5517;

    plutôt que (que je ne comprends pas cf: Σ) :
    σ^2_x = Σ(x_i - x̄)^2 / (n - 1)





    Je vais donc tenter de réexpliquer mon besoin, graphiquement, cela sera peut être plus simple et compréhensible :
    Donc j'ai une matrice d'interpolation / stimulus dont je ne connais pas les valeurs.
    A priori, il est possible d'inverser une matrice (régression ?) pour retrouver ses valeurs,
    mais pour cela il faut des données d'entrée (8 x 8) et des données de sortie qui correspondent (3 x 8).
    Entrée : De L1 à L8, ce sont les mesures que j'ai faites pour F0 à F8
    Sortie : Pour chaque mesure de  L1 à L8, je donne les valeurs de X, Y et Z que je devrais obtenir si je connaissais les bonnes valeurs de ma matrice.
    Si besoin, en remontant le fil de cette discussion, vous pouvez récupérer toutes les données sous forme de texte que je vous présente dans cette image.

    Dites moi si c'est plus clair comme cela ?
    Pouvez vous m'aider sous forme très simple ?
    (je sais multiplier / diviser / additionner / soustraire, mais pour le reste, je suis nul).
    Cela fait plus de 30 ans que j'ai eu mon dernier cours de math.
    Si je m'adresse à vous, c'est parce que je suis persuadé que l'un d'entre vous a les connaissances pour m'aider à faire cette régression de matrice et avoir les valeurs  : ?.??????
    Mais ce n'est pas le résultat final qui m'intéresse vraiment (les valeurs),
    mais toute la démarche pour y arriver afin de pouvoir la reproduire dans un code informatique,
    et ainsi pouvoir faire différentes matrice suivant d'autres valeurs.
    Merci
  • Modifié (13 Feb)
    Bonjour Thierry
    Je m'avance peut-être beaucoup, mais d'après mes souvenirs d'algèbre vieux de quelque 50 ans, je ne crois pas que ton problème puisse être résolu de la façon dont tu sembles t'y attendre, car passer d'une matrice 8x8 à une matrice 3x8 ne me semble pas possible avec une simple autre matrice 3x8 ... 
    J'espère que les algébristes du forum pourront t'aider ...
    Bien cordialement, JLB
  • Modifié (13 Feb)
    je n'ai pas lu le document (ça reste en dehors de mon champ de compétence); je n'ai fait qu'une recherche sur internet en tapant "capteur AS7341 calibration" :
    https://ams.com/documents/20143/36005/AS7341_AN000633_2-00.pdf
    ou encore
    https://forums.adafruit.com/viewtopic.php?p=924905
    Est-ce que ça donne des pistes ???
  • Modifié (13 Feb)
    merci pour vos retours,
    paul18 : j'ai déjà lu toutes docs autour du capteur (dont celle sur la calibration qui donne justement une matrice) et différents sites autour de la calibration, les matrices, .....  + mon ami CHATGPT mais pas facile d'exprimer mon besoin je ne suis pas matheux, mais c'est très gentil.
    jelobreuil : Je suis persuadé que c'est faisable car le fabriquant vend un logiciel (650 Euros) pour calculer cette matrice et les données sont les mêmes que les miennes pour faire cette matrice, cf : https://ams.com/documents/20143/36005/AS7341_AN000633_2-00.pdf page 18 et page 21
    C'est de l'algèbre .... je ne savais pas ... j'ai appris une première chose  :) 

    Pour donner encore de l'eau au moulin, c'est faisable car j'ai eu un programme il y a bien longtemps qui permettait de le faire avec un capteur RGB donc 3 entrées



    Ici on a une matrice 3 x 3 et pour faire la calibration dans le logiciel, je mettais 3 valeurs.
    Donc en entrée j'avais une matrice 3 x 3 (3 fois RGB) pour trouver les valeurs de la matrice 3 x 3 (celle ou on voit des valeurs sur l'image) et qui me donnait une matrice 1 x 3 (XYZ)
    pour des termes plus mateux ..... c'est une transformation linéaire simple, pour la régression, cela parle de déterminant.
    Si cela peut vous donner des pistes.
  • Modifié (14 Feb)
    À mon avis, tu n'as pas posé les bonnes questions. Voici les réponses que j'ai obtenues.Pour l'inversion de la matrice, je te laisse rechercher. Bonne lecture

    Exemple numérique

    Supposons que nous avons une sonde RVB qui mesure trois couleurs : rouge, vert et bleu. La matrice des valeurs mesurées par la sonde pour une charte de couleurs de référence est la suivante :

    S = [
        [100, 110, 120],
        [130, 140, 150],
        [160, 170, 180],
    ]
    

    La matrice des valeurs de référence de la charte de couleurs est la suivante :

    R = [
        [255, 0, 0],
        [0, 255, 0],
        [0, 0, 255],
    ]
    

    En utilisant la méthode des moindres carrés, nous pouvons estimer la matrice de correction suivante :

    M = [
        [0.98, 0.01, 0.01],
        [0.01, 0.99, 0.01],
        [0.01, 0.01, 0.98],
    ]
    

    Si nous mesurons une nouvelle couleur avec la sonde et obtenons les valeurs suivantes :

    s = [190, 200, 210]
    

    En appliquant la matrice de correction, nous obtenons la couleur corrigée suivante :

    c = M * s = [254.99, 254.99, 254.99]
    

    La couleur corrigée est donc très proche de la couleur de référence (255, 255, 255).

    Remarques:

    • Cet exemple est simplifié et ne prend pas en compte tous les aspects du calcul de la matrice de correction.
    • En pratique, il est important d'utiliser un logiciel de calibration de sonde pour obtenir des résultats précis.

    J'espère que cet exemple vous sera utile. N'hésitez pas à me poser d'autres questions.


    tu peut détailler le calcule qui permet d'avoir la nouvelle couleur


    Détail du calcul de la nouvelle couleur

    1. Multiplication matricielle:

    Le calcul de la nouvelle couleur corrigée c implique une multiplication matricielle entre la matrice de correction M et la matrice des valeurs mesurées par la sonde s.

    Étape 1: Définir les matrices

    • M : Matrice de correction (3x3)
    • s : Matrice des valeurs mesurées par la sonde (1x3)
    • c : Matrice de la couleur corrigée (1x3)

    Étape 2: Effectuer la multiplication

    c = M * s
    
    c = [m11 m12 m13] * [s1 s2 s3]
    
    = [m11*s1 + m12*s2 + m13*s3, m21*s1 + m22*s2 + m23*s3, m31*s1 + m32*s2 + m33*s3]
    

    Étape 3: Interpréter le résultat

    Chaque élément de la matrice c représente la valeur corrigée pour une des composantes RVB de la nouvelle couleur.

    2. Application à l'exemple numérique:

    Reprenons l'exemple numérique précédent :

    • M = [[0.98, 0.01, 0.01], [0.01, 0.99, 0.01], [0.01, 0.01, 0.98]]
    • s = [190, 200, 210]

    En effectuant la multiplication matricielle, on obtient :

    c = [0.98*190 + 0.01*200 + 0.01*210, 0.01*190 + 0.99*200 + 0.01*210, 0.01*190 + 0.01*200 + 0.98*210]
    
    = [254.99, 254.99, 254.99]
    

    3. Conclusion:

    La nouvelle couleur corrigée est donc c = [254.99, 254.99, 254.99].

    Remarques:

    • Le calcul de la nouvelle couleur peut être effectué manuellement, mais il est généralement réalisé par un logiciel de calibration de sonde.
    • La précision de la nouvelle couleur dépend de la précision de la matrice de correction et des valeurs mesurées par la sonde.

    J'espère que ce détail vous est utile. N'hésitez pas à me poser d'autres questions.



    Calcul de la matrice de correction par inversion directe

    1. Principe:

    Il est possible de calculer la matrice de correction M directement à partir de la matrice des valeurs mesurées par la sonde S et de la matrice des valeurs de référence de la charte de couleurs R sans utiliser la méthode des moindres carrés. Cette approche repose sur l'inversion de la matrice R.

    2. Étapes du calcul:

    Étape 1: Définir les variables

    • S : Matrice des valeurs mesurées par la sonde (n x m)
    • R : Matrice des valeurs de référence de la charte de couleurs (n x m)
    • M : Matrice de correction à estimer (m x m)
    • n : Nombre de couleurs mesurées
    • m : Nombre de composantes RVB

    Étape 2: Vérifier la condition d'invertibilité

    La matrice R doit être inversible pour que le calcul de M par inversion directe soit possible. Cela signifie que la matrice R doit être carrée et non singulière.

    Étape 3: Calculer la matrice de correction

    La matrice de correction M est calculée par l'équation suivante :

    M = S * R^(-1)
    

    Étape 4: Interpréter le résultat

    La matrice de correction M obtenue permet de corriger les erreurs de mesure de la sonde.

    3. Remarques:

    • L'inversion directe est une méthode simple et directe pour calculer la matrice de correction.
    • Cependant, cette méthode est sensible aux erreurs de mesure et peut ne pas fournir des résultats précis si la matrice R est mal conditionnée.
    • La méthode des moindres carrés est généralement plus robuste et fiable que l'inversion directe.

    4. Exemple d'application:

    Supposons que nous avons une sonde RVB qui mesure trois couleurs et que nous disposons des matrices S et R suivantes :

    S = [
        [100, 110, 120],
        [130, 140, 150],
        [160, 170, 180],
    ]
    
    R = [
        [255, 0, 0],
        [0, 255, 0],
        [0, 0, 255],
    ]
    

    En calculant l'inverse de R et en effectuant la multiplication S * R^(-1), on obtient la matrice de correction suivante :

    M = [
        [0.98, 0.01, 0.01],
        [0.01, 0.99, 0.01],
        [0.01, 0.01, 0.98],
    ]
    

    5. Conclusion:

    L'inversion directe est une méthode simple pour calculer la matrice de correction d'une sonde RVB. Cependant, la méthode des moindres carrés est généralement préférée pour sa robustesse et sa précision.

    J'espère que ces informations vous seront utiles. N'hésitez pas à me poser d'autres questions.

  • merci beaucoup 123rourou pour votre retour et votre patience (il en faut un peu avec moi qui ne connait pas grand  chose en mathématique ....)
    Je vais regarder, lire et comprendre cela tranquillement.
    Et pour une inverser une matrice plus dense (3 x 8) ce sera la même méthode ?
  • Modifié (14 Feb)
    Tout fou le camp. je te poste la question que j'ai posée à l'IA   https://gemini.google.com/app
    Il te répond avec du code Python et une lib , même pas besoin de savoir inverser une matrice. Bon, après, je n'ai pas testé donc ...
    "Je suppose que je dispose d'une sonde de couleur 8 canaux. Comment puis-je calculer la matrice de correction par inversion à partir de la sonde et du résultat, je souhaite beaucoup de détail d'un point de vue mathématique parque je ne sais pas inverser une matrice"
    Bonne continuation mais à mon avis il doit exister des softs open-source pour faire cela.
Connectez-vous ou Inscrivez-vous pour répondre.
Success message!