使用pypng在Python中水平翻转图像

0 投票
2 回答
2653 浏览
提问于 2025-04-17 04:50

我正在尝试用Python和PyPNG把一张图片水平翻转(从左到右),我写了以下代码,但好像不太管用,有谁知道我哪里出错了吗?

def horizontal_flip(image):
    rows = len(image)
    cols = len(image[0])
    new_image = []
    for r in range(rows):
        new_row = []
        for c in range(0,cols,3):
            if c != cols/2:
                image[c:c+3], image[-c-3: -c] = image[-c-3: -c], image[c:c+3]
                new_row.append(image[r][c])
        new_image.append(new_row)
    return new_image

2 个回答

0

你内层循环的逻辑有问题,特别是这一行:

image[c:c+3], image[-c-3: -c] = image[-c-3: -c], image[c:c+3]

你在直接修改 image 这个变量,但似乎忘了行变量 r。现在你是在改变行。而且你的负切片有点问题。对于 c=0,你会得到 image[-3:0],这不是一个有效的切片,会返回 []

不过从你的代码来看,你并不想直接修改 image,你其实是想创建一个 new_image。你应该做的是把切片插入到 new_row 的末尾:

def horizontal_flip(image):
    rows = len(image)
    cols = len(image[0])
    new_image = []
    for r in range(rows):
        new_row = []
        for c in range(0,cols,3):
            new_row = image[r][c:c+3] + new_row
        new_image.append(new_row)
    return new_image

顺便说一下,你也可以直接修改 image,但要小心。因为你传递的是一个 list,在修改之前应该先复制一份,这样原来的数据才不会改变。这是那个版本:

def horizontal_flip(image):
    cols = len(image[0])/3

    #make a copy so that original image is not altered
    image = [row[:] for row in image]

    for row in image:
        for c in range(int(cols/2)): # int() is not needed for Python 2.x, since integer division yields integer
                                     # This also takes care of odd n cases, middle chunk is not changed.
            row[3*c:3*c+3], row[3*(cols-c-1):3*(cols-c-1)+3] = row[3*(cols-c-1):3*(cols-c-1)+3], row[3*c:3*c+3]

    return image

这也可以用列表推导式在一行内完成,但可读性会差一些。如果你想的话,这里有一种做法:

from itertools import chain
flipped_image = [list(chain(*[row[3*i:3*i+3] for i in range(len(image[0])/3-1,-1,-1)])) for row in image]
0

new_row.append(image[r][c])放到if外面去。

另外,你把图片水平翻转了两次……可以把你的循环改成range(0,cols/2,3)。这样可能也就不需要那个if了。

你还在原地修改原始图片;你确定要这样做吗?

看起来一个更简单的办法是反向遍历每一行,然后把它们加到新图片的行里。

撰写回答