将颜色数组转换为浮点数数组。

3

我有一个颜色数组,我希望将其转换为数字矩阵:

using Colors

cols = [RGB{Float64}(rand(), rand(), rand()) for i in 1:6]
6-element Array{ColorTypes.RGB{Float64},1}:
RGB{Float64}(0.836012,0.505908,0.249548)
RGB{Float64}(0.383172,0.105153,0.361422)
RGB{Float64}(0.680616,0.974232,0.942787)
RGB{Float64}(0.804829,0.825503,0.990222)
RGB{Float64}(0.0404051,0.569093,0.772053)
RGB{Float64}(0.872298,0.704112,0.473588)

转换为:

6×3 Array{Float64,2}:
0.836012  0.505908  0.249548
0.383172  0.105153  0.361422
0.680616  0.974232  0.942787
0.804829  0.825503  0.990222
0.0404051 0.569093 0.772053
0.872298  0.704112  0.473588

我该如何做到这一点?
2个回答

4

使用 reinterpret 函数。它可以 "构造一个与给定数组具有相同二进制数据的数组,但使用指定的元素类型"。这意味着它按照相同的顺序读取数据 - 请记住,Julia 是列优先的。它也不知道返回的数组应该是什么形状,默认情况下它是一个向量:

julia> reinterpret(Float64, cols)
18-element Array{Float64,1}:
 0.836012
 0.505908
 0.249548
 0.383172
 0.105153

您可以看到,它提取了浮点值并将它们放在一个平坦的向量中,[c₁, c₂] 变成了 [r₁, g₁, b₁, r₂, g₂, b₂]。因此,您首先需要获得一个符合此结构的 3x6 数组:
julia> fs = reinterpret(Float64, cols, (3, length(cols)))
3x6 Array{Float64,2}:
 0.836012  0.383172  0.680616  0.804829  0.0404051  0.872298
 0.505908  0.105153  0.974232  0.825503  0.569093   0.704112
 0.249548  0.361422  0.942787  0.990222  0.772053   0.473588

现在,如果需要,您可以通过转置来到达所需的形状:

julia> fs'
6x3 Array{Float64,2}:
 0.836012   0.505908  0.249548
 0.383172   0.105153  0.361422
 0.680616   0.974232  0.942787
 0.804829   0.825503  0.990222
 0.0404051  0.569093  0.772053
 0.872298   0.704112  0.473588

谢谢!我一直想知道 reinterpret 是做什么的 - 看起来非常有用! - daycaster
是的,它可以在不复制数据的情况下完成其工作,因此这将是最快的可能方式!但要注意,这意味着修改重新解释的数组也会影响您的“RGB”数组。 - mbauman

1

One way is:

[j(cols[i]) for i=1:6,j in [red,green,blue]] 

vcat(map(x->[red(x) green(x) blue(x)],cols)...) 是同样的风格,但对于类型分析来说更好。 基准测试显示它比答案更快。 但可能@Matt B.的选项更快。 - Dan Getz
谢谢 - 我不知道为什么我没有想到那个... :) 正如你所说,reinterpret 更快。 - daycaster
@DanGetz,cat(n, map(f,x)...)是“Julian”或者至少是一种通常实现这种功能的好方法吗?我经常使用它,但从来不确定是否有更好的方法? - Alexander Morley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接