numpy - Inconsistent Contrast Handling with Psychopy -


i can't not find source of difference in handling of contrast version 1.75.01 , 1.82. here 2 images show used (1.75), v 1.75 , looks like: v1.82

unfortunately, rolling not trivial run problems dependencies (especially pil v pillow). images created numpy array, , suspect there related how numbers getting handled (?type, rounding) when conversion array image occurs, can't find bug. appreciated.

edited - new minimal example

#! /bin/bash  import numpy np 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 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() 

which yields this:

enter image description here

the 3 checker-boards along horizontal have contrast changed in array when generated before conversion image. vertical left shows changing image contrast afterwards works fine. reason can't use a) have collected lot of data last version, , b) want grade contrast of big long bars in centre programatically multiplying 1 array against another, e.g. using log scale or other function, , doing math easier in numpy.

i still suspect issue in conversion np.array -> pil.image. dtype of these array float64, if coerce float32 nothing changes. if examine array before conversion @ half contrast filled 0.5 , -0.5 numbers, negative numbers getting turned black , black being set 0 @ time of conversion psychopy.tools.imagetools.array2image think.

ok, yes, problem issue of scale array values. basically, you've found corner case psychopy isn't handling correctly (i.e. bug).

explanation: psychopy has complex set of transformation rules handling image/textures; tries deduce you're going image , whether should stored in way supports colour manipulations (signed float) or not (can unsigned byte). in case psychopy getting wrong; fact array filled floats made psychopy think color transforms, fact nxnx3 suggest shouldn't (we don't want specify "color" has color specified every pixel rgb vals).

workarounds (any 1 of these):

  1. just provide array nxn, not nxnx3. right thing anyway; means less compute/store , providing "intensity" values these can recolored on-the-fly. had discovered in providing 1 slice of nxnx3 array, point could/should create 1 slice in first place.

  2. use gratingstim, converts signed floating point values rather trying work out what's best (potentially you'd need work out spatial frequency stuff though)

  3. you add line fix rescaling array (*0.5+0.5) you'd have set occurred version (we'll fix before next release)

basically, i'm suggesting (1) because works past, present , future versions , more efficient anyway. letting know - i'll try make sure catch 1 in future

best wishes jon


Comments

Popular posts from this blog

java - Spring Data JPA: Why findOne(id) executing delete query internally? -

python - Mongodb How to add addtional information when aggregating? -

java - Incorrect order of records in M-M relationship in hibernate -