Скопируйте значение центрального пикселя в значение большинства в блоке - PullRequest
0 голосов
/ 28 августа 2018

У меня есть массив предсказания пикселей изображения размером 9085x10852. Я хочу получить блок 10х10 вокруг каждого пикселя. если значение центрального пикселя отличается от значений большинства пикселей в блоке, то замените значение центрального пикселя значением большинства. Может кто-нибудь помочь мне, пожалуйста

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

Одним из возможных подходов может быть определение функции, которая заменяет центральное значение режимом ...

import numpy as np
from scipy.ndimage import generic_filter

def most_frequent(x):
    central = x[x.size//2] 
    values, counts = np.unique(x, return_counts=True)
    max_freq = counts.max()
    modes = values[counts == max_freq]
    if central in modes:
        return central
    else:
        return modes[0]

... и передачу такой функции в scipy.ndimage.generic_filter.

Демо

In [143]: r = 2

In [144]: block_size = (2*r + 1, 2*r + 1)

In [145]: block_size
Out[145]: (5, 5)

In [146]: np.random.seed(329)

In [147]: arr = np.random.randint(low=0, high=10, size=(6, 8), dtype=np.uint8)

In [148]: arr
Out[148]: 
array([[9, 6, 2, 2, 0, 5, 6, 4],
       [9, 7, 0, 2, 0, 5, 4, 2],
       [1, 3, 8, 1, 4, 6, 5, 2],
       [5, 1, 7, 8, 5, 7, 0, 2],
       [8, 1, 0, 5, 4, 5, 4, 5],
       [4, 1, 5, 3, 6, 9, 4, 3]], dtype=uint8)

In [149]: generic_filter(arr, function=most_frequent, 
     ...:                size=block_size, mode='constant', cval=np.nan)
     ...: 
Out[149]: 
array([[9, 2, 2, 2, 0, 2, 4, 5],
       [9, 1, 0, 2, 0, 2, 5, 2],
       [1, 1, 0, 5, 5, 5, 5, 5],
       [1, 1, 1, 5, 5, 5, 4, 5],
       [1, 1, 1, 5, 5, 5, 4, 5],
       [1, 1, 5, 5, 5, 5, 4, 4]], dtype=uint8)

Обратите внимание, что запуск этого кода в массиве 9085 & times; 10852 может занять некоторое время.

0 голосов
/ 11 сентября 2018

Я копался в scikit-image, искал что-то еще сегодня, и если вы углубитесь в scikit-image.filters, а затем еще дальше в rank, вы столкнетесь с modal()! Смотри документацию здесь .

Я использовал то же случайное начальное число, что и @Tonechas, чтобы получить сопоставимые результаты:

import numpy as np
from skimage.morphology import rectangle   # for Structuring Elements (e.g. disk, rectangle)
from skimage.filters.rank import modal     # the puppy we want

# Same seed for directly comparable results
np.random.seed(329)

# Sample array/image
arr = np.random.randint(low=0, high=10, size=(6, 8), dtype=np.uint8)

# Run the filter with a 5x5 rectangular Structuring Element
result = modal(arr,rectangle(5,5))

print(result)

array([[9, 2, 0, 0, 0, 2, 4, 5],
       [1, 1, 0, 0, 0, 2, 5, 2],
       [1, 1, 0, 5, 5, 5, 5, 5],
       [1, 1, 1, 5, 5, 5, 4, 5],
       [1, 1, 1, 1, 5, 5, 4, 5],
       [1, 1, 5, 5, 5, 5, 4, 4]], dtype=uint8)

Ключевые слова : Python, numpy, scikit, skimage, обработка изображений, обработка изображений, медиана, режим, модальный, структурирующий элемент, морфология, фильтр, фильтры, ранг.

0 голосов
/ 29 августа 2018

Поскольку вы, кажется, немного не уверены / не согласны в деталях вашего вопроса, я хотел бы предложить очень простое, альтернативное решение, не на Python, но слишком большое для комментария, которое поможет вам и другим узнать, действительно ли вы хотите это и то, что вы действительно хотите - прежде чем кто-то потратит часы на программирование Python.

Я предлагаю вам использовать ImageMagick , который установлен в большинстве дистрибутивов Linux и доступен для macOS и Windows. Итак, просто в Terminal вы можете создать пример изображения черного цвета с белым квадратом посередине, например:

convert -size 100x100 xc:black -fill white -draw "rectangle 10,10 90,90" test.png

enter image description here

Теперь попробуйте свой фильтр, и вы увидите, что углы скруглены:

convert test.png -statistic mode 10x10 result.png

enter image description here

Теперь попробуйте еще раз с большим "радиусом" :

convert test.png -statistic mode 20x20 result.png

enter image description here

Может быть, вы можете поэкспериментировать с этим и посмотреть, будет ли он делать то, что вы хотите, прежде чем кто-то потратит слишком много времени на кодирование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...