buf.get_pixels(roi, TypeInt16, cvb.data);
I think that should be TypeUInt16, it's unsigned if you declared the cv::Mat
with CV_16U. But I don't think that is your primary problem.
I don't know OpenCV well enough to know how the cv::normalize() behaves, but
I'm guessing that you are converting the full range of uint16 in cvb into the
0-255 range of cvb8? (I'm not exactly sure why you are reading into a 16 bit
matrix and then using OpenCV to convert to 8 bits. You could have just used
get_pixels to write directly into the 8 bit matrix.)
For the sake of nomenclature, we generally speak of the normalized ranges, that
is, in a uint8 file, a code value of 0 means 0.0 and a code value of 255 means
1.0. For a uint16 file, a code value of 0 is 0.0 and a code value of 65535
means 1.0. The normalized range for integer encoded files is always presumed to
be 0.0 - 1.0, but that can be encoded as uint8, or uint16, or whatever,
depending on the file type and desired precision.
Looking at the stats of the two images (for simplicity, let's just look at the
first subimage of each, using oiiotool --stats zser8.tif zser16.tif):
zser8.tif : 160 x 128, 1 channel, uint8 tiff (11 subimages)
Stats Min: 0 (of 255)
Stats Max: 255 (of 255)
Stats Avg: 119.29 (of 255)
Stats StdDev: 31.98 (of 255)
zser16.tif : 160 x 128, 1 channel, uint16 tiff (11 subimages)
Stats Min: 626 (of 65535)
Stats Max: 1034 (of 65535)
Stats Avg: 838.42 (of 65535)
Stats StdDev: 49.75 (of 65535)
These two files are NOT the same images simply represented as uint8 and uint16
values, respectively. They are quite different.
zser8.tif fully covers the range of a uint8, 0-255. Its average is 119 (a
mid-gray tone of 0.467 of the maximum range) and you can see from the standard
deviation (32/255 = 12.5% of the full range) that you should see some
meaningful contrast.
However, zser16.tif has a min-to-max range of only 626 to 1034 in code values,
but normalized to the 0-65535 range, that means its minimum is 0.0096
(=626/65535) and its maximum is 0.0158 (=1034/65535). The average is 0.0128 and
standard deviation merely 0.000759. That is a very narrow range of values, and
very dark.
If you convert zser16.tif to an 8-bit unsigned data type, you would end up with
a minimum code value of 2 and a maximum of 4, but indeed as you note, almost
all pixels should have value 3 (= 0.0128*255).
I think that given these input files, both OIIO and OpenCV are doing exactly
what you are telling it to do. These two files do not represent the same image.
> On Oct 13, 2020, at 9:58 PM, Arman Garakani <[email protected]> wrote:
>
> Attached are small tif multi-image files. zser8.tif and zser16.tif. They are
> 160x128 single channel and 16 bit. They are also very small.
> <zser8.tif><zser16.tif>
>
> zser8.tif works fine. zser16.tif does not ( displays all black ). I have
> tried not converting or automatic conversion to u8 or float. Forcing
> conversion to uint8 fills the destination with 0x03.
>
> To check issues with 16bit or float display, I used cv::normalize to convert
> 16bit to 8bit. Result was random stuff — normalized.
>
> In terms of automatic conversion. I could not find documentation describing
> how it is done. If there is please point me to it.
>
> Here is the test code:
>
> auto test_file = [](const ustring& filename){
>
> ImageBuf buf(filename);
> int nsubimages = buf.nsubimages();
> const ImageSpec& bspec = buf.spec();
> int xres = bspec.width;
> int yres = bspec.height;
> int channels = bspec.nchannels;
> int bps = bspec.get_int_attribute("oiio:BitsPerSample", -1);
> std::cout << xres << "," << yres << "," << channels << ":" << bps <<
> std::endl;
>
> // Now read them from cache and display them
> namedWindow("oiio", WINDOW_AUTOSIZE | WINDOW_OPENGL);
> for (int ss = 0; ss < nsubimages; ss++){
> buf.reset(filename, ss, 0);
> std::string datetime =
> buf.spec().get_string_attribute("DateTime");
> std::cout << buf.subimage() << " @ " << datetime << std::endl;
> ROI roi = buf.roi();
> cv::Mat cvb (yres,xres, CV_16U);
> cv::Mat cvb8 (yres,xres, CV_8U);
>
> buf.get_pixels(roi, TypeInt16, cvb.data);
> cv::normalize(cvb, cvb8, 0, 255, NORM_MINMAX, CV_8UC1);
> cv::imshow("oiio", cvb8);
> cv::waitKey();
> }
> };
>
> _______________________________________________
> Oiio-dev mailing list
> [email protected]
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
--
Larry Gritz
[email protected]
_______________________________________________
Oiio-dev mailing list
[email protected]
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org