JuliaImages / Images.jl

An image library for Julia
http://juliaimages.org/
Other
531 stars 141 forks source link

Problem in saving Array{Float16, 3} into Tiff #1057

Open pywugate opened 4 months ago

pywugate commented 4 months ago

Hi,

I have original 4D data typeof(data) = Array{UInt16, 3}, size(data) = (512, 512, 5, 100) . I reshape, permute to (512, 512, 100, 5) and take as 3D img = data[:, :, :, 1], size(img) = (512, 512, 100) . It is ok if I directly save this Array{UInt16, 3} as tiff FileIO.save("img.tif", img)

But if I convert it into floating point img = Float16.(img) , typeof(img) = Array{Float16, 3} and try to save FileIO.save("img.tif", img).

Here the problem and error come,

 Warning: Mapping to the storage type failed; perhaps your data had out-of-range values?
│ Try `map(clamp01nan, img)` to clamp values to a valid range.
........
MethodError: no method matching save(::File{DataFormat{:TIFF}, String}, ::Array{Float16, 3})

Closest candidates are:
  save(::Stream{DataFormat{:PNG}}, ::S; permute_horizontal, mapi, kwargs...) where {T, S<:Union{AbstractArray{T, 3}, AbstractMatrix}}
   @ ImageIO ~\.julia\packages\ImageIO\uPn5K\src\ImageIO.jl:40
  save(::File{DataFormat{:PNG}}, ::S; kwargs...) where {T, S<:Union{AbstractArray{T, 3}, AbstractMatrix}}
   @ ImageIO ~\.julia\packages\ImageIO\uPn5K\src\ImageIO.jl:36

===========================================
ArgumentError: N0f8 is an 8-bit type representing 256 values from 0.0 to 1.0; cannot represent 63744.0
===========================================
ArgumentError: Package OpenCV [f878e3a2-a245-4720-8660-60795d644f2a] is required but does not seem to be installed: - Run `Pkg.instantiate()` to install all recorded dependencies.

===========================================
Fatal error:
ERROR: MethodError: no method matching save(::File{DataFormat{:TIFF}, String}, ::Array{Float16, 3})

Closest candidates are:
  save(::Stream{DataFormat{:PNG}}, ::S; permute_horizontal, mapi, kwargs...) where {T, S<:Union{AbstractArray{T, 3}, AbstractMatrix}}
   @ ImageIO ~\.julia\packages\ImageIO\uPn5K\src\ImageIO.jl:40
  save(::File{DataFormat{:PNG}}, ::S; kwargs...) where {T, S<:Union{AbstractArray{T, 3}, AbstractMatrix}}
   @ ImageIO ~\.julia\packages\ImageIO\uPn5K\src\ImageIO.jl:36

Stacktrace:
 [1] #invokelatest#2
   @ .\essentials.jl:892 [inlined]
 [2] invokelatest
   @ .\essentials.jl:889 [inlined]
 [3] action(call::Symbol, libraries::Vector{Union{…}}, file::Formatted, args::Array{Float16, 3}; options::@Kwargs{})
   @ FileIO ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:219
 [4] action
   @ ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:196 [inlined]
 [5] action
   @ ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:185 [inlined]
 [6] save(file::String, args::Array{Float16, 3}; options::@Kwargs{})
   @ FileIO ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:129
 [7] save(file::String, args::Array{Float16, 3})
   @ FileIO ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:125
 [8] top-level scope
   @ ~\Documents\Julia\Lab8b07IMBAS\IMGfromH5.jl:70
Stacktrace:
 [1] handle_error(e::MethodError, q::Base.PkgId, bt::Vector{Union{Ptr{Nothing}, Base.InterpreterIP}})
   @ FileIO ~\.julia\packages\FileIO\xOKyx\src\error_handling.jl:61
 [2] handle_exceptions(exceptions::Vector{Tuple{Any, Union{Base.PkgId, Module}, Vector}}, action::String)
   @ FileIO ~\.julia\packages\FileIO\xOKyx\src\error_handling.jl:56
 [3] action(call::Symbol, libraries::Vector{Union{…}}, file::Formatted, args::Array{Float16, 3}; options::@Kwargs{})
   @ FileIO ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:228
 [4] action
   @ ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:196 [inlined]
 [5] action
   @ ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:185 [inlined]
 [6] save(file::String, args::Array{Float16, 3}; options::@Kwargs{})
   @ FileIO ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:129
 [7] save(file::String, args::Array{Float16, 3})
   @ FileIO ~\.julia\packages\FileIO\xOKyx\src\loadsave.jl:125
 [8] top-level scope
   @ ~\Documents\Julia\Lab8b07IMBAS\IMGfromH5.jl:70
Some type information was truncated. Use `show(err)` to see complete types.

I tried map(clamp01nan, img) , FileIO.save("img.tif", img) again, and got same error.

but there is no problem to save random data img= rand(Float16, 512, 512, 100); .

what can I do?

thanks in advacne.

mkitti commented 4 months ago

Did you do the following?

img = map(clamp01nan, img)
FileIO.save("img.tif", img)

Basically we're expecting all your floating point values to be between 0 and 1.

pywugate commented 4 months ago

I did, the transformed image img3 = map(clamp01nan, img2) can be saved. But all the values were transformed to 1.0

julia> size(img), typeof(img)
((512, 512, 100), Array{UInt16, 3})

julia> unique(img)
96-element Vector{Int64}:
 1791
 1983
    ⋮
 7039
 6975

julia> img2 = Float16.(img); typeof(img2)
Array{Float16, 3}

julia> unique(img2)
96-element Vector{Float16}:
 1.791e3
 1.983e3
 ⋮
 7.04e3
 6.976e3

julia> img3 = map(clamp01, img2); unique(img3)
1-element Vector{Float16}:
 1.0

julia> img3 = map(clamp01nan, img2); unique(img3)
1-element Vector{Float16}:
 1.0

julia> img3 = clamp01nan.(img2); unique(img3)
1-element Vector{Float16}:
 1.0
julia> versioninfo()
Julia Version 1.10.2
Commit bd47eca2c8 (2024-03-01 10:14 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 16 × AMD Ryzen 7 4800HS with Radeon Graphics
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-15.0.7 (ORCJIT, znver2)
Threads: 6 default, 0 interactive, 3 GC (on 16 virtual cores)
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS = 6

julia> Pkg.status()
  [5ae59095] Colors v0.12.10
  [8f5d6c58] EzXML v1.2.0
  [5789e2e9] FileIO v1.16.3
  [e9467ef8] GLMakie v0.9.10
  [f67ccb44] HDF5 v0.17.2
⌃ [6218d12a] ImageMagick v1.2.1
  [86fae568] ImageView v0.12.1
  [916415d5] Images v0.26.1
  [9c8b4983] LightXML v0.9.1
  [dbb5928d] MappedArrays v0.4.2
  [c020b1a1] NaturalSort v1.0.0
  [731e570b] TiffImages v0.10.0
  [1986cc42] Unitful v1.19.0
  [d6f4376e] Markdown
[[deps.ImageCore]]
 ⋮
version = "0.9.4"