Сопоставить трехмерный вектор в массиве 4D путем интерполяции? - PullRequest
0 голосов
/ 18 февраля 2019

Итак ... Я пробовал что-то новое ради обучения.Я пытаюсь получить длину волны от 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

I Использую этот класс, хранящий разные процессы - это 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'])

Первое, что я попробовал, это итерация по 4D-таблице через ее 3 координаты XYZ:

  # -------------------------------------
  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

Но, очевидно, это не работает, поскольку он все еще слишком строг.Затем я попробовал на стороне интерполяции вещи, и я должен сказать ... я потерян.

Я получил глобальную концепцию интерполяции, но я не могу найти, как применить хороший тип интерполяции.Поэтому мне просто нужен кто-то, кто скажет мне, кого мне следует использовать для этой проблемы.

Я не прошу решения, мне просто нужен совет о том, где искать - поскольку интерполяция кажется совершенно новым космосоминформацию, которую я нашел, чтобы "мутировать" объект или приблизить промежуточные значения из пула.Но я не понимаю, как можно получить приблизительную позицию трехмерного вектора в 4-мерном массиве.

Итак, чтобы возобновить: мне просто нужно направление в мире интерполяции, чтобы понять, как получить 4-е измерение в 4-мерном массиве с ближайшим совпадением из 3-го вектора.

1 Ответ

0 голосов
/ 18 февраля 2019

Во-первых, для преобразования из RGB в WaveLength требуется шаг нормализации значения RGB до заданной интенсивности, а затем поиск нормализованного значения и ответ на пару значений длины волны и интенсивности.

Это

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

Это основано на том, что пропорционально аналогичные значения RGB должны отображаться на одну и ту же длину волны.Аналогичные значения имеют одинаковый цвет , только с разной интенсивностью.

Это говорит о том, что таблица длин волн также должна быть нормализована.И этот черный является особым случаем, когда длина волны не определена, а интенсивность равна нулю.

Во-вторых, разве findNearestAt не следует сравнивать расстояния?Обратите внимание, что для сравнения можно использовать квадрат расстояния, который был бы намного быстрее для сравнения.

В-третьих, если таблица длин волн нормализована, то все значения таблицы (и значения поиска) соответствуютповерхность трехмерной сферы.Поскольку табличные значения упорядочены (по длине волны), точки должны проходить по сфере упорядоченным образом, хотя, вероятно, не в виде простой линии.Такое упорядоченное размещение вполне возможно может быть использовано для создания функции быстрого поиска.

...