Guillaume Andreani
Guillaume Andreani

Reputation: 27

Image processing : luminance weighted 2

I would like to weigh values of luminance on a new image. I have an image (5px.jpg) of 5 pixels with these luminance :50,100,150,200,250.

I have a vector of coefficient.

I created a new Mat Z which combine luminance of 5px.jpg and the coefficient.

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

And so on...

But I do not know why my code does not works.

I had already asked a similar question for a vector here and now, I'm try to adapt to an image.

My picture in input :

enter image description here

My output :

enter image description here

#define MPI 3.14159265358979323846264338327950288419716939937510
#define RAD2DEG (180./MPI)
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>
#include <math.h>
#include <string.h>
using namespace cv;
using namespace std;

int main()
{

    Mat image = imread("5px.jpg", 1);
    if (image.empty())
    {
        cout << "Couldn't load " << image << endl;

    }
    else
    {
        cout << "Image upload, go" << endl;
    }


    namedWindow("ImageIn", CV_WINDOW_AUTOSIZE);
    imshow("ImageIn", image);
    Mat imgGrayScale;

    cvtColor(image, imgGrayScale, CV_BGR2GRAY);


    float *deltaP = new float[imgGrayScale.cols];
    float *angle = new float[imgGrayScale.cols];
    float *coeff = new float[imgGrayScale.cols];
    int col;


    for (col = 0; col < imgGrayScale.cols; ++col)
    {
        //cout << "position x = " << col << endl;
        deltaP[col] = imgGrayScale.at<uchar>(0, col);
        //cout << "luminance = " << deltaP[col] << endl;

        angle[col] = acos(deltaP[col] / 255);
        //cout << "angle =" << angle[col] << endl;

        coeff[col] = (1 / cos(angle[col]));
        cout << "coeff = " << coeff[col] << endl;
    }

    int width = imgGrayScale.size().width;
    int height = imgGrayScale.size().height;

    int width2 = width * 5;

    int idx_coef = 0;
    Mat Z = Mat::zeros(height, width2, CV_8UC1);


    //for (int r = 0; r < imgGrayScale.rows; r++)
    //{
    //cout << "Saut de ligne "  << endl << endl << endl;
    for (int t = 0; t < imgGrayScale.cols; t++)
    {
        //cout << "Saut de colonne "  << endl;
        // Attribue le coeff à une variable
        int c = int(coeff[idx_coef]);
        //cout << "x" << t << endl;

        for (int i = 0; i < c; ++i)
        {
            Z.at<uchar>(0, c) = imgGrayScale.at<uchar>(0, t);
        }


        float alpha = fmod(coeff[idx_coef], 1.f);
        float beta = 1.f - alpha;

        Z.at<uchar>(0, c + 1) = (alpha * imgGrayScale.at<uchar>(0, t) + beta *  imgGrayScale.at<uchar>(0, t + 1));

        idx_coef++;
        coeff[idx_coef] = coeff[idx_coef] - beta;



        if (idx_coef >= width - 1)
        {

            int cc = int(coeff[idx_coef]);
            for (int i = 0; i < cc; ++i)
            {
                Z.at<uchar>(0, c) = imgGrayScale.at<uchar>(0, t);
            }
            idx_coef = 0;
            break;

        }

    }
    //}

    namedWindow("m", CV_WINDOW_AUTOSIZE);
    imshow("m", Z);
    imwrite("lumianacetest.jpg", Z);
    int t = waitKey();
    if ((char)t == 27)

        return 0;
}

Upvotes: 0

Views: 75

Answers (1)

Miki
Miki

Reputation: 41775

  • You messed up with the indices while accessing the matrix Z. You shoudn't access Z at column c, but you need access the current column (as a vector::push_back would do). So you can keep the current index column in a variable, here idx_z, and increment it every time you access Z
  • Here your Z is CV_8U, so you lose accuracy since your values are float. You can create Z as CV_32F, and if you need to store values in CV_8U format to save the image, you can convert to CV_8U later, eventually.
  • The last columns of Z won't be set to any value (so I initialized them with value 0). If you need them to have the last value as in the imgGrayScale, just decomment the relevant part of the code.

Here the code:

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

#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;

int main()
{
    Mat1b imgGrayScale = (Mat1b(2, 5) <<    50, 100, 150, 200, 250,
                                            50, 100, 150, 200, 250);

    vector<float> deltaP(imgGrayScale.cols);
    vector<float> angle(imgGrayScale.cols);
    vector<float> coeff(imgGrayScale.cols);
    int col;


    for (col = 0; col < imgGrayScale.cols; ++col)
    {
        //cout << "position x = " << col << endl;
        deltaP[col] = imgGrayScale.at<uchar>(0, col);
        //cout << "luminance = " << deltaP[col] << endl;

        angle[col] = acos(deltaP[col] / 255);
        //cout << "angle =" << angle[col] << endl;

        coeff[col] = (1 / cos(angle[col]));
        cout << "coeff = " << coeff[col] << endl;
    }

    int width = imgGrayScale.size().width;
    int height = imgGrayScale.size().height;

    int width2 = width * 5;


    Mat1f Z(height, width2, 0.f);


    for (int r = 0; r < imgGrayScale.rows; r++)
    {
        int idx_lum = 0;
        int idx_coef = 0;
        int idx_z = 0;

        vector<float> coef = coeff;

        // Set all values in Z to the last value in imgGrayScale
        Z.row(r) = imgGrayScale(r, imgGrayScale.cols-1);

        while (true)
        {
            int c = int(coef[idx_coef]);

            for (int i = 0; i < c; ++i)
            {
                Z(r, idx_z++) = imgGrayScale(r, idx_lum);
            }


            float alpha = fmod(coef[idx_coef], 1.f);
            float beta = 1.f - alpha;

            Z(r, idx_z++) = (alpha * imgGrayScale(r, idx_lum) + beta *  imgGrayScale(r, idx_lum + 1));

            idx_coef++;
            idx_lum++;
            coef[idx_coef] = coef[idx_coef] - beta;

            if (idx_lum >= imgGrayScale.cols - 1 || idx_coef >= coef.size() - 1)
            {

                int cc = int(coef[idx_coef]);
                for (int i = 0; i < cc; ++i)
                {
                    Z(r, idx_z++) = imgGrayScale(r, idx_lum);
                }
                idx_coef = 0;
                break;

            }

        }
    }

    Mat1b ZZ;
    Z.convertTo(ZZ, CV_8U);

    cout << "Float values:" << endl;
    cout << Z << endl << endl;

    cout << "Uchar values:" << endl;
    cout << ZZ << endl << endl;

    namedWindow("m", CV_WINDOW_AUTOSIZE);
    imshow("m", Z);
    imwrite("lumianacetest.png", ZZ);
    waitKey();

    return 0;
}

Upvotes: 1

Related Questions