c++opencvluminance

Image processing: luminance weighted


I would like to weigh values of luminance.

Example: I have a vector of luminance values:

vector <int> lum {50,100,150,200,250);

I have a vector of coefficients:

vector <float> coef {5.1 , 2.55 , 1.7 , 1.275, 1.02 }

I create an empty image:

Mat1 m(15):

So, my first value of luminance is 50 (lum[0]=50) and I want it to be applied on the 5.1 (coef[0]=5.1) first pixel of my matrix. To do that, I need to weight the 6th pixel with the first and the second value of luminance. In my case, the luminance of my 6th pixel will be 95 because (0.1*50)+ (0.9*100)=95

At the moment, for the second coefficient (coef[1]=2.55), I have used 0.9 on 2.55 for the previous calcul. It remains 1,65 on this coefficient so the 7th pixel will have 100 of luminance and the 8th will have (0.65*100)+ (0.35*150) = 117,5.

And so on...

Actually I have this:

//Blibliothèque Opencv
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
// cpp include
#include <iostream>
#include <cmath>
#include <math.h>
#include <string.h>
#include <vector>
#include <opencv2/opencv.hpp>

#define MPI 3.14159265358979323846264338327950288419716939937510
#define RAD2DEG (180./MPI)

using namespace cv;
using namespace std;


vector <int> lum{ 50, 100, 150, 200, 250 };
vector <float> coef (5,0);
vector <int> newv(15, 0);
float pixelRef = 255, angle = 0, coeff = 0;


int main()
{


    for (int n = 0; n < lum.size(); ++n)
    {
        //get angle
        angle = ((acos(lum[n] / pixelRef)));
        cout << "angle :" << angle*RAD2DEG << endl;
        // get coefficient
        coef [n] = (1 / (cos(angle)));
        cout << "coeff :" << coef [n] << endl;
        // try to weighted my pixels
        newv[n] = (coef*lum[n]) + ((1 - coeff)*lum[n + 1]);
    }
    return 0;
}

Solution

  • I modified the last element of coef to 3.02f to show that this code handles well also the last element. The result sequence is:

    50, 50, 50, 50, 50, 95, 100, 117.5, 150, 182.5, 218.75, 250, 250,
    

    enter image description here

    The code could be probably re-written better, but I'll leave this to you:

    #include <opencv2/opencv.hpp>
    #include <vector>
    #include <iostream>
    using namespace cv;
    using namespace std;
    
    int main()
    {
        vector <int> lum{ 50, 100, 150, 200, 250 };
        vector <float> coef{ 5.1f, 2.55f, 1.7f, 1.275f, 3.02f };
    
        vector<float> v;
    
        int idx_lum = 0;
        int idx_coef = 0;
    
        while (true)
        {
            int c = int(coef[idx_coef]);
            for (int i = 0; i < c; ++i)
            {
                v.push_back(float(lum[idx_lum]));
            }
    
            float alpha = fmod(coef[idx_coef], 1.f);
            float beta = 1.f - alpha;
    
            v.push_back(alpha * lum[idx_lum] + beta * lum[idx_lum + 1]);
    
            idx_lum++;
            idx_coef++;
            coef[idx_coef] = coef[idx_coef] - beta;
    
            if (idx_lum >= lum.size() - 1 || idx_coef >= coef.size() - 1)
            {
                int cc = int(coef[idx_coef]);
                for (int i = 0; i < cc; ++i)
                {
                    v.push_back(float(lum[idx_lum]));
                }
    
                // Only if the last remainder is needed
                //float alpha = fmod(coef[idx_coef], 1.f);
                //v.push_back(alpha * lum[idx_lum]);
                break;
            }
        }
    
        // Print out the values
        copy(v.begin(), v.end(), ostream_iterator<float>(cout, ", "));
    
        // Get a cv::Mat from the std::vector
        Mat1f m = Mat1f(v).t();
    
        return 0;
    }