首页 > 解决方案 > 通过插值匹配 4D 数组中的 3D 矢量?

问题描述

所以……为了学习,我一直在尝试新的东西。我正在尝试从 sRGB 中获取波长。我有所有 sRGB 到 XYZ 的转换以及从 XYZ 到波长的转换表 - 4 维。

我的问题仍然在最后一行 - 这似乎是最复杂的,至少对于我这个非数学家来说:我需要在表格转换中找到最接近的 XYZ 位置,类似于请求的 XYZ。

表看起来像:

WL,X,Y,Z
380,0.0014,0.0000,0.0065
381,0.0015,0.0000,0.0070
382,0.0016,0.0000,0.0077
383,0.0018,0.0001,0.0085
384,0.0020,0.0001,0.0094
385,0.0022,0.0001,0.0105
386,0.0025,0.0001,0.0120
...,...,...
780,0.0000,0.0000,0.0000

我使用这个类存储不同的进程 - 那就是 wip 将被拆分:

#*************
class Sounder:
#*************
  # -----------------
  def __init__(self):
  # -----------------
    self.cursor = -1

    self.__wavelengthTable = []
    with open(CONVERTER_PATH, 'r') as csvfile:
      dictReader = csv.DictReader(csvfile)
      for row in dictReader:
        self.__wavelengthTable.append(row)
      csvfile.close()

    self.table = {
      'X': [],
      'Y': [],
      'Z': [],
      'WL': []
    }
    for row in self.__wavelengthTable:
      self.table['X'].append(row['X'])
      self.table['Y'].append(row['Y'])
      self.table['Z'].append(row['Z'])
      self.table['WL'].append(row['WL'])

我尝试的第一件事是通过 3 XYZ 坐标遍历 4D 表:

  # -------------------------------------
  def cursorIterateMatch(self, XYZArray):
  # -------------------------------------
    x = float(round(XYZArray[0], 4))
    y = float(round(XYZArray[1], 4))
    z = float(round(XYZArray[2], 4))
    # print("[{}:{}:{}]".format(x,y,z))
    found = False
    while found == False:
      if self.cursor >= self.get_tableLength():
        break
      found = self.cursorMatchAt(x, 'X')
      if found != False:
        print("x:{}".format(x))
        found = self.cursorMatchAt(y, 'Y')
        if found != False:
          print("y:{}".format(y))
          found = self.cursorMatchAt(z, 'Z')
          if found != False:
            print("z:{}".format(z))
            self.cursorReset
            return found
      # print(found)
      found = False
      self.cursorReset()
      return found

  # -----------------------------------------
  def cursorMatchAt(self, matchValue, label):
  # -----------------------------------------
    while matchValue != self.get_cursorAt(label):
      self.cursor += 1
      if self.cursor > self.get_tableLength():
        return False

    return self.get_cursorAt(label)

  # ----------------------------
  def get_cursorAt(self, label):
  # ----------------------------
    return self.get_tableAt(self.cursor, label)

  # ------------------------------------
  def get_tableAt(self, rowIdx,  label):
  # ------------------------------------
    if rowIdx >= self.get_tableLength():
      return False
    return self.__wavelengthTable[rowIdx][label.upper()]

显然它不起作用,因为我得到的 XYZ 从来没有完全匹配一个位置。

所以我开始检查最近的位置函数,并尝试了这个:

  # -----------------------------
  def aproxMatch(self, XYZArray):
  # -----------------------------
    x = float(round(XYZArray[0], 4))
    y = float(round(XYZArray[1], 4))
    z = float(round(XYZArray[2], 4))
    # print("[{}:{}:{}]".format(x,y,z))
    xfound = self.findNearestAt(x, 'X')
    yfound = self.findNearestAt(y, 'Y')
    zfound = self.findNearestAt(z, 'Z')
    print("[{}:{}:{}]".format(xfound,yfound,zfound))

    mx = max([xfound, yfound, zfound])
    mn = min([xfound, yfound, zfound])
    diff = mx - mn

    if diff > 5:
      return False

    return (xfound + yfound + zfound)/3

  # -----------------------------------------
  def findNearestAt(self, matchValue, label):
  # -----------------------------------------
    array = np.asarray(self.table[label])
    idx = (np.abs(array - matchValue)).argmin()
    return idx

但显然这不起作用,因为它仍然太严格。然后我尝试了插值方面的事情,我必须说......我迷路了。

我得到了插值的全局概念,但我似乎无法找到如何应用良好的插值类型。所以我只需要有人告诉我应该使用哪个来解决这个问题。

我不是在寻求解决方案,我只需要关于在哪里搜索的建议 - 因为插值似乎是一个全新的信息宇宙,我发现了“变异”对象或在池中的值之间近似的东西。但我不明白如何在 4d 数组中获得 3d 矢量的近似位置。

所以要恢复:我只需要插值世界中的一个方向,以了解如何在 4d 数组中获得与 3d 向量最接近的匹配的第 4 维。

标签: python-3.xvectorinterpolation4d

解决方案


首先,从 RGB 转换为 WaveLength 似乎需要将 RGB 值标准化为设定强度的步骤,然后查找标准化值并回答波长和强度值对。

那是

( wavelength( norm(R, G, B) ), intensity(R, G, B) )

这是基于注意比例相似的 RGB 值应该映射到相同的波长。相似的值具有相同的颜色,只是强度不同。

这表明波长表也被归一化。而且,黑色是波长未定义且强度为零的特殊情况。

第二,不应该findNearestAt比较距离吗?请注意,比较可以使用距离的平方,这样进行比较会快得多。

第三,如果波长表被归一化,那么表值(和查找值)都适合三维球体的表面。由于表中的值是按波长排序的,因此这些点应该以有序的方式穿过球体,尽管可能不是一条简单的线。这种有序的放置很可能用于形成快速查找功能。


推荐阅读