2017-09-02 9 views
2

J'essaie de pixelliser (\ mosaïque) une image en calculant la moyenne d'une fenêtre glissante (sans chevauchement) sur l'image. Pour cela j'essaye d'implémenter un "taille de fenêtre" et un "pas" paramètres. En supposant que mon pas ne dépassera pas la bordure de l'image. Signifie que si mon image est un 32X32 dims la fenêtre peut être 2x2 \ 4x4 \ 8x8 \ 16x16 dims. Here an exampleEssayer de calculer la moyenne d'une fenêtre glissante d'une image Python

J'essaie de chercher quelques combinaisons d'opérateur moyen \ masque \ convolution mais je n'ai rien trouvé de pertinent. Voici quelques exemples de ce que j'essaie de rechercher: Ces liens ont donné quelques parties de ma question mais je n'ai pas trouvé comment les combiner pour implémenter une fenêtre glissante avec pas à pas.

Numpy à deux dimensions moyenne mobile, scipy.org/../scipy.signal.medfilt, mosaic.py sur Vectorisation GitHub et Numpy de fonctionnement fenêtre coulissante Comment faire fenêtre coulissante pour pixelate parties d'une image séparément.

+0

Êtes-vous seulement à la recherche de sous-échantillonnage (par exemple, [cette question] (https://stackoverflow.com/ questions/18666014/downsample-array-in-python)) ou voulez-vous réellement préserver la taille de l'image (quelque chose comme un sous-échantillonnage et haut de gamme)? – jdehesa

+0

Je ne suis pas sûr Si j'ai bien compris ce que signifie le sous-échantillonnage. Je veux garder les dimensions dans leur taille proportionnelle d'origine. Je veux juste déplacer une fenêtre sans chevauchement et appliquer la valeur moyenne de celle-ci sur la partie correspondante de l'image. Ensuite, faites glisser la fenêtre à la partie suivante repeativley. Exactement comme indiqué dans l'image que j'ai jointe. Merci pour votre réponse. –

Répondre

0

est ici (je pense) une solution à votre problème:

def pixelate(img, wx, wy=None): 
    wy = wy or wx 
    y, x = img.shape 
    if x % wx != 0 or y % wy != 0: 
     raise ValueError("Invalid window size.") 
    ny = y // wy 
    nx = x // wx 
    windowed = img.reshape((ny, wy, nx, wx)) 
    means = windowed.mean(axis=(1, 3), keepdims=True) 
    means = np.tile(means, (1, wy, 1, wx)) 
    result = means.reshape((y, x)) 
    return result 

img est un tableau 2D NumPy représentant une image, wx est la dimension horizontale de la fenêtre et wy la taille verticale (qui par défaut au même que wy). L'image doit être divisible par la taille de la fenêtre. Fondamentalement, il remodèle le tableau d'image à ses fenêtres, calcule les moyens, les carreaux le résultat et remet en forme.

est un exemple ici avec une circonférence:

import numpy as np 
import matplotlib.pyplot as plt 

def pixelate(img, wx, wy=None): 
    wy = wy or wx 
    y, x = img.shape 
    if x % wx != 0 or y % wy != 0: 
     raise ValueError("Invalid window size.") 
    ny = y // wy 
    nx = x // wx 
    windowed = img.reshape((ny, wy, nx, wx)) 
    means = windowed.mean(axis=(1, 3), keepdims=True) 
    means = np.tile(means, (1, wy, 1, wx)) 
    result = means.reshape((y, x)) 
    return result 

# Build a circumference 
WIDTH = 400 
HEIGHT = 300 
RADIUS = 100 
THICKNESS = 10 
xx, yy = np.meshgrid(np.arange(WIDTH) - WIDTH/2, np.arange(HEIGHT) - HEIGHT/2) 
r = np.sqrt(np.square(xx) + np.square(yy)) 
circ = (r > (RADIUS - THICKNESS/2)) & (r < (RADIUS + THICKNESS/2)) 
circ = circ.astype(np.float32) 

# Pixelate 
WINDOW_SIZE = 20 
circ_pix = pixelate(circ, WINDOW_SIZE) 

# Show 
fig = plt.figure() 
ax1 = fig.add_subplot(121) 
ax1.imshow(circ, "binary") 
ax2 = fig.add_subplot(122) 
ax2.imshow(circ_pix, "binary") 

Sortie:

Result