【问题标题】:Converting a Gray-Scale Array to a FloatingPoint-Array将灰度数组转换为浮点数组
【发布时间】:2017-12-09 15:24:59
【问题描述】:

我正在尝试将 julia 中的 .tif 文件作为浮点数组读取。使用 FileIOImageMagick-Package 我可以做到这一点,但我得到的数组是 Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2} 类型的。

我可以通过将此 FixedPoint-Array 乘以 255(因为 UInt8)将其转换为 Float32-Array,但我正在寻找一个函数来为任何类型的 FixedPointNumber(即 reinterpret()convert())执行此操作。

using FileIO
# Load the tif
obj = load("test.tif");
typeof(obj)
# Convert to Float32-Array
objNew = real.(obj) .* 255
typeof(objNew)

输出是

julia> using FileIO

julia> obj = load("test.tif");

julia> typeof(obj)
Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}

julia> objNew = real.(obj) .* 255;

julia> typeof(objNew)
Array{Float32,2}

我在文档中查找了很长一段时间,但没有找到将给定 FixedPoint-Array 转换为 FloatingPont-Array 而不将其与 Integer 类型的最大值相乘的函数。

感谢您的帮助。

编辑: 我创建了a small gist 以查看 Michael 的解决方案是否有效,并且确实有效。谢谢!

注意:我不知道为什么,但是real.(obj) .* 255-code 不起作用(请参阅要点)。

【问题讨论】:

  • 如果有帮助,这会从 obj 计算 255.0: 2.0^FixedPointNumbers.nbitsfrac(typeof(real(first(obj))))-1.‌​0
  • 如果类型(例如UInt8)已知,您可以使用reinterpret(UInt8, obj) |> Array{Float32},这通常是这种情况。值得注意的是,这个类型取决于你的图片文件格式,“FileIO”可能会读取到默认类型错误的图片。

标签: julia tiff geotiff


【解决方案1】:

为什么不只是Float32.()

using ColorTypes
a = Gray.(convert.(Normed{UInt8,8}, rand(5,6)));
typeof(a)
#Array{ColorTypes.Gray{FixedPointNumbers.Normed{UInt8,8}},2}
Float32.(a)

【讨论】:

  • 不错! :) (+ using ColorTypes 工作示例)
  • 这行得通,谢谢。我制作了一个 gist-notebook 来检查您的代码,并发现我的问题 (real.(obj).*255) 中列出的方式不起作用
  • 关于乘以 255 的解释见下文。
【解决方案2】:

简短的答案确实是迈克尔给出的答案,只需使用Float32.(a)(用于灰度)。另一种选择是channelview(a),它通常执行通道分离,因此也会从阵列中剥离颜色信息。在后一种情况下,您将不会得到 Float32 数组,因为您的图像以每像素 8 位存储,而是会得到 N0f8 (= FixedPointNumbers.Normed{UInt8,8})。你可以阅读这些数字here

考虑到其他图像处理框架的工作方式,您乘以 255 的本能是很自然的,但 Julia 已经做出了一些努力,以值得花点时间思考的方式保持“意义”的一致性。例如,在另一种编程语言中,只需更改数组的数值精度:

img = uint8(255*rand(10, 10, 3));   % an 8-bit per color channel image
figure; image(img)
imgd = double(img);   % convert to double-precision, but don't change the values
figure; image(imgd)

产生以下令人惊讶的结果:

第二个“全白”图像代表饱和度。在另一种语言中,“5”表示两个完全不同的东西,具体取决于它是作为UInt8 还是Float64 存储在内存中。我认为可以公平地说,在任何正常情况下,数值库的用户都会称这是一个错误,而且是一个非常严重的错误,但不知何故,我们中的许多人已经在图像处理的背景下接受了这一点。

这些新类型的出现是因为在 Julia 中,我们努力实现新的数值类型 (FixedPointNumbers),它们的作用类似于小数值(例如,介于 0 和 1 之间),但内部存储的位模式与 "对应的“UInt8(乘以 255 得到的那个)。这使我们能够处理 8 位数据,同时允许始终以一致的比例(0.0=黑色,1.0=白色)解释值。

【讨论】:

    猜你喜欢
    • 2011-11-22
    • 1970-01-01
    • 2019-07-05
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多