如何(快速)从2d图像的特定点提取双线性插值斑块?

时间:2019-01-29 12:40:44

标签: python deep-learning regression pytorch

  

更新:原始问题的表述有点不清楚。我不仅要裁剪图像,还要在补丁提取过程中应用 双线性插值 。 (请参见下面的论文参考)。这就是为什么该算法比仅获取切片要复杂得多的原因。


我正在尝试训练一种深度学习模型来预测this paper之后的人脸特征。我需要将包含面部的图像部分裁剪为面部标志周围的小块。例如,如果我们有下面显示的图像:

enter image description here

该函数应生成N=15个“补丁”,每个界标一个补丁:

enter image description here

我在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代码,但可能有人以前已经做过类似的事情。

能否请您提供一些替代上面显示的代码的建议,或者就如何使其更快地提出建议? (除了使用多个并行工作器之外。)

1 个答案:

答案 0 :(得分:1)

1)使用numpy

2)选择带有索引提取的补丁。示例:

Patch=img[0:100,0:100]

3)创建3维物体,其中3维物体是补丁。 [15x15x补丁数]

4)进行双线性整型。使用numpy同时处理所有色块(以一个像素为例,使用第3维的所有像素进行计算)。

这将使您的处理工作超出您的想象力

如果您不想变老等待工作完成,请忘记数学模块。它在数据科学中没有地位。