首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何加速处理图像中的大量补丁?

如何加速处理图像中的大量补丁?
EN

Stack Overflow用户
提问于 2019-07-19 02:47:22
回答 1查看 602关注 0票数 1

我编写了一个处理图像的函数,在该函数中我提取了许多补丁,然后使用相同的函数(Func)处理它们以生成新的图像。但是,这是非常缓慢的,因为两个循环,func,补丁的数量,补丁的大小。我不知道该如何加速这段代码。

功能如下所示。

代码语言:javascript
运行
复制
# code1
def filter(img, func, ksize, strides=1):
    height,width = img.shape
    f_height,f_width = ksize
    new_height = height - f_height + 1
    new_width = width - f_width + 1

    new_img = np.zeros((new_height,new_width))

    for i in range(new_height):
        for j in range(new_width):
            patch = img[i:i+f_height,j:j+f_width]
            new_img[i][j] = func(patch)

    return new_img

功能可以非常灵活和耗时。我以一个为例。下面的函数要计算贴片中值的中心点。但是,我不希望那些值为255的像素计算中位数(255是无效像素的默认值)。所以我在numpy中使用了蒙面数组。蒙面数组使代码慢了好几次,我不知道如何优化它。

代码语言:javascript
运行
复制
# code2
def relative_median_and_center_diff(patch, in_the_boundary, rectangle, center_point):
        mask = patch == 255
        mask[center_point] = True
        masked_patch = np.ma.array(patch, mask=mask)
        count = masked_patch.count()
        if count <= 1:
            return 0
        else:
            return patch[center_point]/(np.ma.median(masked_patch)+1)

我尝试过或得到过的想法:

  1. 我在循环之前使用了一些numpy函数来提取补丁,希望这比patch = img[i:i+f_height,j:j+f_width]更快。我找到了从Extracting patches of a certain size from the image in python efficiently中提取补丁的函数,一开始我尝试了从skimage.util.shape中提取view_as_windows。代码被更改如下所示。这比code1花费更多的时间。我还尝试了sklearn.feature_extraction.image.extract_patches_2d,发现这比code3快,但仍然比code1慢。(有人能告诉我为什么会这样吗?)
代码语言:javascript
运行
复制
# code3
def filter(img, func, ksize, strides=1):
    height,width = img.shape
    f_height,f_width = ksize
    new_height = height - f_height + 1
    new_width = width - f_width + 1

    new_img = np.zeros((new_height,new_width))

    from skimage.util.shape import view_as_windows
    patches = view_as_windows(img, (f_height,f_width))

    for i in range(new_height):
        for j in range(new_width):
            patch = patches[i,j]
            new_img[i][j] = func(patch)

    return new_img
  1. 这一操作有点像卷积或滤波,除了功能。我不知道他们怎么处理这件事,你们能给我一些线索吗?
  2. 在这种情况下,我们能避免两个循环吗?也许这能加速密码。
  3. 我有gpus。我是否可以更改代码以在gpus上运行,并使其并行处理补丁以使其更快?
  4. 将代码更改为C,这是我最不想做的事情,因为这可能有点混乱。

你们能给我一些想法或建议吗?

EN

回答 1

Stack Overflow用户

发布于 2019-07-19 05:33:02

如果您的计算机有多个CPU,则可以通过将进程提交到ThreadPoolExecutor来多线程该进程。

您的代码应该如下所示:

代码语言:javascript
运行
复制
from concurrent.futures import ThreadPoolExecutor
from multiprocessing import cpu_count()

executor = ThreadPoolExecutor(max_workers=cpu_count())
future = executor.submit(func, data, *args)
future_to_item[future] = data

for future in concurrent.futures.as_completed(future_to_item):
    # do something when you get the result

我一直使用ThreadPoolExecutor进行图像处理。

由于我们只有函数,而且不知道程序(完全)是如何工作的,所以检查一下Python中的并发性,这样您就可以更好地了解如何将其集成到代码中:https://docs.python.org/3/library/concurrent.futures.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57104880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档