【问题标题】:Efficient color lookup with linear interpolation in Python在 Python 中使用线性插值进行高效颜色查找
【发布时间】:2015-04-23 06:06:50
【问题描述】:

我有兴趣找到一种从定义的查找表中查找线性插值颜色的快速方法。目的是在运行时根据给定的颜色映射为大量项目分配颜色。颜色图查找表是包含值(升序)、红色、绿色、蓝色、不透明度的元组列表

以下是标准 python 的简单配方。 我也可以使用 pandas,因为我也将它用于其他用途。

# Interpolate colors from a lookup table
import bisect

def find_color(x, vlist, lut):
    """Finds linearly interpolated color from specified lut and x
       Returns RGBA tuple
       Parameters
       x: value to lookup
       vlist: list of values in lut
       lut: List of tuples Value, R, G, B, A
    """
    last = len(lut) - 1 # last index for lut

    if x <= vlist[0] : #clamp low end
            return lut[0][1], lut[0][2], lut[0][3], lut[0][4]
    elif x >= vlist[last]: #clamp high end
            return lut[last][1], lut[last][2], lut[last][3], lut[last][4]
    else:
            # since vlist is sorted we can use bisect
            hi = bisect.bisect_left(vlist, x) #hi index
            lo = hi -  1 # lo index

            # interpolation weight from left
            w = ( x - vlist[lo] ) / (vlist[hi] -vlist[lo] )
            #print x, lo, hi, w

            # use w to interpolate r,g,b,a from lo and hi bins
            # interpolated_value = low_value + w * bin_size
            r = lut[lo][1]  + w * (lut[hi][1] - lut[lo][1])
            g = lut[lo][2]  + w * (lut[hi][2] - lut[lo][2])
            b = lut[lo][3]  + w * (lut[hi][3] - lut[lo][3])
            a = lut[lo][4]  + w * (lut[hi][4] - lut[lo][4])
            return int(r), int(g), int(b), int(a)


# Color lookup table
lut = [ (0.0, 255, 0, 0, 64),
     (0.5, 0, 255, 255,128),
     (1.0, 0, 0, 255, 255) ]

# Value list - extract first column from lut
vlist = [ x[0] for x in lut]

# Test find_color() for arbitrary value
for i in xrange(-5, 12):
    x = i/10.0
    print find_color(x, vlist, lut)

【问题讨论】:

  • 在 pandas 中查找内容有多种有效方法,只需在 pandas 中搜索“lookup”,您就会发现很多。我问了一个关于 n 维查找的问题,该问题得到了很好的回答,可能与您尝试做的类似:stackoverflow.com/questions/25772977/…
  • 我在发帖前确实进行了搜索,但我遇到的结果不是用于插值查找。我需要为 1000 个值重复执行此操作,因此需要效率。另外我没有使用颠簸,但感谢您的想法
  • 如果你使用 pandas,你有点在使用 numpy,因为 pandas 是建立在 numpy 之上的;-) 此外,你确实提到了效率,并且 numpy 将比标准的 python 列表更有效。至于查找+插值,我认为您不会找到该组合,但似乎您的问题也可以分两步解决——1.查找,2.插值。 FWIW。
  • 啊不知道 pandas 是建立在 numpy 上的。谢谢

标签: python pandas colors interpolation lookup


【解决方案1】:

如果您可以提前对查找表进行预处理,则可以将二分查找 + 插值替换为简单查找。只要您愿意接受输出不完全准确的可能性,颜色应该就是这种情况 - 一个错误很难检测到。

取值并乘以某个常数,然后转换为整数,并将该整数用作列表的索引。

resolution = 1024
multiplier = float(resolution) / (lut[-1][0] - lut[0][0])
lookup = [(0, 0, 0, 0)] * resolution
for index in range(resolution):
    r, g, b, a = find_color(lut[0][0] + i / multiplier, vlist, lut)
    lookup[index] = (r, g, b, a)

def find_color2(x):
    return lookup[int((x - lut[0][0]) * multiplier)]

【讨论】:

  • 我的印象是,除非我显着提高分辨率,因为我的数据是双精度浮点数,否则这将无法预测。谢谢你的想法
  • @user3043805 继续提高分辨率然后,内存很便宜。值的精度与它们之间的距离几乎没有关系,如果两个非常接近,则需要高分辨率,但如果它们都散开,则可以使用更少。试着测试一下看看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
  • 1970-01-01
  • 2022-08-16
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
相关资源
最近更新 更多