将一个范围的数值转换为RGB用于可视化数据

在一些情况下需要可视化一份数据, 可能是一份温度的数据,也可能是一份高度图,最常见的思路就是将这些数据转化为图片,直观地观察数据是否为预期的值。

如果数据的范围不大,最小值和最大值差256以内(如:红外摄像头的输入),可以直接把数据映射到[0, 255],灰度也好,只利用红色通道也好,都是切实可行的方案,这种方案实现起来比较简单,代码量不大。如果对于精度要求不高,只为验证数据正确性的话, 其实更大的范围也能按比例映射到[0,255]

现在考虑一个最小值和最大值相差1536以内的映射方案

为什么是1536?因为是 256 ∗ 6 = 1536 256*6=1536 2566=1536,也就是把映射到[0, 255]的方案扩大了6倍,在原本的基础上增加了一些精度。

考虑到数据是连续的,映射为颜色后也希望颜色是连续的,才不至于产生断层,显得突兀,先提出下列要求:

  1. 设计6段独立的色彩区间,用于对应6段不同的数据区间
  2. 两个相邻的色彩区间是连续的
  3. 用纯黑和纯白表示低于和高于待观测数据区间的值(过滤)
  4. 在有效数据点处避免出现纯白和纯黑的情况

从而设计出如下的色彩区间的端点:

-012345
R000255255255
G025525525500
B255255000255

纯蓝色开始,到紫色为止,进行渐变,如下:

渐变

代码:

_max = 8752
_min = -407
_range = _max - _min + 1
# 将_data映射到不同的色彩区间中
def convert_data(_data):
    if _data < _min:
        return [0, 0, 0]
    r = (_data - _min) / _range
    step = int(_range / 5)
    idx = int(r * 5)
    h = (idx + 1) * step + _min
    m = idx * step + _min
    local_r = (_data - m) / (h - m)
    if _data < _min:
        return [0, 0, 0]
    if _data > _max:
    	return [255, 255, 255]
    if idx == 0:
        return [0, int(local_r * 255), 255]
    if idx == 1:
        return [0, 255, int((1 - local_r) * 255)]
    if idx == 2:
        return [int(local_r * 255), 255, 0]
    if idx == 3:
        return [255, int((1 - local_r) * 255), 0]
    if idx == 4:
        return [255, 0, int(local_r * 255)]

这只是一个简化的设计,最理想的情况是将 255 ∗ 255 ∗ 255 = 16581375 255*255*255=16581375 255255255=16581375种颜色映射到线性空间中,并且依旧能保证色彩是连续的,就能很精确地可视化最值差达到16581375的数据。
附上一张利用上述方法可视化地球海拔数据的效果图:
地球高程

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值