我编写了一个处理图像的函数,其中提取了许多补丁,然后使用相同的函数(func)处理它们以生成新图像。但是,由于两个循环,函数,补丁数量,补丁大小,这非常慢。我不知道该如何加速这段代码。
功能如下。
# 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
func可能非常灵活且耗时。我举一个例子。 下面的函数要计算补丁的中心点除补丁的中间值。但是,我不希望那些值为255的像素计算中值(255是无效像素的默认值)。所以我在numpy中使用蒙版数组。掩码数组会使代码运行速度降低数倍,而且我不知道如何对其进行优化。
# 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)
我尝试过的想法:
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慢。(谁能告诉我为什么会这样吗?)# 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
除了func之外,此操作有点像卷积或过滤器。我不知道那些lib如何处理这个问题,你们能给我一些线索吗?
在这种情况下我们可以避免两个循环吗?也许这可以加速代码。
我有GPU。我可以更改代码以在gpus上运行并使其并行处理补丁以使其更快吗?
将代码更改为C。这是我想做的最后一件事,因为这可能有点混乱。
你们能给我一些想法或建议吗?
答案 0 :(得分:0)
如果您的计算机具有多个CPU,则可以通过将其提交到ThreadPoolExecutor
您的代码应如下所示:
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 >