通过插值匹配4D数组中的3D向量?

时间:2019-02-18 18:09:12

标签: python-3.x vector interpolation 4d

所以... 为了学习,我一直在尝试一些新的东西。 我正在尝试从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'])

我尝试的第一件事是通过3D 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向量的近似位置。

因此,我继续:我只需要在插值世界中找到一个方向,即可了解如何从3d向量中获得最匹配的4d数组中的第4维。

1 个答案:

答案 0 :(得分:0)

首先,从RGB转换为WaveLength似乎需要执行以下步骤:将RGB值归一化为设置的强度,然后查找归一化值并回答一对波长和强度值。

那是

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

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

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

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

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