Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python图像库将一个图像剪切为多个图像_Python_Image Manipulation_Python Imaging Library_Image Segmentation - Fatal编程技术网

使用Python图像库将一个图像剪切为多个图像

使用Python图像库将一个图像剪切为多个图像,python,image-manipulation,python-imaging-library,image-segmentation,Python,Image Manipulation,Python Imaging Library,Image Segmentation,我需要使用PIL将这张图片分成三部分,然后选择中间部分。 我该怎么做 看看PIL的crop()方法 (需要了解图像的边界框…假设图像每天具有相同的尺寸,您应该能够确定一次边界框并一直使用它) 加载图像 知道尺寸了吗 使用该方法 保存中间图像 对于这个特定的图像,您可以这样做 import Image i = Image.open('dt110507dhct.jpg') frame2 = i.crop(((275, 0, 528, 250))) frame2.save('dt110507dhct

我需要使用PIL将这张图片分成三部分,然后选择中间部分。 我该怎么做

看看PIL的crop()方法

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

  • 加载图像
  • 知道尺寸了吗
  • 使用该方法
  • 保存中间图像

  • 对于这个特定的图像,您可以这样做

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

    如果之前不知道长方体,我会在图像(x和y方向)上运行一个简单的边缘查找过滤器来查找长方体的边界

    一个简单的方法是:

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

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

    说你有这样一张很长的照片

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

    下面是一个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)
    
    这是输出



    我想投票表决解决方案,但缺乏足够的声誉。然而,我想我会发布我根据他的答案开发的代码,以防它可能对其他人有所帮助。我还添加了遍历文件结构和选择图像宽度的功能

    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)
    
    导入图像
    导入操作系统
    #设置根目录
    rootdir='path/to/your/file/directory'
    def long_切片(图像路径、输出名称、输出目录、切片高度、切片宽度):
    img=图像。打开(图像路径)#加载图像
    imageWidth,imageHeight=img.size#获取图像尺寸
    左=0#设置最左边的边
    上部=0#设置最顶部边缘
    而(左<图像宽度):
    而(上部<图像高度):
    #如果裁剪框的底部和右侧超出图像范围。
    如果(上+切片高度>图像高度)和\
    左+切片宽度>图像宽度):
    bbox=(左、上、图像宽度、图像高度)
    #如果裁剪框右侧超出图像范围
    elif(左+切片宽度>图像宽度):
    bbox=(左、上、图像宽度、上+切片高度)
    #如果裁剪框底部超出图像范围
    elif(上部+切片高度>图像高度):
    bbox=(左、上、左+切片宽度、图像高度)
    #如果整个裁剪框位于图像内,
    #正常进行。
    其他:
    bbox=(左、上、左+切片宽度、上+切片高度)
    工作_slice=img.crop(bbox)#基于创建的边界裁剪图像
    #保存新裁剪的图像。
    工作\u slice.save(os.path.join(outdir,'slice\u'+out\u name+\
    “'+str(上)+”'+str(左)+'.jpg'))
    上+=切片高度#增加水平位置
    左+=切片宽度#增加垂直位置
    上限=0
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    #遍历一组目录中的所有文件。
    对于os.walk(rootdir)中的subdir、dir和文件:
    对于文件中的文件:
    长_切片(subdir+'/'+文件'longcat',subdir,128,128)
    
    我需要将其自动化,有时线条是手工绘制的,但肯定有线条。你的回答很好,但我想知道你是否有任何代码片段可以发布在这里?或者链接到这样做的站点?每个盒子(子图像)的大小可能不是固定的,所以自动检测盒子是我要找的吗?我想给一个任何大小的图像,在它的框,并得到个人的图像。因此,算法必须在找到垂直线和水平线时做出最佳猜测。谢谢,对不起,我没有任何代码。但是,似乎PIL已经具备了所需的功能:我猜这个页面上的FIND_EDGES过滤器会很有用。不幸的是,这似乎可以同时得到X和Y的边。但是您可以定义自己的过滤器内核。对于水平try[-1,0,1],对于垂直try,相同,但作为列向量而不是行向量。