如何在Python中将图像分割成多个片段

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Python中将图像分割成多个片段相关的知识,希望对你有一定的参考价值。

我正在尝试使用PIL将照片分成多个部分。

def crop(Path,input,height,width,i,k,x,y,page):
    im = Image.open(input)
    imgwidth = im.size[0]
    imgheight = im.size[1]
    for i in range(0,imgheight-height/2,height-2):
        print i
        for j in range(0,imgwidth-width/2,width-2):
            print j
            box = (j, i, j+width, i+height)
            a = im.crop(box)
            a.save(os.path.join(Path,"PNG","%s" % page,"IMG-%s.png" % k))
            k +=1

但它似乎没有起作用。它会分割照片但不是精确的方式(你可以尝试)。

答案
from PIL import Image

def crop(path, input, height, width, k, page, area):
    im = Image.open(input)
    imgwidth, imgheight = im.size
    for i in range(0,imgheight,height):
        for j in range(0,imgwidth,width):
            box = (j, i, j+width, i+height)
            a = im.crop(box)
            try:
                o = a.crop(area)
                o.save(os.path.join(path,"PNG","%s" % page,"IMG-%s.png" % k))
            except:
                pass
            k +=1
另一答案

编辑:我相信这个答案错过了将图像切割成列和行的矩形的意图。这个答案只能分成几行。它看起来像列和行中的其他答案。

比所有这些更简单的是使用其他人发明的轮子:)它可能更多涉及设置,但是它很容易使用。

这些说明适用于Windows 7;它们可能需要适应其他操作系统。

here获取并安装点子。

下载安装存档,并将其解压缩到根Python安装目录。打开控制台并键入(如果我没记错的话):

python get-pip.py install

然后通过在控制台输入以下命令,通过pip获取并安装image_slicer模块:

python -m pip install image_slicer

将要切片的图像复制到Python根目录中,打开python shell(不是“命令行”),然后输入以下命令:

import image_slicer
image_slicer.slice('huge_test_image.png', 14)

这个模块的美妙之处在于它

  1. 安装在python中
  2. 可以使用两行代码调用图像分割
  3. 接受任何偶数作为图像切片参数(例如,在此示例中为14)
  4. 获取该参数并自动将给定图像拆分为如此多的切片,并将结果编号的切片自动保存在同一目录中,最后
  5. 具有将图像拼接在一起的功能(我还没有测试过);文件显然必须按照您在测试image_slicer.slice函数后在拆分文件中看到的约定命名。
另一答案

将图像分割为MxN像素的图块(假设im为numpy.ndarray):

tiles = [im[x:x+M,y:y+N] for x in range(0,im.shape[0],M) for y in range(0,im.shape[1],N)]

如果您想将图像拆分为四个部分:

M = im.shape[0]//2
N = im.shape[1]//2

tiles [0]保持左上方的tile

另一答案
  1. 如果将裁剪代码与图像保存代码分开,crop将是一个更可重用的函数。它还可以使呼叫签名更简单。
  2. im.crop返回一个Image._ImageCrop实例。此类实例没有保存方法。相反,您必须将Image._ImageCrop实例粘贴到新的Image.Image
  3. 您的范围没有正确的步长。 (为什么height-2而不是height?例如。为什么要停在imgheight-(height/2)?)。

所以,你可能会尝试这样的事情:

import Image
import os

def crop(infile,height,width):
    im = Image.open(infile)
    imgwidth, imgheight = im.size
    for i in range(imgheight//height):
        for j in range(imgwidth//width):
            box = (j*width, i*height, (j+1)*width, (i+1)*height)
            yield im.crop(box)

if __name__=='__main__':
    infile=...
    height=...
    width=...
    start_num=...
    for k,piece in enumerate(crop(infile,height,width),start_num):
        img=Image.new('RGB', (height,width), 255)
        img.paste(piece)
        path=os.path.join('/tmp',"IMG-%s.png" % k)
        img.save(path)
另一答案

这是一个简洁,纯粹的python解决方案,适用于python 3和2:

from PIL import Image

infile = '20190206-135938.1273.Easy8thRunnersHopefully.jpg'
chopsize = 300

img = Image.open(infile)
width, height = img.size

# Save Chops of original image
for x0 in range(0, width, chopsize):
   for y0 in range(0, height, chopsize):
      box = (x0, y0,
             x0+chopsize if x0+chopsize <  width else  width - 1,
             y0+chopsize if y0+chopsize < height else height - 1)
      print('%s %s' % (infile, box))
      img.crop(box).save('zchop.%s.x%03d.y%03d.jpg' % (infile.replace('.jpg',''), x0, y0))

笔记:

  • 超过原始图像右侧和底部的裁剪将调整为原始图像限制并仅包含原始像素。
  • 通过使用两个chopsize变量并在上面的代码中适当地替换chopsize,很容易为w和h选择不同的chopsize。
  • 另一答案

    这是我的脚本工具,将css-split图像拆分为图标非常简单:

    Usage: split_icons.py img dst_path width height
    Example: python split_icons.py icon-48.png gtliu 48 48
    

    将代码保存到split_icons.py中:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import os
    import sys
    import glob
    from PIL import Image
    
    def Usage():
        print '%s img dst_path width height' % (sys.argv[0])
        sys.exit(1)
    
    if len(sys.argv) != 5:
        Usage()
    
    src_img = sys.argv[1]
    dst_path = sys.argv[2]
    
    if not os.path.exists(sys.argv[2]) or not os.path.isfile(sys.argv[1]):
        print 'Not exists', sys.argv[2], sys.argv[1]
        sys.exit(1)
    
    w, h = int(sys.argv[3]), int(sys.argv[4])
    im = Image.open(src_img)
    im_w, im_h = im.size
    print 'Image width:%d height:%d  will split into (%d %d) ' % (im_w, im_h, w, h)
    w_num, h_num = int(im_w/w), int(im_h/h)
    
    for wi in range(0, w_num):
        for hi in range(0, h_num):
            box = (wi*w, hi*h, (wi+1)*w, (hi+1)*h)
            piece = im.crop(box)
            tmp_img = Image.new('L', (w, h), 255)
            tmp_img.paste(piece)
            img_path = os.path.join(dst_path, "%d_%d.png" % (wi, hi))
            tmp_img.save(img_path)
    
    另一答案

    我觉得skimage.util.view_as_windows或`skimage.util.view_as_blocks更容易,它也允许你配置步骤

    http://scikit-image.org/docs/dev/api/skimage.util.html?highlight=view_as_windows#skimage.util.view_as_windows

    以上是关于如何在Python中将图像分割成多个片段的主要内容,如果未能解决你的问题,请参考以下文章

    如何从 RCNN 中裁剪分割的对象?

    通过 BPM 将音轨分割成片段,并使用 Superpowered iOS 分析每个片段

    在 Python 多处理进程中运行较慢的 OpenCV 代码片段

    毕业了,在Python中使用 OpenCV 和K-Means 聚类对毕业照进行图像分割

    毕业了,在Python中使用 OpenCV 和K-Means 聚类对毕业照进行图像分割

    计算机视觉常用算法讲解