Uma introdução sobre como representar, ler e exibir imagens no Adessowiki podem ser vista em:
master:tutorial_img_ds Representação, Leitura e Visualização de Imagens no Adessowiki
.O conceito de fatiamento (slicing) do Numpy é um dos mais importantes para processamento de imagens, tanto pela sua versatilidade como pela sua eficiência. Reunimos nesta página um conjunto de processamento de imagens utilizando quase que exclusivamente operações de fatiamento.
Para entender melhor como o fatiamento funciona, recomenda-se ver uma explicação didática do fatiamento:
tutorial_numpy_1_2 Fatiamentos unidimensionais
tutorial_numpy_1_3 Fatiamentos bidimensionais
In [59]:
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from PIL import Image
from IPython.display import display
In [61]:
f = mpimg.imread('../data/cameraman.tif').copy()
display(Image.fromarray(f))
In [17]:
f[::10,:] = 255 # linhas horizontais
f[:,::10] = 255 # linhas verticais
Image.fromarray(f)
Out[17]:
In [20]:
f = mpimg.imread('../data/cameraman.tif').copy()
display(Image.fromarray(f))
f[ :10, : ] = 0 # frame superior
f[-10: , : ] = 0 # frame inferior
f[ : , :10] = 0 # frame esquerdo
f[ : ,-10: ] = 0 # frame direito
display(Image.fromarray(f))
In [22]:
f1 = mpimg.imread('../data/cameraman.tif').copy()
f = f1[:,64:192]
print('original shape=%s' % (f.shape,))
Image.fromarray(f)
Out[22]:
In [23]:
g = f.transpose()
print('transposta shape=%s' % (g.shape,))
Image.fromarray(g)
Out[23]:
In [24]:
gr = g[::-1,:]
#'reflete na vertical'
Image.fromarray(gr)
Out[24]:
In [25]:
gr[:10,:20] = 0
Image.fromarray(gr)
Out[25]:
In [27]:
g = f1[::2,::2]
print('shape=%s' % (g.shape,) )
display(Image.fromarray(f1))
Image.fromarray(g)
Out[27]:
In [29]:
f = mpimg.imread('../data/keyb.tif').copy()[:50,:80]
print('original %s' % (f.shape,) )
Image.fromarray(f)
Out[29]:
In [30]:
H,W = f.shape
g = np.zeros( (2*H,2*W), 'uint8')
g[ ::2, ::2] = f
g[1::2, ::2] = f
g[1::2,1::2] = f
g[ ::2,1::2] = f
plt.imshow(g, cmap='gray')
print('ampliada por replicação %s' % (g.shape,) )
print(g)
In [31]:
f = mpimg.imread('../data/tvframe.pgm')[100:350,100:300]
plt.imshow(f, cmap='gray')
print('original com dois campos')
In [32]:
g_par = f[::2,:]
plt.imshow(g_par,cmap='gray')
Out[32]:
In [33]:
g_impar = f[1::2,:]
plt.imshow(g_impar,cmap='gray')
Out[33]:
In [34]:
ns1 = np.array(g_par.shape)
ns = ns1 + np.array([g_impar.shape[0], 0])
print(tuple(ns))
In [35]:
g = np.empty(ns)
g[:g_par.shape[0]] = g_par
g[g_par.shape[0]:] = g_impar
plt.imshow(g,cmap='gray')
Out[35]:
Reescrevendo o código para torná-lo mais legível
In [40]:
H_par,W_par = g_par.shape
H_impar,W_impar = g_impar.shape
F = np.empty((H_par+H_impar, W_par))
F[:H_par] = g_par
F[H_par:] = g_impar
plt.imshow(F,cmap='gray')
Out[40]:
In [41]:
g_even = np.zeros_like(f)
g_even[::2] = f[::2]
g_even[1::2] = f[::2]
display(Image.fromarray(g_even))
print('campo linhas pares')
In [43]:
g_odd = np.zeros_like(f)
g_odd[::2] = f[1::2]
g_odd[1::2] = f[1::2]
print('campo linhas ímpares')
Image.fromarray(g_odd)
Out[43]:
In [44]:
f1 = mpimg.imread('../data/woodlog.tif')
plt.imshow(f1,cmap='gray')
print('f1: woodlog')
In [45]:
f2 = mpimg.imread('../data/keyb.tif')
plt.imshow(f2,cmap='gray')
print('f2: keyb')
In [46]:
H,W = np.minimum(np.array(f1.shape),np.array(f2.shape))
g = np.empty((H,W))
g[::2,:] = f1[:H:2,:W]
g[1::2,:] = f2[1:H:2,:W]
plt.imshow(g[:,:],cmap='gray')
print('linhas ímpares de f1 e pares de f2')
In [47]:
H,W = np.minimum(np.array(f1.shape),np.array(f2.shape))
g = f1[:H,:W]//2 + f2[:H,:W]//2
plt.imshow(g,cmap='gray')
plt.colorbar()
print('combinando f1 + f2 usando cálculo em inteiros')
In [48]:
H,W = np.minimum(np.array(f1.shape),np.array(f2.shape))
g = f1[:H,:W]/f1.max() + f2[:H,:W]/f2.max()
plt.imshow(g,cmap='gray')
plt.colorbar()
print('combinando f1 + f2 usando ponto flutuante')
In [49]:
f = mpimg.imread('../data/keyb.tif')[:50,:50]
plt.imshow(f,cmap='gray')
print('original')
In [50]:
H,W = f.shape
g = np.empty( (2*H,2*W), 'uint8')
g[:H,:W] = f # original no quadrante superior esquerdo
g[H:,:W] = f[::-1,:] # refletida vertical no quadrante inferior esquerdo
g[:H,W:] = f[:,::-1] # refletida horizontal no quadrante superior direito
g[H:,W:] = f[::-1,::-1] # refletida vert. e hor. no quadrante inferior direito
plt.imshow(g,cmap='gray')
print('refletidas')
Uma operação primitiva que é utilizada na construção de várias outras operações é a translação de uma imagem por um fator de deslocamento na vertical e na horizontal. Numpy permite fazer translações extremamente eficientes utilizando fatiamento. O exemplo abaixo, a imagem g é deslocada de (dH,dW).
In [51]:
H,W = 100,200
f = np.zeros((H,W),'uint8')
f[::10,:] = 255
f[:,::10] = 255
plt.imshow(f,cmap='gray')
print('reticulado de passo 10 pixels')
In [55]:
g = mpimg.imread('../data/lenina.pgm').copy()
plt.imshow(g,cmap='gray')
Out[55]:
In [56]:
f = g[:H,:W]
plt.imshow(f,cmap='gray')
print('imagem g na origem (0,0)')
In [58]:
dH,dW = (50,100)
f[dH:H+dH,dW:W+dW] = g[:H,:W]
adshow(f, 'imagem g deslocada por (%d,%d)' % (dH,dW))
In [ ]: