Искажение изображения Python

Я пытаюсь применить волновой эффект к изображению в python. Я нашел подушку im.transform(im.size, Image.MESH,.... это возможно? Может быть, мне нужно загрузить изображение с помощью numpy и применить алгоритм. Я также нашел это: http://www.pygame.org/project-Water+Ripples-1239-.html

рябь

другой способ вручную, но я не знаю никакого алгоритма. это мой старт. это ничего не делает...

    #!/usr/bin/env python3

    from PIL import Image
    import sys
    import numpy
    import math

    im = Image.open(sys.argv[1])
    im.show()

    matrix = numpy.asarray(im)
    width = im.size[0]
    height = im.size[1]
    amplitude = ? # parameters
    frequency = ?
    matrix_dest = numpy.zeros((im.size[0],im.size[1],3))

    for x in range(0, width):
        for y in range(0, height):
            pass # ç_ç

    im2 = Image.fromarray(numpy.uint8(matrix_dest))
    im2.show()

ИЗМЕНИТЬ:

Я бы очень хотел сохранить эту структуру (используя подушку. Я уже широко использую в своем проекте, и если бы я мог, я бы не добавлял никакой другой зависимости) и не включая scipi или matplotlib. Со следующим кодом у меня есть искажение, которое я хотел, но цвета испорчены. Возможно, мне нужно применить искажение к плоскостям R, G, B, а затем скомпоновать результат в одно изображение. Или подберите палитру к изображению, а затем примените исходную палитру.

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

im = Image.open(sys.argv[1])
im.show()

m = numpy.asarray(im)
m2 = numpy.zeros((im.size[0],im.size[1],3))
width = im.size[0]
height = im.size[1]

A = m.shape[0] / 3.0
w = 1.0 / m.shape[1]

shift = lambda x: A * numpy.sin(2.0*numpy.pi*x * w)

for i in range(m.shape[0]):
    print(int(shift(i)))
    m2[:,i] = numpy.roll(m[:,i], int(shift(i)))

im2 = Image.fromarray(numpy.uint8(m2))
im2.show()

person hexec    schedule 21.02.2014    source источник


Ответы (3)


Вы можете использовать np.roll для поворота каждой строки или столбца в соответствии с некоторой синусоидальной функцией.

from scipy.misc import lena
import numpy as np
import matplotlib.pyplot as plt

img = lena()

A = img.shape[0] / 3.0
w = 2.0 / img.shape[1]

shift = lambda x: A * np.sin(2.0*np.pi*x * w)

for i in range(img.shape[0]):
    img[:,i] = np.roll(img[:,i], int(shift(i)))

plt.imshow(img, cmap=plt.cm.gray)
plt.show()

введите здесь описание изображения

person M4rtini    schedule 21.02.2014

Почему бы вам не попробовать что-то вроде:

# import scipy
# import numpy as np
for x in range(cols):
    column = im[:,x]
    y = np.floor(sin(x)*10)+10
    kernel = np.zeros((20,1))
    kernel[y] = 1
    scipy.ndimage.filters.convolve(col,kernel,'nearest')

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

person wbest    schedule 21.02.2014
comment
Почему строки import закомментированы? - person Palbitt; 31.08.2020

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

Я понимаю, что исходный постер не хочет больше зависимостей, если это возможно, но для тех, у кого нет ограничений, вот альтернативный образец решения, предоставленный scikit docs:

http://scikit-image.org/docs/dev/auto_examples/transform/plot_piecewise_affine.html#sphx-glr-auto-examples-transform-plot-piecewise-affine-py

Копирование из документа выше:

import numpy as np
import matplotlib.pyplot as plt
from skimage.transform import PiecewiseAffineTransform, warp
from skimage import data


image = data.astronaut()
rows, cols = image.shape[0], image.shape[1]

src_cols = np.linspace(0, cols, 20)
src_rows = np.linspace(0, rows, 10)
src_rows, src_cols = np.meshgrid(src_rows, src_cols)
src = np.dstack([src_cols.flat, src_rows.flat])[0]

# add sinusoidal oscillation to row coordinates
dst_rows = src[:, 1] - np.sin(np.linspace(0, 3 * np.pi, src.shape[0])) * 50
dst_cols = src[:, 0]
dst_rows *= 1.5
dst_rows -= 1.5 * 50
dst = np.vstack([dst_cols, dst_rows]).T


tform = PiecewiseAffineTransform()
tform.estimate(src, dst)

out_rows = image.shape[0] - 1.5 * 50
out_cols = cols
out = warp(image, tform, output_shape=(out_rows, out_cols))

fig, ax = plt.subplots()
ax.imshow(out)
ax.plot(tform.inverse(src)[:, 0], tform.inverse(src)[:, 1], '.b')
ax.axis((0, out_cols, out_rows, 0))
plt.show()
person Dean Liu    schedule 05.12.2016