Какой самый эффективный способ вычислить режим в скользящем окне над двумерным массивом в Python? - PullRequest
2 голосов
/ 10 февраля 2012

У меня есть изображение RGBA, которое мне нужно масштабировать, сохраняя при этом гладкость.

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

Таким образом, чтобы получить плавные края, я надеялся увеличить масштаб, используя ближайшего соседа (давая мне схемы лестниц), а затем закруглить края, заменив каждый пиксель в целевом изображении на цвет пикселя, который встречается чаще всего.в пределах определенного радиуса, например:

from PIL import Image, ImageFilter
amount=3
image=Image.open(<file>)
image=image.filter(ImageFilter.ModeFilter(amount))

Это заканчивается довольно быстро, за исключением того, что он не работает, поскольку ImageFilters PIL работают отдельно на каждом канале. Встряхивает кулак

Я попытался прибегнуть к массиву numpy и сделать в цикле следующее:

dest[x,y]=Counter([tuple(e) for e in reshape(source[max(x-r,0):x+r+1,max(y-r,0):y+r+1],(-1,4))]).most_common()[0][0]

Обратите внимание, что dest и source здесь - это одинаковые массивы XxYx4,следовательно, необходимо преобразовать и преобразовать в кортежи.
Теоретически это будет работать, но потребуется 12 часов, чтобы закончить для 82 миллионов пикселей изображения, над которым я работаю.Я делаю вывод, что это в основном из-за ненужных накладных расходов с приведением и изменением формы.

Каков будет подходящий способ сделать это в Python?

Я готов поднять руки и написать модуль C ++, чтобы выполнить эту задачу.
Все, что отвлечет меня от этого пути, будет высоко ценится!

Ответы [ 2 ]

1 голос
/ 10 февраля 2012

Если вы заботитесь о фиксированном наборе цветов в вашем изображении, режим изображения «Палитра», возможно, будет более подходящим (по крайней мере, если на вашей карте не более 256 цветов).

Я бы предложил сначала преобразовать ваше изображение в режим «P» (поскольку я не очень знаком с PIL, я не уверен, насколько это просто. Возможно, вам сначала придется явно построить палитру?), а затем примените фильтр режима.

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

0 голосов
/ 13 февраля 2012

EPX, описанный в Image_scaling , не вводит новых цветов.Шкала 2x делает это:

  A    --\ 1 2
C P B  --/ 3 4
  D 

IF C==A => 1=A
IF A==B => 2=B
...

и там также описывается шкала 3x.
Кроме того, я бы согласился с «перейти прямо к C» - зависит от того, что вы знаете.Кто-нибудь использовал np_inline ?

...