Как я могу получить массив гауссовского ядра для фильтрации моего изображения

Для эксперимента мне нужен гауссов фильтр по всему окну, например, показывается средняя часть. Поскольку я использую 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.)

Другие вопросы по тегам