使用python为图像添加边框

Nih*_*ngi 32 python image image-processing

我有大量固定大小的图像(比如说500*500).我想编写一个python脚本,将它们调整为固定大小(比如800*800),但会将原始图像保持在中心,并用固定颜色(比如黑色)填充多余区域.

我正在使用PIL.我现在可以使用该resize功能调整图像大小,但这会改变宽高比.有没有办法做到这一点?

hel*_*ker 46

您可以使用所需的新尺寸创建新图像,并将旧图像粘贴到中心,然后保存.如果需要,可以覆盖原始图像(确定吗?; o)

import Image

old_im = Image.open('someimage.jpg')
old_size = old_im.size

new_size = (800, 800)
new_im = Image.new("RGB", new_size)   ## luckily, this is already black!
new_im.paste(old_im, ((new_size[0]-old_size[0])/2,
                      (new_size[1]-old_size[1])/2))

new_im.show()
# new_im.save('someimage.jpg')
Run Code Online (Sandbox Code Playgroud)


Igo*_*bin 36

就在这里.

做这样的事情:

import Image, ImageOps
ImageOps.expand(Image.open('original-image.png'),border=300,fill='black').save('imaged-with-border.png')
Run Code Online (Sandbox Code Playgroud)

你可以在几行写下相同的内容:

import Image, ImageOps
img = Image.open('original-image.png')
img_with_border = ImageOps.expand(img,border=300,fill='black')
img_with_border.save('imaged-with-border.png')
Run Code Online (Sandbox Code Playgroud)

而且你说你有一个图像列表.然后你必须使用一个循环来处理所有这些:

import Image, ImageOps
for i in list-of-images:
  img = Image.open(i)
  img_with_border = ImageOps.expand(img,border=300,fill='black')
  img_with_border.save('bordered-%s' % i)
Run Code Online (Sandbox Code Playgroud)

  • 好的找到了解决方法,`ImageOps.expand(Image.open('original-image.png'),border =(300,500),fill ='black').save('imaged-with-border.png')` (4认同)
  • 有趣.是否可以为上下左右选择不同的边框,因此新的图像尺寸可以是参数,而不是边框​​尺寸? (2认同)
  • ImageOps.expand 似乎在大多数情况下都可以工作,尽管它在处理大图像(5500x5500 像素)时给我带来了麻烦。出于某种原因,图像显示为灰度,而在较小图像上运行的完全相同的代码可以完美运行。鉴于此,我在下面发布了一个关于使用 Image.crop 的答案,它似乎没有相同的限制/错误。 (2认同)

pir*_*irt 9

或者,如果您使用的是OpenCV,它们会调用一个函数copyMakeBorder,允许您向图像的任何一侧添加填充.除了纯色之外,它们还为花式边框提供了一些很酷的选择,例如反射或扩展图像.

import cv2

img = cv2.imread('image.jpg')

color = [101, 52, 152] # 'cause purple!

# border widths; I set them all to 150
top, bottom, left, right = [150]*4

img_with_border = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
Run Code Online (Sandbox Code Playgroud)

cv2.copyMakeBorder函数的示例结果

来源:OpenCV边界教程用于copyMakeBorder的OpenCV 3.1.0文档

  • 我认为你应该在定义`value = color`之前添加`cv2.BORDER_CONSTANT`,如http://docs.opencv.org/3.1.0/d3/df2/tutorial_py_basic_ops.html (3认同)

kev*_*cke 5

PIL 的方法实际上可以通过使用原始图像边界框之外的数字来为您处理这个问题,尽管文档crop中没有明确说明。左侧和顶部的负数将为这些边缘添加黑色像素,而右侧和底部大于原始宽度和高度的数字将为这些边缘添加黑色像素。

此代码考虑了奇数像素大小:

from PIL import Image

with Image.open('/path/to/image.gif') as im:
    old_size = im.size
    new_size = (800, 800)

    if new_size > old_size:
        # Set number of pixels to expand to the left, top, right,
        # and bottom, making sure to account for even or odd numbers
        if old_size[0] % 2 == 0:
            add_left = add_right = (new_size[0] - old_size[0]) // 2
        else:
            add_left = (new_size[0] - old_size[0]) // 2
            add_right = ((new_size[0] - old_size[0]) // 2) + 1

        if old_size[1] % 2 == 0:
            add_top = add_bottom = (new_size[1] - old_size[1]) // 2
        else:
            add_top = (new_size[1] - old_size[1]) // 2
            add_bottom = ((new_size[1] - old_size[1]) // 2) + 1

        left = 0 - add_left
        top = 0 - add_top
        right = old_size[0] + add_right
        bottom = old_size[1] + add_bottom

        # By default, the added pixels are black
        im = im.crop((left, top, right, bottom))
Run Code Online (Sandbox Code Playgroud)

您可以使用 2 元组在左/右和上/下添加相同数量的像素,或者使用 1 元组向所有边添加相同数量的像素,而不是 4 元组。