与心理不一致的对比处理
Inconsistent Contrast Handling with Psychopy
我找不到 1.75.01 和 1.82 版本对比度处理差异的根源。这里有两张图片显示了它过去的样子 (1.75),
以及它现在的样子:
不幸的是,回滚并不是微不足道的,因为我 运行 遇到了依赖性问题(尤其是 PIL v PILLOW)。这些图像是从一个 numpy 数组创建的,我怀疑当从数组到图像的转换发生时,与数字的处理方式(?类型,舍入)有关,但我找不到错误。任何帮助将不胜感激。
已编辑 - 新的最小示例
#! /bin/bash
import numpy as np
from psychopy import visual,core
def makeRow (n,c):
cp = np.tile(c,[n,n,3])
cm = np.tile(-c,[n,n,3])
cpm = np.hstack((cp,cm))
return(cpm)
def makeCB (r1,r2,nr=99):
#nr is repeat number
(x,y,z) = r1.shape
if nr == 99:
nr = x/2
else:
hnr = nr/2
rr = np.vstack((r1,r2))
cb=np.tile(rr,[hnr,hnr/2,1])
return(cb)
def makeTarg(sqsz,targsz,con):
wr = makeRow(sqsz,1)
br = makeRow(sqsz,-1)
cb = makeCB(wr,br,targsz)
t = cb*con
return(t)
def main():
w = visual.Window(size = (400,400),units = "pix", winType = 'pyglet',colorSpace = 'rgb')
fullCon_np = makeTarg(8,8,1.0)
fullCon_i = visual.ImageStim(w, image = fullCon_np,size = fullCon_np.shape[0:2][::-1],pos = (-100,0),colorSpace = 'rgb')
fullCon_ih = visual.ImageStim(w, image = fullCon_np,size = fullCon_np.shape[0:2][::-1],pos = (-100,0),colorSpace = 'rgb')
fullCon_iz = visual.ImageStim(w, image = fullCon_np,size = fullCon_np.shape[0:2][::-1],pos = (-100,0),colorSpace = 'rgb')
fullCon_ih.contrast = 0.5
fullCon_ih.setPos((-100,100))
fullCon_iz.setPos((-100,-100))
fullCon_iz.contrast = 0.1
partCon_np = makeTarg(8,8,0.1)
partCon_i = visual.ImageStim(w, image = partCon_np,pos = (0,0), size = partCon_np.shape[0:2][::-1],colorSpace = 'rgb')
zeroCon_np = makeTarg(8,8,0.0)
zeroCon_i = visual.ImageStim(w, image = zeroCon_np,pos=(100,0), size = zeroCon_np.shape[0:2][::-1],colorSpace = 'rgb')
fullCon_i.draw()
partCon_i.draw()
fullCon_ih.draw()
fullCon_iz.draw()
zeroCon_i.draw()
w.flip()
core.wait(15)
core.quit()
if __name__ == "__main__":
main()
产生这个:
水平方向的三个checker-boards在转换为图像之前生成时,数组中的对比度发生了变化。垂直左侧显示,之后更改图像对比度效果很好。我不能使用它的原因是 a) 我用上一个版本收集了很多数据,并且 b) 我想通过将一个数组与另一个数组相乘来以编程方式对中心那些大长条的对比度进行分级,例如使用对数刻度或其他一些函数,在 numpy 中做数学更容易。
我仍然怀疑问题出在从 np.array -> pil.image 的转换中。这些数组的 dtype
是 float64,但即使我强制转换为 float32 也没有任何变化。如果您在转换前以半对比度检查数组,它会填充 0.5 和 -0.5 数字,但所有负数都会变成黑色,并且在 psychopy.tools.imagetools.array2image
转换时黑色被设置为零我认为.
代码太长,我无法通读并解决实际问题。
可能的问题是零应该放在哪里的问题。我认为有一段时间 numpy 数组被视为具有 vals 0:1 而 PsychoPy 的其余部分期望值是 -1:1 所以你可能需要用 array=array*2-1
重新调整你的值才能返回到老(不良行为)。或者也检查不透明度,这可能有类似的问题。如果你写一个最小的例子,我会read/test它正确
谢谢
好的,是的,问题是数组值的比例问题。基本上,您发现了 PsychoPy 无法正确处理的极端情况(即错误)。
说明:
PsychoPy 有一套复杂的转换规则来处理 image/textures;它会尝试推断您将如何处理此图像,以及它是否应该以支持颜色操作(有符号浮点数)或不支持(可以是无符号字节)的方式存储。在您的情况下,PsychoPy 弄错了;数组中充满了浮点数这一事实让 PsychoPy 认为它可以进行颜色变换,但它是 NxNx3 的事实表明它不应该(我们不想为已经有它的东西指定 "color"为每个像素指定的颜色为 rgb vals)。
解决方法(其中之一):
只需将数组提供为 NxN,而不是 NxNx3。无论如何,这是正确的做法; compute/store 对您来说意味着更少,通过提供 "intensity" 值,这些值可以即时重新着色。这大致就是您在仅提供 NxNx3 数组的一个切片时已经发现的内容,但要点是您 could/should 一开始只创建一个切片。
使用 GratingStim,它将所有内容转换为带符号的浮点值,而不是试图计算出最好的值(尽管如此,您可能需要计算空间频率)
您可以通过重新缩放数组 (*0.5+0.5) 添加一行来修复它,但您必须进行一些设置,以便仅针对此版本发生这种情况(我们会修复它在下一个版本之前)
基本上,我建议您执行 (1),因为它已经适用于过去、现在和未来的版本,而且无论如何都更有效。但感谢您让我们知道 - 我会努力确保我们在未来抓住这个
祝福
乔恩
我找不到 1.75.01 和 1.82 版本对比度处理差异的根源。这里有两张图片显示了它过去的样子 (1.75),
不幸的是,回滚并不是微不足道的,因为我 运行 遇到了依赖性问题(尤其是 PIL v PILLOW)。这些图像是从一个 numpy 数组创建的,我怀疑当从数组到图像的转换发生时,与数字的处理方式(?类型,舍入)有关,但我找不到错误。任何帮助将不胜感激。
已编辑 - 新的最小示例
#! /bin/bash
import numpy as np
from psychopy import visual,core
def makeRow (n,c):
cp = np.tile(c,[n,n,3])
cm = np.tile(-c,[n,n,3])
cpm = np.hstack((cp,cm))
return(cpm)
def makeCB (r1,r2,nr=99):
#nr is repeat number
(x,y,z) = r1.shape
if nr == 99:
nr = x/2
else:
hnr = nr/2
rr = np.vstack((r1,r2))
cb=np.tile(rr,[hnr,hnr/2,1])
return(cb)
def makeTarg(sqsz,targsz,con):
wr = makeRow(sqsz,1)
br = makeRow(sqsz,-1)
cb = makeCB(wr,br,targsz)
t = cb*con
return(t)
def main():
w = visual.Window(size = (400,400),units = "pix", winType = 'pyglet',colorSpace = 'rgb')
fullCon_np = makeTarg(8,8,1.0)
fullCon_i = visual.ImageStim(w, image = fullCon_np,size = fullCon_np.shape[0:2][::-1],pos = (-100,0),colorSpace = 'rgb')
fullCon_ih = visual.ImageStim(w, image = fullCon_np,size = fullCon_np.shape[0:2][::-1],pos = (-100,0),colorSpace = 'rgb')
fullCon_iz = visual.ImageStim(w, image = fullCon_np,size = fullCon_np.shape[0:2][::-1],pos = (-100,0),colorSpace = 'rgb')
fullCon_ih.contrast = 0.5
fullCon_ih.setPos((-100,100))
fullCon_iz.setPos((-100,-100))
fullCon_iz.contrast = 0.1
partCon_np = makeTarg(8,8,0.1)
partCon_i = visual.ImageStim(w, image = partCon_np,pos = (0,0), size = partCon_np.shape[0:2][::-1],colorSpace = 'rgb')
zeroCon_np = makeTarg(8,8,0.0)
zeroCon_i = visual.ImageStim(w, image = zeroCon_np,pos=(100,0), size = zeroCon_np.shape[0:2][::-1],colorSpace = 'rgb')
fullCon_i.draw()
partCon_i.draw()
fullCon_ih.draw()
fullCon_iz.draw()
zeroCon_i.draw()
w.flip()
core.wait(15)
core.quit()
if __name__ == "__main__":
main()
产生这个:
水平方向的三个checker-boards在转换为图像之前生成时,数组中的对比度发生了变化。垂直左侧显示,之后更改图像对比度效果很好。我不能使用它的原因是 a) 我用上一个版本收集了很多数据,并且 b) 我想通过将一个数组与另一个数组相乘来以编程方式对中心那些大长条的对比度进行分级,例如使用对数刻度或其他一些函数,在 numpy 中做数学更容易。
我仍然怀疑问题出在从 np.array -> pil.image 的转换中。这些数组的 dtype
是 float64,但即使我强制转换为 float32 也没有任何变化。如果您在转换前以半对比度检查数组,它会填充 0.5 和 -0.5 数字,但所有负数都会变成黑色,并且在 psychopy.tools.imagetools.array2image
转换时黑色被设置为零我认为.
代码太长,我无法通读并解决实际问题。
可能的问题是零应该放在哪里的问题。我认为有一段时间 numpy 数组被视为具有 vals 0:1 而 PsychoPy 的其余部分期望值是 -1:1 所以你可能需要用 array=array*2-1
重新调整你的值才能返回到老(不良行为)。或者也检查不透明度,这可能有类似的问题。如果你写一个最小的例子,我会read/test它正确
谢谢
好的,是的,问题是数组值的比例问题。基本上,您发现了 PsychoPy 无法正确处理的极端情况(即错误)。
说明: PsychoPy 有一套复杂的转换规则来处理 image/textures;它会尝试推断您将如何处理此图像,以及它是否应该以支持颜色操作(有符号浮点数)或不支持(可以是无符号字节)的方式存储。在您的情况下,PsychoPy 弄错了;数组中充满了浮点数这一事实让 PsychoPy 认为它可以进行颜色变换,但它是 NxNx3 的事实表明它不应该(我们不想为已经有它的东西指定 "color"为每个像素指定的颜色为 rgb vals)。
解决方法(其中之一):
只需将数组提供为 NxN,而不是 NxNx3。无论如何,这是正确的做法; compute/store 对您来说意味着更少,通过提供 "intensity" 值,这些值可以即时重新着色。这大致就是您在仅提供 NxNx3 数组的一个切片时已经发现的内容,但要点是您 could/should 一开始只创建一个切片。
使用 GratingStim,它将所有内容转换为带符号的浮点值,而不是试图计算出最好的值(尽管如此,您可能需要计算空间频率)
您可以通过重新缩放数组 (*0.5+0.5) 添加一行来修复它,但您必须进行一些设置,以便仅针对此版本发生这种情况(我们会修复它在下一个版本之前)
基本上,我建议您执行 (1),因为它已经适用于过去、现在和未来的版本,而且无论如何都更有效。但感谢您让我们知道 - 我会努力确保我们在未来抓住这个
祝福 乔恩