Python图像失真

时间:2014-02-21 17:17:45

标签: python numpy pillow

我正在尝试对python中的图像应用涟漪效果。 我找到了Pillow的im.transform(im.size,Image.MESH,......有可能吗? 也许我必须用numpy加载图像并应用算法。 我也发现了这个:http://www.pygame.org/project-Water+Ripples-1239-.html

ripple

手动另一种方式,但我不知道任何算法。这是我的开始。它没有做任何事......

    #!/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平面,然后将结果组合在一个图像中。 或调色图像,然后应用原始调色板。

(顺便说一下,图像将用作纹理,以在3D环境中显示移动的水。)

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()

3 个答案:

答案 0 :(得分:7)

您可以使用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()

enter image description here

答案 1 :(得分:4)

你为什么不尝试这样的事情:

# 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')

我现在把它扔到一起,所以你需要稍微调整一下。罪的频率肯定太高,请检查here。但我认为总的来说这应该有用。

答案 2 :(得分:0)

我遇到了类似的问题,在尝试这里提出的解决方案时,在应用罪之后,有时颜色似乎弄乱了(得到一些奇怪的红线)。无法解决它。

据我所知,如果可能的话,原始海报不希望有更多的依赖关系,但对于那些不受限制的海报,这里是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()