c++opencvimage-processinggamma

Gamma Correction with pow


I would use gamma correction to a image. So, I have to pow every pixel intensity of my source image with a G = 0.6. I have problem cause the destination image is completely wrong. Maybe I have a casting problem when I take pixel from source image. Here my code:

#include <opencv2/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
using namespace std;


int main() {

    Mat src = imread("spine1.jpeg");


    Mat dst = Mat(src.rows, src.cols, CV_8UC1);
    cvtColor(src, src, CV_8UC1);
    dst = Scalar(0);

    for (int x = 0; x < src.rows; x++) {
        for (int y = 0; y < src.cols; y++) {
            int pixelValue = (int)src.at<uchar>(x, y);

            dst.at<uchar>(x, y) = pow(pixelValue, 0.6);

        }
    }



    namedWindow("Input", CV_WINDOW_AUTOSIZE);
    namedWindow("Output", CV_WINDOW_AUTOSIZE);

    imshow("Input", src);
    imshow("Output", dst);

    waitKey(0);
    return 0;
}

Edit: change cvtColor(src, src, CV_8UC1); in cvtColor(src, src, COLOR_BGR2GRAY);


Solution

  • The call to cvtColor is wrong. You should use:

    cvtColor(src, src, COLOR_BGR2GRAY);
    

    Also, you can make your code much simpler, and less error prone:

    #include <opencv2/opencv.hpp>
    
    int main()
    {
        // Load the image as grayscale
        cv::Mat1b src = cv::imread("path_to_img", cv::IMREAD_GRAYSCALE);
    
        // Convert to double for "pow"
        cv::Mat1d dsrc;
        src.convertTo(dsrc, CV_64F);
    
        // Compute the "pow"
        cv::Mat1d ddst;
        cv::pow(dsrc, 0.6, ddst);
    
        // Convert back to uchar
        cv::Mat1b dst;
        ddst.convertTo(dst, CV_8U);
    
        // Show results
        imshow("SRC", src);
        imshow("DST", dst);
        waitKey();
    
        return 0;
    }