【问题标题】:How to vectorize tasks in python?如何在python中对任务进行矢量化?
【发布时间】:2019-10-28 23:18:37
【问题描述】:

我(将)有一个坐标列表;使用 python 的枕头模块,我想将一系列(裁剪的)较小的图像保存到磁盘。目前,我正在使用 for 循环来一次确定一个坐标,然后在继续下一个坐标之前裁剪/保存图像。

有没有办法分割这项工作,以便同时裁剪/保存多个图像?我知道这会占用更多 RAM,但会缩短性能时间。

我确定这是可能的,但我不确定这是否简单。我听说过像“矢量化”和“多线程”这样的术语听起来有点适合这种情况。但这些话题超出了我的经验范围。

我已附上代码以供参考。但是,我只是想征求推荐的策略。 (即我应该学习哪些技术来更好地调整我的方法,一次采取多种作物等?)


def parse_image(source, square_size, count, captures, offset=0, offset_type=0, print_coords=False):
    """
    Starts at top left corner of image. Iterates through image by square_size (width = height)
    across x values and after exhausting the row, begins next row lower by function of 
    square_size. Offset parameter is available such that, with multiple function calls, 
    overlapping images could be generated.
    """
    src = Image.open(source)
    dimensions = src.size
    max_down = int(src.height/square_size) * square_size + square_size
    max_right = int(src.width/square_size) * square_size + square_size

    if offset_type == 1:
        tl_x = 0 + offset
        tl_y = 0
        br_x = square_size + offset 
        br_y = square_size

        for y in range(square_size,max_down,square_size):
            for x in range(square_size + offset,max_right - offset,square_size):
                if (tl_x,tl_y) not in captures:
                    sample = src.crop((tl_x,tl_y,br_x,br_y))
                    sample.save(f"{source[:-4]}_sample_{count}_x{tl_x}_y{tl_y}.jpg")
                    captures.append((tl_x,tl_y))

                    if print_coords == True: 
                        print(f"image {count}: top-left (x,y): {(tl_x,tl_y)}, bottom-right (x,y): {(br_x,br_y)}")
                    tl_x = x
                    br_x = x + square_size
                    count +=1                
                else:
                    continue
            tl_x = 0 + offset
            br_x = square_size + offset
            tl_y = y
            br_y = y + square_size
    else:
        tl_x = 0
        tl_y = 0 + offset
        br_x = square_size 
        br_y = square_size + offset

        for y in range(square_size + offset,max_down - offset,square_size):
            for x in range(square_size,max_right,square_size):
                if (tl_x,tl_y) not in captures:
                    sample = src.crop((tl_x,tl_y,br_x,br_y))
                    sample.save(f"{source[:-4]}_sample_{count}_x{tl_x}_y{tl_y}.jpg")
                    captures.append((tl_x,tl_y))

                    if print_coords == True: 
                        print(f"image {count}: top-left (x,y): {(tl_x,tl_y)}, bottom-right (x,y): {(br_x,br_y)}")
                    tl_x = x
                    br_x = x + square_size
                    count +=1
                else:
                    continue
            tl_x = 0
            br_x = square_size 
            tl_y = y + offset
            br_y = y + square_size + offset
    return count

【问题讨论】:

    标签: python multithreading vectorization


    【解决方案1】:

    你在这里想要实现的是更高程度的并行性,首先要做的是了解你在这里需要做的最小任务是什么,然后思考如何更好地分配它.

    这里首先要注意的是有两种行为,第一种如果您有 offset_type 0,另一种如果您有 offset_type 1,则将其拆分为两个不同的函数。

    第二件事是:给定一张图片,您将在给定的偏移量(x,y) 处对整个图片进行给定大小的裁剪。例如,在给定图像偏移量 (x,y) 的情况下,您可以简化此函数以裁剪图像。然后,您可以为图像的所有 x 和 y 并行调用此函数。这几乎是大多数图像处理框架试图实现的目标,甚至是在 GPU 内运行代码的框架,即在图像中本地运行的小代码块。

    假设您的图像的宽度=100,高度=100,并且您正在尝试裁剪 w=10,h=10。鉴于我描述的简单功能,我将其称为crop(img, x, y, crop_size_x, crop_size_y) 您所要做的就是创建图像:

    img = Image.open(source)
    crop_size_x = 10
    crop_size_y = 10
    crops = [crop(img, x, y, crop_size_x, crop_size_y) for x, y in zip(range(img.width), range(img.height))]
    

    稍后,您可以将列表推导替换为 multi_processing 库,该库实际上可以产生许多进程,进行真正的并行处理,甚至在 GPU 内核/着色器中编写此类代码,并使用 GPU 并行处理来实现高性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多