将灰度数组转换为浮点数组

Converting a Gray-Scale Array to a FloatingPoint-Array

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

我可以通过将它与 255 相乘(因为 UInt8)将这个 FixedPoint-Array 转换为 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-代码不起作用(见要点)。

为什么不 Float32.()

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

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

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

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)

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

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

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