Can I transfer numpy data to imageStim?

Hi Friends.
I need to load 600 pictures in the computer.
Use PIL to load original pictures spend about 45 seconds now.
It’s too long to load picitures.

I read the baseVisual.py。In def _createTexture it says “tex : Any Texture data. Value can be anything that resembles image data.”
And I find some codes about:

 if type(tex) == numpy.ndarray:

But I use the numpy data,the screen shows strange pictures.Full screen are white only a litter space are red.
This is my code:


def ReadPicture(dirPath, win):
    pic = []
    # 对目录下的文件进行遍历
    for file in os.listdir(dirPath):
        # 判断是否是文件
        if os.path.isfile(os.path.join(dirPath, file)) == True:
            c = os.path.basename(file)
            name = dirPath + '\\' + c
            im1 = Image.open(name)
            im = np.array(im1) # here I transfer the numpy data.
            pic.append(visual.ImageStim(win, image=im, units='norm', size=2))
    return pic

def demo(win):
    time_start = time.time()
    pic = ReadPicture("../img/pic/",win)
    time_end = time.time()
    print("time cost:",time_end-time_start)
    loopFlag = True
    while loopFlag:
        for i in range(len(pic)):
            pic[i].draw()
            win.flip()
        if keyboard.is_pressed('escape'):
            loopFlag = False
            continue

if __name__ == "__main__":
    mon = monitors.Monitor(
        name='my_monitor',
        # width=53.704,  # 显示器宽度,单位cm
        # distance=45,  # 被试距显示器距离,单位cm
        gamma=None,  # gamma值
        verbose=False)  # 是否输出详细信息
    mon.setSizePix(utilSize)  # 设置显示器分辨率
    mon.save()  # 保存显示器信息
    win = visual.Window(monitor=mon, size=(1900,1000), fullscr=False,
                        screen=0, winType='pyglet', units='norm')  # , allowGUI=False

    # 退出
    demo(win)

Are there have any way to increase the loading speed?
Or transfer the numpy data to imageStim is the best way to increase the loading speed?

Looking forward to receiving reply.
Thanks!

I think the problem is this line:

im = np.array(im1) # here I transfer the numpy data.

ImageStim can accept a PIL image directly, so you don’t need to convert to an array, and it’s better not to as the conversion can cause problems like what you’re seeing.

If you’re interested, the problem is with color spaces - when a PIL image is converted to an array, it’s outputted with RGB values ranging from 0-255, but ImageStim expects an array to be from 0-1. If you ever need to, we now have a class which can handle this conversion much easier than before, you’d just need to do this:

from psychopy import colors, visual
win = visual.Window()

# Load PIL image
img = Image.open("myImage.png")
# Convert to an array (RGB from 0 to 255)
imgArray = numpy.array(img)
# Convert to a PsychoPy Color array
imgColors = colors.Color(imgArray, 'rgb255')
# Create Image
imgObject = visual.ImageStim(win, image=imgColors)

Thanks for your reply.
I tried to use your offered function at once.But my console remind me about this Error.

File "D:/five_center/1026/ssvep/Demo/loadPic.py", line 23, in ReadPicture
    pic.append(visual.ImageStim(win, image=imgColors))
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\visual\image.py", line 96, in __init__
    self.color = color
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\visual\basevisual.py", line 365, in color
    self.foreColor = value
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\visual\image.py", line 277, in foreColor
    self.setImage(self._imName, log=False)
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\visual\image.py", line 338, in setImage
    setAttribute(self, 'image', value, log)
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\tools\attributetools.py", line 141, in setAttribute
    setattr(self, attrib, value)
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\tools\attributetools.py", line 32, in __set__
    newValue = self.func(obj, value)
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\visual\image.py", line 309, in image
    value = value.render('rgb1')
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\colors.py", line 347, in render
    buffer = self.copy()
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\colors.py", line 427, in copy
    dupe.rgba = self.rgba
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\colors.py", line 479, in rgba
    return self._appendAlpha('rgb')
  File "D:\five_center\1026\ssvep\Lib\site-packages\psychopy\colors.py", line 469, in _appendAlpha
    alpha = alpha.reshape((len(self), 1))
ValueError: cannot reshape array of size 3240 into shape (1080,1)

Process finished with exit code -1

Sorry I can’t solve this error.
Here’s my edit version about readPicture this function.

def ReadPicture(dirPath, win):
    pic = []
    # 对目录下的文件进行遍历
    for file in os.listdir(dirPath):
        # 判断是否是文件
        if os.path.isfile(os.path.join(dirPath, file)) == True:
            c = os.path.basename(file)
            name = dirPath + '\\' + c
            im1 = Image.open(name)
            # im = np.array(im1)
            imgArray = np.array(im1)
            imgColors = colors.Color(imgArray,'rgb255')
            pic.append(visual.ImageStim(win, image=imgColors))
    return pic

I guess perhaps it’s about pic.append()←this.Or another wrong.
Hope receive your reply.

supplement:I use psychoPy 2021.1.3.Is the color.Colors() this function in new version?

I was just giving that as extra info, I think your problem can be solved by just using im rather than im1 :slight_smile:

Ok.Thanks a lot.
I will try to find another way to solve my problems.