Как я могу получить массив гауссовского ядра для фильтрации моего изображения
Для эксперимента мне нужен гауссов фильтр по всему окну, например, показывается средняя часть. Поскольку я использую PsychoPy, в основном, мне нужен массив N x M (N и M - размер в пикселях окна) из тех, что находятся посередине (где основной стимул видим, идущий к -1 по краям. Тогда я могу использовать этот массив в качестве маски в GratingStim. До сих пор я пробовал ndimage.filters.gaussian_filter(filter_input, sigma = 7)
Но у меня возникли некоторые проблемы с этой функцией. Если filter_input представляет собой матрицу NxM с единицами или нулями, функция ndimage оставляет их без изменений. Если filter_input - это матрица со случайными числами, она все равно меняет их. Но я все еще не получил результат, на который я надеюсь. Я осознаю тот факт, что маски PsychoPy допускают только значения от -1 до 1, но, как теперь показано в приведенном ниже коде, я не должен ничего видеть, поскольку маска равна -1.
Итак, чтобы быть более конкретным: почему ndimage.filters.gaussian_filter(filter_input, sigma = 7) ведет себя так же, как и он? Как я могу заставить его присвоить каждой точке в матрице NxM такое значение, чтобы назначенные значения имели гауссово 2d-распределение? Позже я мог просто отрубить значения выше 1 и ниже -1.
Прошу прощения, если мой вопрос тривиален, я занимался программированием в PsychoPy, но я новичок в numpy и scipy...
Спасибо за вашу помощь!
Вот пример кода:
# -*- 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()
1 ответ
Ваш вклад в gaussian_filter
массив, заполненный -1. Всякий раз, когда вы фильтруете, вы должны учитывать, как обрабатываются края. Обработка краев gaussian_filter
определяется mode
аргумент. По умолчанию mode
является 'reflect'
, что означает, что данные "вне" вашего массива (с точки зрения фильтра) являются отраженной копией данных внутри массива. Так что единственное значение, которое gaussian_filter
видит это константа -1. Фильтр Гаусса является фильтром нижних частот, поэтому постоянное значение передается без изменений. Вот почему ваш массив gaussian
содержит те же значения, что и filter_input
,
Чтобы создать фактическую гауссову поверхность, передайте массив с нулем, за исключением одного 1 в центре. Например,
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
является scipy.ndimage
, а также imshow
является matplotlib.pyplot.imshow
.)