使用 Python 图像库将一张图像切割成多张图像

Posted

技术标签:

【中文标题】使用 Python 图像库将一张图像切割成多张图像【英文标题】:Cutting one image into multiple images using the Python Image Library 【发布时间】:2011-05-19 13:14:04 【问题描述】:

我需要使用 PIL 将此图像切成三部分并选择中间部分。 我该怎么做?

http://thedilbertstore.com/images/periodic_content/dilbert/dt110507dhct.jpg

【问题讨论】:

【参考方案1】:

假设你有这样一张很长的照片。

现在你想把它切成更小的垂直位,因为它太长了。

这是一个可以执行此操作的 Python 脚本。这对我为 LaTeX 文档准备很长的图像很有用。

from __future__ import division
import Image
import math
import os

def long_slice(image_path, out_name, outdir, slice_size):
    """slice an image into parts slice_size tall"""
    img = Image.open(image_path)
    width, height = img.size
    upper = 0
    left = 0
    slices = int(math.ceil(height/slice_size))

    count = 1
    for slice in range(slices):
        #if we are at the end, set the lower bound to be the bottom of the image
        if count == slices:
            lower = height
        else:
            lower = int(count * slice_size)  
        #set the bounding box! The important bit     
        bbox = (left, upper, width, lower)
        working_slice = img.crop(bbox)
        upper += slice_size
        #save the slice
        working_slice.save(os.path.join(outdir, "slice_" + out_name + "_" + str(count)+".png"))
        count +=1

if __name__ == '__main__':
    #slice_size is the max height of the slices in pixels
    long_slice("longcat.jpg","longcat", os.getcwd(), 300)

这是输出



【讨论】:

【参考方案2】:

我想对Gourneau's 解决方案进行投票,但缺乏足够的声誉。但是,我想我会发布我根据他的回答开发的代码,以防万一它可能对其他人有帮助。我还添加了遍历文件结构并选择图像宽度的功能。

import Image
import os

# Set the root directory
rootdir = 'path/to/your/file/directory'

def long_slice(image_path, out_name, outdir, sliceHeight, sliceWidth):
    img = Image.open(image_path) # Load image
    imageWidth, imageHeight = img.size # Get image dimensions
    left = 0 # Set the left-most edge
    upper = 0 # Set the top-most edge
    while (left < imageWidth):
        while (upper < imageHeight):
            # If the bottom and right of the cropping box overruns the image.
            if (upper + sliceHeight > imageHeight and \
                left + sliceWidth > imageWidth):
                bbox = (left, upper, imageWidth, imageHeight)
            # If the right of the cropping box overruns the image
            elif (left + sliceWidth > imageWidth):
                bbox = (left, upper, imageWidth, upper + sliceHeight)
            # If the bottom of the cropping box overruns the image
            elif (upper + sliceHeight > imageHeight):
                bbox = (left, upper, left + sliceWidth, imageHeight)
            # If the entire cropping box is inside the image,
            # proceed normally.
            else:
                bbox = (left, upper, left + sliceWidth, upper + sliceHeight)
            working_slice = img.crop(bbox) # Crop image based on created bounds
            # Save your new cropped image.
            working_slice.save(os.path.join(outdir, 'slice_' + out_name + \
                '_' + str(upper) + '_' + str(left) + '.jpg'))
            upper += sliceHeight # Increment the horizontal position
        left += sliceWidth # Increment the vertical position
        upper = 0

if __name__ == '__main__':
    # Iterate through all the files in a set of directories.
    for subdir, dirs, files in os.walk(rootdir):
        for file in files:
            long_slice(subdir + '/' + file, 'longcat', subdir, 128, 128)

【讨论】:

【参考方案3】:

对于这个特定的图像,你会这样做

import Image
i = Image.open('dt110507dhct.jpg')
frame2 = i.crop(((275, 0, 528, 250)))
frame2.save('dt110507dhct_frame2.jpg')

【讨论】:

【参考方案4】:

如果事先不知道这些框,我会在图像上运行一个简单的边缘寻找过滤器(x 和 y 方向)以找到框的边界。

一个简单的方法是:

    对图像运行水平边缘过滤器。您现在有一个图像,其中每个像素都描述了该像素左右强度的变化。 IE。它会“找到”垂直线。 对于水平边缘图像中的每一列,获取其行的平均绝对幅度。在生成的 1 x WIDTH 大小的数组中,您会在最高值的位置找到垂直线。由于线条的宽度超过 1 个像素,因此您可能需要稍微聪明一点。 对另一个轴执行相同操作以找到水平线。

如果您认为框的边框将始终为黑色,则可以通过首先仅提取黑色(或接近黑色)的像素来进行一些预处理。但我怀疑是否有必要,因为上述方法应该非常稳定。

【讨论】:

我需要自动化这个,有时线条是手绘的,但肯定有线条。您的回答很好,但我想知道您是否有任何 sn-p 代码可以在这里发布?或链接到完成此操作的站点?每个盒子(子图像)的大小可能不固定,所以自动检测盒子是我要找的吗?我想提供任何大小的图像,其中包含框并获取单个图像。所以算法必须在找到垂直、水平线时做出最好的猜测。谢谢一堆。 抱歉,我没有任何代码。但似乎 PIL 有什么需要:我猜这个页面上的 FIND_EDGES 过滤器pythonware.com/library/pil/handbook/imagefilter.htm 会很有用。不幸的是,这似乎可以同时获得 X 和 Y 的边缘。但是您可以定义自己的过滤器内核。对于水平尝试 [-1, 0, 1] 和对于垂直,相同但作为列向量而不是行向量。【参考方案5】:

看一下PIL的crop()方法

http://effbot.org/imagingbook/image.htm

(需要了解图像的边界框...假设图像每天都具有相同的尺寸,您应该能够确定边界框一次并一直使用它)。

【讨论】:

【参考方案6】:
    加载图片 获取大小 使用Crop 方法 保存中间图片

【讨论】:

以上是关于使用 Python 图像库将一张图像切割成多张图像的主要内容,如果未能解决你的问题,请参考以下文章

用MATLAB将一幅图分割成4*3的小块该怎么做呢?

利用matlab将一张图片分割成10×10的小图片,求程序!

使用 PHP GD 将一张图像与另一张图像屏蔽

如何使用 CameraX 拍摄多张图像?

ImageMagick:将一张图像的 4 个边缘并排合成到另一张图像中

将一张图片分割成多张小图片 Python3