I was reading "The remarkable inefficiency of word recognition" (Pelli et al. 2003) and I wanted to generate some of the stimuli they were using. In Python it took me a few hours total, starting cold using the Python Imaging Library. The code is below....
"""This contains routines to generate degraded letter stimuli"""
import Image #The PIL
import ImageDraw
import ImageFont
import numpy
def generate_letter(contrast_energy = .01, #michelson contrast energy
noise = 30.,
bg_luminance = 128.,
letter = "a",
letter_size = 400):
N = 300 #size of image in pixels
#first figure out what is the ink-area of the letter
font = ImageFont.truetype("Data/arial.ttf", letter_size)
#we copy the .ttf file to the local directory to avoid problems
im_temp = Image.new("1", (1,1), 0)
draw = ImageDraw.Draw(im_temp)
#now we can draw on this
sz = draw.textsize(letter, font=font)
#this tells us the size of the letter
im_temp = Image.new("1", sz, 0)
#this is a temporary binary image created solely for the purpose of computing
#the ink-area of the letter
draw = ImageDraw.Draw(im_temp)
#now we can draw on this
draw.text((0,0), letter, font=font, fill=1)
pix = im_temp.load()
#pix is now an addressable array of pixel values
area_in_pixels = 0.
for row in xrange(sz[0]):
for col in xrange(sz[1]):
area_in_pixels += pix[row,col]
#since contrast_energy = contrast^2 * pixel_area
contrast = (contrast_energy/area_in_pixels)**0.5
fg_luminance = bg_luminance*(1+contrast)/(1-contrast)
print area_in_pixels
print contrast
print fg_luminance
im = Image.new("L", (N,N), bg_luminance)
#im is now a NxN luminance image with luminance set to bg_luminance
draw = ImageDraw.Draw(im)
#now we can draw on this
draw.text(((N-sz[0])/2, (N-sz[1])/2), letter, font=font, fill=fg_luminance)
#this centers the letter
if noise > 0:
pix = im.load()
#pix is now an addressable array of pixel values
rd = numpy.random.normal(scale=noise, size=(N,N))
for row in xrange(N):
for col in xrange(N):
pix[row,col] += rd[row,col]
im.show()
Comments
Post a Comment