PIL: Создать одномерную гистограмму яркости цвета изображения?

Я работаю над сценарием, и мне это нужно в основном:

  • Сделайте изображение в оттенках серого (или двухтональным, я поиграю с обоими, чтобы увидеть, какой из них работает лучше).
  • Обработайте каждый отдельный столбец и создайте чистое значение интенсивности для каждого столбца.
  • Выплевывайте результаты в упорядоченный список.

Есть очень простой способ сделать это с помощью ImageMagick (хотя вам нужно несколько утилит Linux для обработки выходного текста), но я не очень понимаю, как это сделать с помощью Python и PIL.

Вот что у меня есть до сих пор:

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)

Это что-то выводит (я хочу представить результаты в виде графика), но это не похоже на вывод ImageMagick. Я использую это, чтобы обнаружить шов и содержание отсканированной книги.

Спасибо всем, кто помогает!


У меня есть (неприятно выглядящее) решение, которое работает на данный момент:

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)

person Blender    schedule 15.11.2010    source источник
comment
3D, можете ли вы показать пример вывода, который вы ищете?   -  person Jason Sundram    schedule 15.11.2010


Ответы (2)


Я вижу, вы используете numpy. Я бы сначала преобразовал изображение в оттенках серого в массив numpy, а затем использовал numpy для суммирования по оси. Бонус: вы, вероятно, обнаружите, что ваша функция сглаживания работает намного быстрее, если вы настроите ее так, чтобы она принимала одномерный массив в качестве входных данных.

>>> 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,)
person Paul    schedule 16.11.2010
comment
ДА! Это именно то, что мне нужно! :D - person Blender; 17.11.2010

Из документов по PIL histogram дает вам список количества пикселей для каждого значения пикселя в изображении. Если у вас есть изображение в градациях серого, будет 256 различных возможных значений в диапазоне от 0 до 255, а список, возвращенный из image.histogram, будет содержать 256 записей.

person Jason Sundram    schedule 15.11.2010
comment
Кажется, я перепутал гистограмму с чем-то другим... Она дает мне правильный результат, но это не совсем то, что мне нужно. Я хотел иметь в основном список яркости (или интенсивности, я не знаком с этой терминологией) для каждого вертикального столбца пикселей в изображении. Гистограмма просто показывает, сколько пикселей попадает в какой цветовой диапазон. - person Blender; 15.11.2010
comment
Разработчики PIL перенесли эту ссылку на документацию сюда. - person Lloyd MacLea; 08.05.2017