0

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;
}
Community
  • 1
  • 1

1 Answers1

1
  • 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;
}
Miki
  • 40,887
  • 13
  • 123
  • 202
  • Yes but when I import luminancetest.jpg in Photoshop, the values are : 69,69,69,69,69,118,123,140,198,227,251,252,250,251,251,251,251... or I would like 50,50,50,50,50,95,100,117,182,218,255,255... As my previous post. I'm lost.. – Guillaume Andreani Feb 10 '16 at 20:21
  • Check now! 1) save in png to avoid compression (yes, some values are modified by jpeg compression), 2) You can see on stdout that values are correct. – Miki Feb 10 '16 at 20:27
  • Weird, png file does not work also. I'm agree the values in terminal are good but, on Photoshop, same problem :/ – Guillaume Andreani Feb 10 '16 at 20:34
  • Probably Photoshop doesn't load the image correctly, i.e. applies some color space transformation / gamma correction / whatever. However, you don't need Photoshop in the first place :D. I can see correct values with paint.net – Miki Feb 10 '16 at 20:37
  • Yes maybe color space. It will be good if it show me good values because this program is for correct loss light on image scanned. Anyway, how to remplace your Mat1b by a real image ? – Guillaume Andreani Feb 10 '16 at 20:44
  • `Mat1b imgGrayScale = imread("path_to_image", IMREAD_GRAYSCALE)` – Miki Feb 10 '16 at 20:45
  • However, if your matrix represent generica values, and not pixel intensities, it's usually better to use `FileStorage` – Miki Feb 10 '16 at 20:47
  • Ok ! Thanks for information. I have inported lumiancetest.png in GIMP, it is ok. Photoshop..hum ;) – Guillaume Andreani Feb 10 '16 at 20:51
  • Well, problem solved :D Please remember to upvote / mark as answer then. – Miki Feb 10 '16 at 20:59
  • 1
    Thanks a lot ! With Miki, keep calm and go to Italy ;) – Guillaume Andreani Feb 10 '16 at 21:03