pytorch / vision

Datasets, Transforms and Models specific to Computer Vision
https://pytorch.org/vision
BSD 3-Clause "New" or "Revised" License
15.76k stars 6.89k forks source link

Roundtrip test for encoding and decoding images #3912

Open NicolasHug opened 3 years ago

NicolasHug commented 3 years ago

This goal of this issue is to add tests for both jpeg and png implementation on all platforms, to test that:

decode(encode(image)) ~= image.

This test will require an image-comparison util that is robust to minor changes. One possible approach is to compare histograms as done in PIL: https://github.com/python-pillow/Pillow/blob/affa059e959280bf7826ec1a023a64cb8f111b6d/Tests/helper.py#L110-L134

This test is not as robust as the ones we currently have where we individually test encode and decode w.r.t. to a reference implementation (PIL), but it's still good to have as a functional / integration test and it will hopefully help https://github.com/pytorch/vision/issues/3913 move forward.

CC @fmassa @datumbox @pmeier

pmeier commented 3 years ago

What I asked myself a few times for these kinds of issues: does the jpeg / png standard define a test for encoding / decoding?

NicolasHug commented 3 years ago

does the jpeg / png standard define a test for encoding / decoding?

Yes, according to https://en.wikipedia.org/wiki/JPEG#Required_precision the tests requirements seem to be in the DCT domain though, not pixel domain. I don't think we'll want to go as far as testing the DCT domain (I'm not even sure we can anyway, since we just use libjpeg)

NicolasHug commented 3 years ago

Actually looking at an older version of this: https://en.wikipedia.org/w/index.php?title=JPEG&oldid=814219419#Required_precision there seem to be pixel-level checks (for the decoding phase though, not the encoding obviously):

a maximum of one bit of difference for each pixel component low mean square error over each 8×8-pixel block ...

farleylai commented 3 years ago

If the critical options are exposed when the decoder is allowed to make a decision, the decoded output can be made identical but some image processing toolkit such as PIL, unlike Tensorflow, could be opaque and simply depend on libjpeg versions.

In this regard, blaming the installation versions may not always make sense since it is not the very root cause but the responsibility of the toolkit to provide APIs exposing those critical options that may result in different output. Then having PIL as the reference implementation does not sound like a good idea.

NicolasHug commented 3 years ago

@farleylai I'm not sure I understand your comment in the context of this issue.

This issue is about having round-trip test for the torchvision implementation. These tests are worth having, regardless of anything else.

Regarding expected results consistency: as you noted PIL will yield different results depending on the libjpeg backend that is used. Whether this is right or wrong, it's something we have to deal with and there isn't much we can do about this. Typically on Windows they link against libjpeg-turbo, but not necessarily on linux or Mac.

farleylai commented 3 years ago

This is to concern the decoding consistency especially when the results apparently affect reproducibility if care is not taken.

NicolasHug commented 2 years ago

One thing we could use here is the pytest-mpl plugin (also available on fbcode) for image comparisons: https://pypi.org/project/pytest-mpl/