更新:原始问题的表述有点不清楚。我不仅要裁剪图像,还要在补丁提取过程中应用 双线性插值 。 (请参见下面的论文参考)。这就是为什么该算法比仅获取切片要复杂得多的原因。
我正在尝试训练一种深度学习模型来预测this paper之后的人脸特征。我需要将包含面部的图像部分裁剪为面部标志周围的小块。例如,如果我们有下面显示的图像:
该函数应生成N=15
个“补丁”,每个界标一个补丁:
我在torch
张量的基础上建立了以下朴素的实现:
def generate_patch(x, y, w, h, image):
c = image.size(0)
patch = torch.zeros((c, h, w), dtype=image.dtype)
for q in range(h):
for p in range(w):
yq = y + q - (h - 1)/2
xp = x + p - (w - 1)/2
xd = 1 - (xp - math.floor(xp))
xu = 1 - (math.ceil(xp) - xp)
yd = 1 - (yq - math.floor(yq))
yu = 1 - (math.ceil(yq) - yq)
for idx in range(c):
patch[idx, q, p] = (
image[idx, math.floor(yq), math.floor(xp)]*yd*xd +
image[idx, math.floor(yq), math.ceil(xp)]*yd*xu +
image[idx, math.ceil(yq), math.floor(xp)]*yu*xd +
image[idx, math.ceil(yq), math.ceil(xp)]*yu*xu
).item()
return patch
def generate_patches(image, points, n=None, sz=31):
if n is None:
n = len(points)//2
patches = []
for i in range(n):
x_val, y_val = points[i], points[i + n]
patch = generate_patch(x_val, y_val, sz, sz, image)
patches.append(patch)
return patches
代码可以正常工作,但速度太慢。我猜是因为所有这些for循环和单独的像素索引。我想将这些代码向量化,或者找到一些基于C的实现,可以更快地实现。
我知道sklearn
包中有一个extract_patches_2d
函数,该函数有助于从图像中选择随机色块。但是,我想从特定点中选择补丁,而不是随机进行。我想我可以以某种方式改编上述功能,或将上面显示的实现转换为Cython / C代码,但可能有人以前已经做过类似的事情。
能否请您提供一些替代上面显示的代码的建议,或者就如何使其更快地提出建议? (除了使用多个并行工作器之外。)
答案 0 :(得分:1)
1)使用numpy
2)选择带有索引提取的补丁。示例:
Patch=img[0:100,0:100]
3)创建3维物体,其中3维物体是补丁。 [15x15x补丁数]
4)进行双线性整型。使用numpy同时处理所有色块(以一个像素为例,使用第3维的所有像素进行计算)。
这将使您的处理工作超出您的想象力
如果您不想变老等待工作完成,请忘记数学模块。它在数据科学中没有地位。