Придание рельефности изображения в Python с PIL — добавляющая глубина, азимут, и т.д.

Я пытаюсь придать рельефность изображению с помощью PIL.

PIL обеспечивает основной способ придать рельефность изображению (использование ImageFilter.EMBOSS).

В пакетах редактирования изображение как GIMP можно варьироваться параметры как Азимут, глубина и повышение в этом рельефном изображении.

Как сделать это с PIL? По крайней мере я хочу скорректировать "глубину" рельефного изображения.

Обновление: Я попробовал вещи, предложенные Paul (изменяющий filterargsтакой как scale, offset и матрица), но я не мог изменить воздействие "глубины". Так все еще поиск ответа.

Вот сравнение придания рельефности эффекту с помощью PIL (слева) и GIMP (справа). Исходное изображение расположено здесь, http://www.linuxtopia.org/online_books/graphics_tools/gimp_advanced_guide/gimp_guide_node74.html.

alt text

6
задан Community 8 February 2017 в 14:19
поделиться

2 ответа

Если вы не можете достичь своей цели с помощью или комбинации операций (например, вращение, затем применение фильтра EMBOSS, повторное вращение) (или увеличение контраста с последующим тиснением), вы можете прибегнуть к изменению (или созданию собственного ) матрица фильтра.

В ImageFilter.py вы найдете этот класс:

##
# Embossing filter.

class EMBOSS(BuiltinFilter):
    name = "Emboss"
    filterargs = (3, 3), 1, 128, (
        -1,  0,  0,
        0,  1,  0,
        0,  0,  0
        )

Размещение -1 в другом углу матрицы изменит азимут и сделает его -2 может иметь желаемый эффект. за.

Матрица применяется попиксельно. Каждый элемент в матрице соответствует текущему пикселю и окружающим пикселям; центральное значение, представляющее текущий пиксель. Новый преобразованный текущий пиксель будет создан как комбинация всех 9 пикселей, взвешенных по значениям в матрице. Например, матрица со всеми нулями и единицей в центре не изменит изображения.

Дополнительные параметры: масштаб и смещение . Для встроенного EMBOSS значения: 1 (масштаб) и 128 (смещение). Их изменение изменит общую силу результата.

Из ImageFilter.py:

# @keyparam scale Scale factor.  If given, the result for each
#    pixel is divided by this value.  The default is the sum
#    of the kernel weights.
# @keyparam offset Offset.  If given, this value is added to the
#    result, after it has been divided by the scale factor.

Поскольку я не знаком с эффектами параметра «глубина» GIMP, я не могу сказать, какой из них, скорее всего, сделает то, что вы хотите.

Вы также можете сделать матрицу другого размера. Замените (3,3) на (5,5), а затем создайте матрицу из 25 элементов.

Чтобы внести временные изменения в фильтр без повторного сохранения исходного кода, просто сделайте следующее:

ImageFilter.EMBOSS.filterargs=((3, 3), 1, 128, (-1, 0, 0, 0, 1, 0, 0, 0, 0))

Изменить: (используя подход NumPy )

from PIL import Image
import numpy

# defining azimuth, elevation, and depth
ele = numpy.pi/2.2 # radians
azi = numpy.pi/4.  # radians
dep = 10.          # (0-100)

# get a B&W version of the image
img = Image.open('daisy.jpg').convert('L') 
# get an array
a = numpy.asarray(img).astype('float')
# find the gradient
grad = numpy.gradient(a)
# (it is two arrays: grad_x and grad_y)
grad_x, grad_y = grad
# getting the unit incident ray
gd = numpy.cos(ele) # length of projection of ray on ground plane
dx = gd*numpy.cos(azi)
dy = gd*numpy.sin(azi)
dz = numpy.sin(ele)
# adjusting the gradient by the "depth" factor
# (I think this is how GIMP defines it)
grad_x = grad_x*dep/100.
grad_y = grad_y*dep/100.
# finding the unit normal vectors for the image
leng = numpy.sqrt(grad_x**2 + grad_y**2 + 1.)
uni_x = grad_x/leng
uni_y = grad_y/leng
uni_z = 1./leng
# take the dot product
a2 = 255*(dx*uni_x + dy*uni_y + dz*uni_z)
# avoid overflow
a2 = a2.clip(0,255)
# you must convert back to uint8 /before/ converting to an image
img2 = Image.fromarray(a2.astype('uint8')) 
img2.save('daisy2.png')

Надеюсь, это поможет. Теперь я понимаю, почему вы были разочарованы результатами PIL. Wolfram Mathworld - хороший ресурс для переподготовки векторной алгебры.

До

alt text

После

alt text

8
ответ дан 10 December 2019 в 00:39
поделиться

Открытый источник выключенного двигателя Правила полки может быть полным переутомлением для вашего приложения, я использовал слюни раньше, и он довольно тяжеловес, вам также нужно будет понять структуру, прежде чем использовать ее - с помощью слюни, это не так уж плохо , но может быть более уместно написать свой собственный двигатель DSL-правила в чем-то вроде Scala / Groovy / JRuby.

Здесь есть интересная статья, которая говорит о создании движнения правил на основе Groovy:

http://www.pleus.net/articles/grules/grules.pdf

Работайте, что подходит вам наилучшим образом из этих вариантов И пойти оттуда.

-121--4244725-

Для увеличения глубины фильтра тиснения увеличивают радиус маски фильтра. Низкая глубина:

h = [[1, 0, 0]
     [0, 0, 0]
     [0, 0, -1]]

по сравнению с высокой глубиной:

h = [[1, 0, 0, 0, 0, 0, 0]
     [0, 0, 0, 0, 0, 0, 0]
     [0, 0, 0, 0, 0, 0, 0]
     [0, 0, 0, 0, 0, 0, 0]
     [0, 0, 0, 0, 0, 0, 0]
     [0, 0, 0, 0, 0, 0, 0]
     [0, 0, 0, 0, 0, 0, -1]]

Чтобы изменить азимут, поместите ненулевые коэффициенты под другим углом:

h = [[0, 0, 1]
     [0, 0, 0]
     [-1, 0, 0]]

Я не совсем уверен в возвышении. Вам может потребоваться изменить ненулевые значения коэффициента? Я просто знаю, что это должно быть высокопроходным фильтром.

В любом случае, для вычисления и отображения изображения с помощью Scipy Solution:

import scipy.misc, scipy.signal
im = scipy.misc.imread(filename)
im_out = scipy.signal.convolve2d(im, h, 'same')
scipy.misc.imshow(im_out)

Надеюсь, это поможет.

Редактировать: Хорошо, как Пол намекнул с PIL, вы можете настроить параметры фильтра или даже определить совершенно новое ядро. Параметры масштаба и смещения не имеют ничего общего с тем, что вы ищете. Размер фильтра наиболее важен для регулировки глубины.

При дальнейшем исследовании PIL не позволяет изменять размер фильтра за 5х5. Кажется странным. Поэтому вы не получите глубину не так драматично, как вы, вероятно, ожидаете.

Для полного контроля вы можете попробовать Scipy Solution I и Павел упомянул ранее. Измените размер фильтра до чего-то смешного, как 21x21, и посмотрите, делает ли он разницу, которую вы хотите.

2
ответ дан 10 December 2019 в 00:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: