【问题标题】:Python Image distortionPython图像失真
【发布时间】:2014-02-21 17:17:45
【问题描述】:

我正在尝试对 python 中的图像应用波纹效果。 我找到了 Pillow 的 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.. 使用以下代码,我得到了我想要的失真,但是 colors 搞砸了。 也许我必须将失真应用到 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()

【问题讨论】:

    标签: python numpy pillow


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      你为什么不试试类似的东西:

      # 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。但我认为总的来说这应该可行。

      【讨论】:

      • 为什么import 行被评论了?
      【解决方案3】:

      我遇到了类似的问题,在此处尝试建议的解决方案时,在应用 sin 后,有时颜色看起来很乱(出现一些奇怪的红线)。无法解决。

      我知道如果可能的话,原始发布者不想要更多的依赖项,但对于那些不受限制的,这里是 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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多