PIL: Crear histograma unidimensional de ligereza imagen en color?
-
10-10-2019 - |
Pregunta
He estado trabajando en un guión, y lo necesito para básicamente:
- Haga la escala de grises de la imagen (o bitonal, voy a jugar con ambos para ver cuál funciona mejor).
- Proceso de cada columna individual y crear un valor de intensidad neta de cada columna.
- Spit los resultados en una lista ordenada.
Hay una manera muy fácil de hacer esto con ImageMagick (aunque se necesita un par de utilidades de Linux para procesar el texto de salida), pero no estoy realmente ver cómo hacer esto con Python y PIL.
Esto es lo que tengo hasta ahora:
from PIL import Image
image_file = 'test.tiff'
image = Image.open(image_file).convert('L')
histo = image.histogram()
histo_string = ''
for i in histo:
histo_string += str(i) + "\n"
print(histo_string)
Este salidas algo (Busco para representar gráficamente los resultados), pero parece en nada a la salida de ImageMagick. Estoy usando este para detectar la costura y el contenido de un libro escaneado.
Gracias a cualquiera que ayude!
Tengo una solución (de aspecto desagradable) que funciona, por ahora:
from PIL import Image
import numpy
def smoothListGaussian(list,degree=5):
window=degree*2-1
weight=numpy.array([1.0]*window)
weightGauss=[]
for i in range(window):
i=i-degree+1
frac=i/float(window)
gauss=1/(numpy.exp((4*(frac))**2))
weightGauss.append(gauss)
weight=numpy.array(weightGauss)*weight
smoothed=[0.0]*(len(list)-window)
for i in range(len(smoothed)):
smoothed[i]=sum(numpy.array(list[i:i+window])*weight)/sum(weight)
return smoothed
image_file = 'verypurple.jpg'
out_file = 'out.tiff'
image = Image.open(image_file).convert('1')
image2 = image.load()
image.save(out_file)
intensities = []
for x in xrange(image.size[0]):
intensities.append([])
for y in xrange(image.size[1]):
intensities[x].append(image2[x, y] )
plot = []
for x in xrange(image.size[0]):
plot.append(0)
for y in xrange(image.size[1]):
plot[x] += intensities[x][y]
plot = smoothListGaussian(plot, 10)
plot_str = ''
for x in range(len(plot)):
plot_str += str(plot[x]) + "\n"
print(plot_str)
Solución
Veo que está utilizando numpy. Me gustaría convertir la imagen en escala de grises a una matriz numpy en primer lugar, a continuación, utilizar numpy para resumir lo largo de un eje. Bono:. Es probable que encuentres a su función de suavizado corre mucho más rápido cuando se arregle para aceptar una serie 1D como entrada
>>> from PIL import Image
>>> import numpy as np
>>> i = Image.open(r'C:\Pictures\pics\test.png')
>>> a = np.array(i.convert('L'))
>>> a.shape
(2000, 2000)
>>> b = a.sum(0) # or 1 depending on the axis you want to sum across
>>> b.shape
(2000,)
Otros consejos
la documentación para PIL , histogram
le da una lista de número de píxeles para cada valor de píxel de la imagen. Si usted tiene una imagen de escala de grises, habrá 256 valores diferentes posibles, que van de 0 a 255, y la lista de regresar de image.histogram
tendrá 256 entradas.