0
votes


Someone gave me this function:

Mat tan_triggs_preprocessing(InputArray src, float alpha = 1, float gamma = 10.0,
                 float tau = 1000.0, int sigma1 = 2) {
  Mat X = src.getMat();
  Mat I, tmp, tmp2;
  double meanI;

  X.convertTo(X, CV_32FC1);
  pow(X, gamma, I);

  meanI = 0.0;
  pow(abs(I), alpha, tmp);
  meanI = mean(tmp).val[0];
  I = I / pow(meanI, 1.0/alpha);

  meanI = 0.0;
  pow(min(abs(I), tau), alpha, tmp2);
  meanI = mean(tmp2).val[0];
  I = I / pow(meanI, 1.0/alpha);

  for(int r = 0; r < I.rows; r++) {
    for(int c = 0; c < I.cols; c++) {
      I.at<float>(r,c) = tanh(I.at<float>(r,c) / tau);
    }
  }
  I = tau * I;

  return I;
}

The function takes an input as a gray scale image or CV_8UC1 type, and it outputs a matrix of CV_32FC1 type. All I know is the function makes the input image lighter, increases its contrast. When I show the image using imshow function, I can see the output of tan_triggs_preprocessing very clearly, and actually the output lighter, more contrast compares to the source image. But the problem is when I save it as image format (JPG for example) using imwrite function, it's totally black. I can't see anything.
I checked the value of elements in the output, and I saw that their values are between [0.06.., 2.3...]. Here are my questions, hopefully you can help me, thank you so much.

  1. Can I write an CV_32FC1 as image file format?
  2. Why is the file written by imwrite above totally black?
  3. I also looked for min and max value in the output, so I can normalize it in to 256 bins for CV_8UC1, but it doesn't work, even when I use imshow or imwrite.
  4. How can I convert it to CV_8UC1 or write it as image file format? I used convertTo but it doesn't work as well.

Thank a lot.

1
You can save the image as an HDR image, .hdr files are floating point. To do this you'll need to use OpenCV 3.0, which is currently in beta.Maggick
Hi maggick. Thank you so much for your attention. I will think about it.user2812045

1 Answers

2
votes

imwrite/imread can only handle 8/16/24/32bit integral data, not floats (if you don't count Ilm/exr)

you probably want :

Mat gray_in = ...
Mat gray_out;
cv::normalize( tan_triggs_preprocessing(gray_in), gray_out, 0, 255, NORM_MINMAX, CV_8UC1); 

(admittedly hard to spot, but it's even in the small print of bytefish's code ;)

also, please look at alternatives to that, like equalizehist and CLAHE