Copie el valor del píxel central al valor mayoritario en el bloque

Tengo una matriz de predicción de píxeles de imagen que es de tamaño 9085×10852. Quiero obtener un bloque de 10×10 alrededor de cada píxel. Si el valor del píxel central es diferente de los valores de píxeles mayoritarios en el bloque, entonces reemplace el valor del píxel central con el valor mayoritario. ¿Alguien puede ayudarme por favor?

Estaba buscando en scikit-image busca de otra cosa hoy y si profundizas en scikit-image.filters y luego en rank , ¡te encuentras con modal() ! Vea la documentación aquí .

Usé la misma semilla aleatoria que @Tonechas para generar resultados comparables:

 import numpy as np from skimage.morphology import rectangle # for Structuring Elements (eg 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) 

Palabras clave : Python, numpy, scikit, skimage, procesamiento de imágenes, proceso de imágenes, mediana, modo, modal, elemento estructurante, morfología, filtro, filtros, rango.

Como parece un poco inseguro / inconsistente acerca de los detalles de su pregunta, me gustaría sugerir una solución alternativa muy simple, no en Python sino demasiado grande para un comentario, que lo ayude a usted ya otros a explorar si realmente desea esto y qué. realmente quieres, antes de que alguien pase horas codificando Python.

Le sugiero que use ImageMagick, que se instala en la mayoría de las distribuciones de Linux y está disponible para macOS y Windows. Entonces, solo en la Terminal , puedes hacer una imagen de muestra que es negra con un cuadrado blanco en el medio, así:

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

introduzca la descripción de la imagen aquí

Ahora prueba tu filtro y podrás ver redondeadas las esquinas:

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

introduzca la descripción de la imagen aquí

Ahora intente de nuevo con un “radio” más grande:

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

introduzca la descripción de la imagen aquí

Tal vez puedas experimentar con eso y ver si hace lo que quieres antes de que alguien pierda demasiado tiempo codificando algo.

Un posible enfoque podría ser definir una función que reemplace el valor central por el modo …

 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] 

… y pasando dicha función a scipy.ndimage.generic_filter .

Manifestación

 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) 

Observe que este código puede tardar un tiempo en ejecutarse en una matriz de 9085 × 10852.