繁体   English   中英

翻转图像/镜像

[英]Flipping image / mirror Image

我需要编写一个获取图像并返回镜像的函数(Y坐标永远不变),而无需使用PIL的任何镜像或翻转模块。
我必须自己写。 我收到一条错误消息:

IndexError: image index out of range

我在这里想念什么?

谢谢。

from os.path import exists
import tkMessageBox, tkFileDialog
from PIL import Image, ImageTk, ImageFilter

def flip(im):
    '''Flips a picutre horizontally, and returns a new image that is a mirror view of the original'''
    org=Image.open(im)
    new=Image.new("RGB",org.size)   
    for x in range(org.size[0]):
        a=org.size[0]
        for y in range(org.size[1]):
            pixel=org.getpixel((x,y))
            new.putpixel((a,y),pixel)
            a-=1
    new.save("new.bmp","bmp")

使用ImageOps.mirror(image)水平翻转图像。

import Image
import ImageOps

img = Image.open(FILENAME)
mirror_img = ImageOps.mirror(img)

您的代码非常接近工作。 您有一个“ off-by-one”错误。

a=org.size[0]
...
new.putpixel((a,y),pixel)

假设org宽度为100像素。 然后,第一次通过循环将像素放置在(100,y) 但是像素的索引范围是0--99。 这就是为什么(以及在何处)出现IndexError: image index out of range异常的原因。


另外,请注意循环中要初始化和递减a 其实,我也不会建议使用a在所有。

而是使用

w,h = org.size
for x in range(w):
    for y in range(h):
        pixel = org.getpixel((x, y))
        new.putpixel(EXPRESSION, pixel)

然后将EXPRESSION替换为您要着色的像素位置的一些公式。

您正在混合基于0和1的索引。 x范围是0org.size[0]-1 a范围从org.size[0]1 ,因为你开始与a=org.size[0]并使用,如果没有第1减法运算。

错误最有可能来自此行内的某个地方:

new.putpixel((a,y),pixel)

…在您的第一个电话上,当您尝试在仅以(0-279,0-279)运行的图像中写入像素(280,0)时。

因此,代替此:

for x in range(org.size[0]):
    a=org.size[0]
    for y in range(org.size[1]):
        pixel=org.getpixel((x,y))
        new.putpixel((a,y),pixel)
        a-=1

做这个:

for x in range(org.size[0]):
    a=org.size[0]-1
    for y in range(org.size[1]):
        pixel=org.getpixel((x,y))
        new.putpixel((a,y),pixel)
        a-=1

但是,一旦解决此问题,就会遇到另一个问题。 每次通过外循环而不是第一次都将org.size[0]设置a 然后,您每次通过内循环而不是外循环递减a 因此,您将最终将原始图像中的每一行复制到从(279,0)到(0,279)的对角线。

因此,您需要这样做:

a=org.size[0]-1
for x in range(org.size[0]):
    for y in range(org.size[1]):
        pixel=org.getpixel((x,y))
        new.putpixel((a,y),pixel)
    a-=1

正是这种原因,您应该避免像这样手动修改索引。 您第一次尝试就永远做不到。 在第三次尝试中,您会得到看起来不错的东西,但是当您尝试测试套件中没有的第一个映像时,它就会崩溃。 最好计算这些值,而不是倒数。 例如:

for x in range(org.size[0]):
    flipped_x = org.size[0] - x - 1
    for y in range(org.size[1]):
        pixel=org.getpixel((x,y))
        new.putpixel((flipped_x,y),pixel)

在此过程中,如果您可以要求/依赖PIL 1.1.6或更高版本,则使用Image.load()返回的数组会明显更简单,更高效且通常更容易调试:

orgpixels, newpixels = org.load(), new.load()
for x in range(org.size[0]):
    flipped_x = org.size[0] - x - 1
    for y in range(org.size[1]):
        pixel=orgpixels[x, y]
        newpixels[flipped_x, y] = pixel

如果您不能依靠1.1.6,则可以使用getdata获取一个可迭代的像素序列,使用它来生成新的list或其他序列(这意味着您可以使用列表推导, map ,甚至将它们输入numpy通过例如np.array(org.getdata()).reshape(org.size) ),然后使用putdata从结果中创建新图像。

当然, getdataputdata处理一维序列,而您希望将其视为2D序列。 幸运的是, grouper在功能itertools文档,您可以复制和粘贴,或者只是pip install more-itertool通常-is正是你想要的:

orgrows = more_itertools.grouper(org.size[0], org.getdata())
newrows = [list(reversed(row)) for row in orgrows]
new.putdata(newrows)

要注意的一件事是Image.open(im)不一定会在RGB模式下返回图像。 如果仅将像素从XYZ或P图像复制到RGB,最终将导致变色的垃圾或仅出现红色通道。 您可能要print org.mode ,并可能要print org.pixel((0, 0))以确保它实际上具有3个通道(它们看起来像RGB)`。

最简单的方法是在执行其他任何操作之前先转换org

org=Image.open(im).convert('RGB')

当然,某些格式要么没有直接转换,要么需要显式的矩阵或调色板。 如果出现ValueError ,则必须阅读有关转换输入类型的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM