Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

imwrite() to TIFF does not use COMPRESSION_SGILOG for 32FC1 (only 32FC3) #25246

Open
chacha21 opened this issue Mar 21, 2024 · 9 comments
Open

Comments

@chacha21
Copy link
Contributor

chacha21 commented Mar 21, 2024

Describe the feature and motivation

The TIFF library supports COMPRESSION_SGILOG for float data.

Currently, in opencv (4.9)

  • a 32FC3 image written as TIFF is automatically using COMPRESSION_SGILOG + PHOTOMETRIC_LOGLUV (with a minor loss of accuracy)
  • a 32FC1 image written as TIFF does not use compression
  • a 32FC1 image can be articially made 32FC3 by duplicating channels to allow TIFF compression, resulting in minor loss of accuracy but pretty good compression rate

However, 32FC1 could be supported using COMPRESSION_SGILOG + PHOTOMETRIC_LOGL
I have already prepared a PR for that

  • the compression rate of 32FC1 is not better than the artificial 32FC3, but...
  • ...I checked that the compressed 32FC1 has a better accuracy than the 32FC1->32FC3 when re-reading the image and comparing it to the original uncompressed data

I could submit the PR but there is one red flag

  • while correctly generated and read back by OpenCV, the 32FC1 TIFF using COMPRESSION_SGILOG + PHOTOMETRIC_LOGL cannot be open by ImageJ.

So I wonder how legal such a TIFF is. Is it expected to fail ? Is this a lack of support from other softwares ? Did I forget anything for this compression scheme ?

Additional context

No response

@chacha21 chacha21 changed the title imwrite() does not use COMPRESSION_SGILOG for 32FC1 (only 32FC3) imwrite("tiff") does not use COMPRESSION_SGILOG for 32FC1 (only 32FC3) Mar 21, 2024
@chacha21 chacha21 changed the title imwrite("tiff") does not use COMPRESSION_SGILOG for 32FC1 (only 32FC3) imwrite() to TIFF does not use COMPRESSION_SGILOG for 32FC1 (only 32FC3) Mar 21, 2024
@chacha21
Copy link
Contributor Author

Opened an issue on ImageJ's github : imagej/ImageJ#243

@Kumataro
Copy link
Contributor

Kumataro commented Mar 21, 2024

Hello, It might be better to remove forcing SGILOG compatible compression in OpenCV for float images...
One idea is to introduce IMWRITE_TIFF_SGILOG which enable convert to float, to set COMPRESSION_SGILOG and PHOTOMETRIC_LOGL/PHOTOMETRIC_LOGLUV.

So I wonder how legal such a TIFF is. Is it expected to fail ?

tiffcp command in libtiff seems to support both L and Luv SGILOG TIFF. So I believe it is OK.

@chacha21
Copy link
Contributor Author

Hello, It might be better to remove forcing SGILOG compatible compression in OpenCV for float images...

Currently, 32FC3 will always force COMPRESSION_SGILOG. Removing it would be a breaking change I think. But indeed, it would certainly have been wiser to let it enabled through params (IMWRITE_TIFF_COMPRESSION=...).

If I push my PR for 32FC1, I'll have to use that param IMWRITE_TIFF_COMPRESSION so that there is no change in the default behaviour. (the only drawback is that currently, COMPRESSION_SGILOG is a constant from libtiff that it not made available in opencv headers, so a caller of imwrite() would have to hardcode COMPRESSION_SGILOG as 34676 )

@Kumataro
Copy link
Contributor

Thank you for your reply, I agree with you !!

So I think the better way is ...
Only for CV_32F cv::Mat ,(not CV_16F, CV_16BF and CV_64F )
if TIFFTAG_COMPRESSION is specified with any COMPRESSION_* including COMPRESSION_NONE for imwrite(), use it.
If not ( default), force to enable COMPRESSION_SGILOG and PHOTOMETRIC_LOGLand PHOTOMETRIC_LOGLUV.

the only drawback is that currently, COMPRESSION_SGILOG is a constant from libtiff that it not made available in opencv headers, so a caller of imwrite() would have to hardcode COMPRESSION_SGILOG as 34676

Yes, however COMPRESSION_SGILOG, PHOTOMETRIC_LOGL and PHOTOMETRIC_LOGLUV have been defined from initial revision 24 years ago, so I think there are no problem,

Ref. https://gitlab.com/libtiff/libtiff/-/blob/0ef31e1f62aa7a8b1c488a59c4930775ee0046e4/libtiff/tiff.h

@Kumataro
Copy link
Contributor

I'm sorry I have been missed.

OpenCV use COMPRESSION_SGILOG and PHOTOMETRIC_LOGLUV in current implementation.
This function is only for CV_32FC3. So to relax this function to support CV_32FC1 mat is better way.

CV_TIFF_CHECK_CALL(TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3));
CV_TIFF_CHECK_CALL(TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32));
CV_TIFF_CHECK_CALL(TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_SGILOG));
CV_TIFF_CHECK_CALL(TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_LOGLUV));
CV_TIFF_CHECK_CALL(TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG));
CV_TIFF_CHECK_CALL(TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT));

@chacha21
Copy link
Contributor Author

This function is only for CV_32FC3. So to relax this function to support CV_32FC1 mat is better way.

My PR is ready, I am just waiting info from ImageJ

@asmorkalov asmorkalov added this to the 4.10.0 milestone Apr 5, 2024
@asmorkalov
Copy link
Contributor

Related: #25325

@asmorkalov
Copy link
Contributor

@chacha21 @Kumataro is the issue still relevant?

@chacha21
Copy link
Contributor Author

chacha21 commented May 16, 2024

@chacha21 @Kumataro is the issue still relevant?

Still no answer from ImageJ.

@asmorkalov asmorkalov modified the milestones: 4.10.0, 4.11.0 May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants