使用python向图像添加边框
image
image-processing
python
5
0

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

我正在使用PIL。我现在可以使用resize功能调整图像的resize ,但这会改变纵横比。有什么办法吗?

参考资料:
Stack Overflow
收藏
评论
共 6 个回答
高赞 时间 活跃

您可以使用scipy.misc.imread将图像scipy.misc.imread为numpy数组。然后使用numpy.zeros((height, width, channels))创建一个具有所需背景的数组,并将图像粘贴到所需位置:

import numpy as np
import scipy.misc

im = scipy.misc.imread('foo.jpg', mode='RGB')
height, width, channels = im.shape

# make canvas
im_bg = np.zeros((height, width, channels))
im_bg = (im_bg + 1) * 255  # e.g., make it white

# Your work: Compute where it should be
pad_left = ...
pad_top = ...

im_bg[pad_top:pad_top + height,
      pad_left:pad_left + width,
      :] = im
# im_bg is now the image with the background.
收藏
评论

您可以创建具有所需新尺寸的新图像,然后将旧图像粘贴到中间,然后保存。如果需要,可以覆盖原始图像(确定吗?

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')
收藏
评论

或者,如果您使用的是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)

cv2.copyMakeBorder函数的示例结果

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

收藏
评论

在这里考虑旧维度,新维度及其差异非常重要。如果差异是奇数(不是偶数),则需要为左,上,右边框指定略有不同的值。

假设旧尺寸为ow,oh,新尺寸为nw,nh。因此,这将是答案:

import Image, ImageOps
img = Image.open('original-image.png')
deltaw=nw-ow
deltah=nh-oh
ltrb_border=(deltaw/2,deltah/2,deltaw-(deltaw/2),deltah-(deltah/2))
img_with_border = ImageOps.expand(img,border=ltrb_border,fill='black')
img_with_border.save('imaged-with-border.png')
收藏
评论

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

您可以使用2个元组在左侧/右侧和顶部/底部添加相同数量的像素,而不是4个元组,或者使用1个元组在所有侧面添加相同数量的像素。

收藏
评论

就在这里。

做这样的事情:

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

您可以在以下几行中编写相同的代码:

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

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

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)
收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号