Reputation: 141
For an experiment, I need a gaussian filter over an entire window such as the middle part is shown. Since I use PsychoPy, basically, I need an N x M array (N and M are the size in pixels of the window) of ones in the middle (where the underlying stimulus is visible going to -1 at the edges. I can then use this array as a mask within GratingStim. So far, I have been trying ndimage.filters.gaussian_filter(filter_input, sigma = 7)
But I am having some trouble with this funcion. If filter_input is a NxM matrix with ones or zeros, the ndimage function leaves them unchanged. If filter_input is a matrix with random numbers, it changes them all right. But I still don't get the result I am hoping for. I am aware of the fact that PsychoPy masks allow only values between -1 and 1 but as it s now in the code below, I should not be able to see anything since the mask is -1.
So, to be more specific: Why does ndimage.filters.gaussian_filter(filter_input, sigma = 7) behave like it does? How could I get it to assign to every point in the NxM matrix a value such that the assigned values have a gaussian 2d distribution? Later I could just chop off the values higher than 1 and lower than -1.
I am sorry if my question is trivial, I have been doing some programing in PsychoPy but I am new to numpy and scipy...
Thanks for your help!
Here is some example code:
# -*- coding: utf-8 -*-
from psychopy import visual, event
import numpy as np
from scipy import ndimage
win = visual.Window([500,500])
#draw rectangle
perc25 = visual.Rect(win, width = 0.6,height=0.4, lineColor='red',fillColor = 'red', pos=(0.0, 0.1)) #notloesu
perc25.draw()
#add circle with fuzzy edges
perc75 = visual.GratingStim(win, sf=0, size=0.5, color='green',pos=(0.0, -0.1), mask = 'raisedCos', maskParams={'fringeWidth':0.6})
perc75.draw()
#create the matrix that should result in a gaussian filter laied centrally over the entire window
#desired Result: some red in the upper part of the visible circle in the middle, the rest beeing green
filter_input = (np.ones([500,500]))*(-1.)
gaussian = ndimage.filters.gaussian_filter(filter_input, sigma = 0.2)
print(filter_input == gaussian)
#i know it's ugly, I just can't think of another way to apply the filter to the entire image and I haven't found anything in the internet
unnecesary_stim_to_get_the_mask_over_the_window = visual.GratingStim(win, sf=0, size=0.0000001, color='green',pos=(0, 0), mask = gaussian)
unnecesary_stim_to_get_the_mask_over_the_window.draw()
win.flip()
event.waitKeys()
Upvotes: 1
Views: 5102
Reputation: 114811
Your input to gaussian_filter
is an array filled with -1. Whenever you filter, you have to consider how the edges are handled. The handling of the edges by gaussian_filter
is determined by the mode
argument. The default mode
is 'reflect'
, which means the data "outside" your array (from the point of view of the filter) is a reflected copy of the data inside the array. So the only value that gaussian_filter
sees is the constant -1. A Gaussian filter is a low-pass filter, so a constant value is passed unchanged. That is why your array gaussian
contains the same values as filter_input
.
To create an actual Gaussian surface, pass an array that is all zero except for a single 1 in the center. For example,
In [92]: x = np.zeros((101, 101))
In [93]: x[50, 50] = 1
In [94]: y = ndi.filters.gaussian_filter(x, sigma=16)
In [95]: imshow(y, interpolation='none', cmap=cm.gray)
Out[95]: <matplotlib.image.AxesImage at 0x1127e4390>
(ndi
is scipy.ndimage
, and imshow
is matplotlib.pyplot.imshow
.)
Upvotes: 5