Search code examples
c++opencvhdrimages

Converting LDR to HDR in OpenCV


I cant seem to find a data structure in opencv which can hold pixel depths greater than 8 bits. My problem is that i would like to take a LDR image and multiply some of the pixels so that these pixel's value would exceed the 255 boundary. This is what i have tried so far. I have tried mapping the pixel values from 0-1, instead of 0-255, then multiplying them with a scalar(to increase their value). But when i need to write the image again, the image is dark unless i multiply with 255. i hope you can help me :)

Mat ApplySunValue(Mat InputImg){


Mat OutPutImg = Mat::zeros(InputImg.rows, InputImg.cols, CV_32FC1);


for(int x = 0; x < OutPutImg.cols; x++){
    for(int y = 0; y < OutPutImg.rows; y++){

        int PixelValue = InputImg.at<uchar>(y,x)/255.f;

        if(PixelValue < 0.9){
            OutPutImg.at<uchar>(y,x) = 0;
        }else{
            OutPutImg.at<uchar>(y,x) = PixelValue * sunMultiplyer;
        }
    }
}

imwrite("/Users/K******/Desktop/EnviormentMap.jpg", OutPutImg * 255);

namedWindow("Hej", CV_WINDOW_AUTOSIZE);
imshow("Hej", OutPutImg * 255);



return OutPutImg;

}


Solution

  • this will be always 0 (integer division):

    int PixelValue = InputImg.at<uchar>(y,x)/255.f;
    

    PixelValue is integer, so your comparison is BS:

    if(PixelValue < 0.9){
    

    as @Micka already spotted, you have to use the correct type for at():

    OutPutImg.at<float>(y,x) = 299.0f; 
    // yes, can be larger than 255 now, so you can discard your broken mapping attempts
    

    you can't save or read floating point images as jpeg or png. check if your opencv libs were built with exr support:

    cerr << cv::getBuildInformation() << endl;
    

    if so, you can save/read it as *.hdr or *.exr