Images.jl icon indicating copy to clipboard operation
Images.jl copied to clipboard

Fix writing of `Ufixed12` images

Open timholy opened this issue 10 years ago • 7 comments

julia> img = Image([Gray(Ufixed12(2)) Gray(Ufixed12(0.8))], spatialorder = ["x","y"])
Gray Images.Image with:
  data: 1x2 Array{Images.ColorTypes.Gray{FixedPointNumbers.UfixedBase{UInt16,12}},2}
  properties:
    spatialorder:  x y

julia> imwrite(img, "/tmp/test.png")

julia> imgr = imread("/tmp/test.png")
Gray Images.Image with:
  data: 1x2 Array{Images.ColorTypes.Gray{FixedPointNumbers.UfixedBase{UInt16,16}},2}
  properties:
    IMcs: Gray
    spatialorder:  x y
    pixelspacing:  1 1

julia> imgr[1]
Gray{Ufixed16}(0.12497)

julia> imgr[2]
Gray{Ufixed16}(0.04999)

timholy avatar Feb 11 '15 23:02 timholy

mhm, I'll leave this open as this still seems to persist.

julia> using Images

julia> A = [Gray(N4f12(2)) Gray(N4f12(0.8))]
1×2 Array{Gray{N4f12},2}:
 Gray{N4f12}(2.0)  Gray{N4f12}(0.8)

julia> save("/tmp/a.png", A)

julia> B = load("/tmp/a.png")
1×2 Array{Gray{N0f16},2}:
 Gray{N0f16}(0.12497)  Gray{N0f16}(0.04999)

Evizero avatar Dec 27 '17 10:12 Evizero

@kimikage If you're available, could you take a look at this issue?

johnnychen94 avatar Jan 03 '20 05:01 johnnychen94

Ufixed12 sounds nostalgic.:smile: I think this is a issue with documentation. As a matter of fact, the "expected behavior" of ImageMagick.jl is unclear. If there are the tests for this issue, I will fix something to pass them.

kimikage avatar Jan 03 '20 07:01 kimikage

We'd need a mechanism to specify the expected return type. NRRD and TIFF formats provide a mechanism to do this, but I don't think PNG or JPG do. NRRD already supports this, see https://github.com/JuliaIO/NRRD.jl/blob/569413d9fadbee958b65d3452c8e3012e0c240c7/test/runtests.jl#L91-L93

timholy avatar Jan 03 '20 08:01 timholy

I think PNG files can contain the "sBIT" chunk. However, I don't know whether ImageMagick supports it. Furthermore, I'm not sure how to handle values ​​greater than one.

kimikage avatar Jan 03 '20 08:01 kimikage

I don't think this is an elegant method, but it might be useful to have a function for mapi which rotate the bits instead of clamping.

Edit: Practically speaking, what is wrong other than the documentation? Should the format be automatically converted to N0f16 when the storage format is 16-bit depth? Is that really a desirable behavior for many users? Is it a problem that ImageMagick saves the bit depth on its own?

kimikage avatar Jan 03 '20 09:01 kimikage

BTW, the Normed-->Normed conversions are different from bit shifting. The conversion from Nxf1 to Nxf2 is the extreme case. The bit shifting means 2 * x.i, but the actual Normed-> Normed conversion means 3 * x.i. Of course, this is a negligible error in practical fs (e.g. (2^16-1) / (2^12-1) ≈ 16.003663).

PNG's "sBIT" is the very thing to prevent the accumulation of errors due to such a conversion. (Unfortunately, it's ruined by the existence of many non-compliant tools.:stuck_out_tongue_closed_eyes:)

IMO, the conversion method should be specified by the users. It may be a good idea to add utility functions for the conversion.

kimikage avatar Jan 03 '20 13:01 kimikage

It does work properly if you use a format like NRRD.

julia> using Images, NRRD

julia> img = [Gray(N4f12(2)) Gray(N4f12(0.8))]
1×2 Array{Gray{N4f12},2} with eltype Gray{N4f12}:
 Gray{N4f12}(2.0)  Gray{N4f12}(0.8)

julia> save("/tmp/12bit.nrrd", img)
4

julia> imgl = load("/tmp/12bit.nrrd")
1×2 reshape(reinterpret(Gray{N4f12}, ::Matrix{UInt16}), 1, 2) with eltype Gray{N4f12}:
 Gray{N4f12}(2.0)  Gray{N4f12}(0.8)

Since 12-bit cameras are probably mostly used for scientific imaging, it's acceptable that one should have to use a suitable file format.

timholy avatar Jul 23 '23 20:07 timholy