所以... 为了学习,我一直在尝试一些新的东西。 我正在尝试从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维。
答案 0 :(得分:0)
首先,从RGB转换为WaveLength似乎需要执行以下步骤:将RGB值归一化为设置的强度,然后查找归一化值并回答一对波长和强度值。
那是
( wavelength( norm(R, G, B) ), intensity(R, G, B) )
这是基于注意到比例相似的RGB值应映射到相同的波长。相似的值具有相同的 color (颜色),只是强度不同。
这表明波长表也已归一化。而且,黑色是一种特殊情况,其中未定义波长且强度为零。
第二,findNearestAt
不应该比较距离吗?请注意,比较可以使用距离的平方,这样可以更快地进行比较。
第三,如果将波长表归一化,则表值(和查找值)都适合于三维球体的表面。由于表值是有序的(按波长排序),因此这些点应该以有序的方式行进穿过球体,尽管可能不是简单的行。这种有序的放置很有可能会用于构建快速查找功能。