Python: выполнять размытие только внутри маски изображения - PullRequest
1 голос
/ 10 января 2020

У меня есть изображение в градациях серого и двоичная маска ROI на этом изображении. Я хотел бы выполнить операцию размытия на изображении в оттенках серого, но только в пределах маски. Прямо сейчас я размываю все изображение, а не просто удаляю элементы вне маски, но я не хочу, чтобы пиксели вне маски влияли на мою рентабельность инвестиций. Есть ли способ сделать это без создания пользовательской функции размытия?

в надежде получить что-то вроде:

import scipy
blurredImage = scipy.ndimage.filters.gaussian_filter(img, sigma = 3, weight = myMask)

@ stefan:

blur = 3
invmask = np.logical_not(mask).astype(int)

masked = img * mask
remaining = img * invmask

blurred = scipy.ndimage.filters.gaussian_filter(masked, sigma = blur)
blurred = blurred+remaining

Подход с расширением:

blur = 3
invmask = np.logical_not(mask).astype(int)    
masked = img * mask
masked2 = scipy.ndimage.morphology.grey_dilation(masked,size=(5,5))
masked2 = masked2 *invmask
masked2 = masked + masked2
blurred = scipy.ndimage.filters.gaussian_filter(masked2, sigma = blur)

Ответы [ 2 ]

2 голосов
/ 10 января 2020

То, чего вы хотите достичь, непросто и менее четко определено, чем вы думаете.

Операция размытия соответствует некоторому (isotropi c) усреднению пикселей в окрестности каждого пикселя. Но вблизи границ домена окрестности являются неполными, и вам необходимо исправить это либо

  • путем локального переопределения коэффициентов фильтра, чтобы избежать "запроса" внешних пикселей; простой способ - установить нулевые веса фильтра для этих пикселей; или

  • путем экстраполяции значений пикселей за пределами области интереса. Это должно быть сделано таким образом, чтобы избежать разрывов вдоль границы, например, с помощью реконструкции Пуассона.

Для первого подхода вы можете захватить стандартный фильтр следующим образом:

  • установите для внешних пикселей значение 0 и размытие всего изображения; когда фильтр перекрывает контур, вы получите комбинацию только внутренних весов и внутренних пикселей;

  • установите для внутренних пикселей значение 1 и размыте изображение; вы получите только сумму внутренних весов;

  • примите соотношение обоих размытых изображений, чтобы веса правильно перенормировались.

Если изображения имеют целочисленный тип, используйте 255 вместо 1, чтобы сохранить достаточную точность. Помните, что за пределами ROI у крысы ios будет нулевой знаменатель.

1 голос
/ 10 января 2020

Правильный подход для применения линейного фильтра к ограниченной области - это использовать Normalized Convolution . Этот метод вычисляет (взвешенное) среднее значение в пределах каждой окрестности, затем нормализуется по (взвешенному) количеству пикселей, присутствующих в этой окрестности. Для этого используются только два применения фильтра и несколько тривиальных операций на пиксель:

# normalized convolution of image with mask
filter = scipy.ndimage.filters.gaussian_filter(img * mask, sigma = blur)
weights = scipy.ndimage.filters.gaussian_filter(mask, sigma = blur)
filter /= weights
# after normalized convolution, you can choose to delete any data outside the mask:
filter *= mask

Обратите внимание, что mask не обязательно должен быть просто 0 и 1, он может содержать промежуточные значения, указывающие, как «уверен», что вы правы в значении этого пикселя. Но обычно это просто 0 для «отсутствующих данных» и 1 для доступных данных.

gaussian_filter должен выполнить свои вычисления в формате с плавающей запятой и вернуть изображение с плавающей запятой. Целочисленные операции здесь не будут работать правильно.


Вот пример:

enter image description here

  • 2-е изображение: простая фильтрация, затем удаление материала вне маски. Это показывает, что данные вне маски влияют на результат фильтрации.

  • 3-е изображение: обычная фильтрация, но сначала устанавливается ноль вне маски. Это показывает, что нули вне маски влияют на результат фильтрации.

  • 4-е изображение: с использованием нормализованной свертки: данные за пределами маскированной области вообще не влияют на фильтрацию.

...