简体   繁体   English

如何(快速)从特定点的二维图像中提取双线性插值块?

[英]How to (quickly) extract bilinear-interpolated patches from a 2d image at specific points?

Update: The original question formulation was a bit unclear.更新:最初的问题表述有点不清楚。 I am not just cropping the image but applying bilinear interpolation during the patches extraction process.我不只是裁剪图像,而是在补丁提取过程中应用双线性插值 (See the paper reference below). (请参阅下面的论文参考)。 That's why the algorithm is a bit more involved than just taking slices.这就是为什么该算法比仅仅切片更复杂的原因。


I am trying to train a deep learning model to predict face landmarks following this paper .我想培养一个深度学习模型来预测下脸地标本文 I need to crop parts of the image that contains face into smaller patches around facial landmarks.我需要将包含面部的图像部分裁剪成面部标志周围的小块。 For example, if we have the image shown below:例如,如果我们有如下所示的图像:

在此处输入图片说明

The function should generate N=15 "patches", one patch per landmark:该函数应生成N=15 “补丁”,每个地标一个补丁:

在此处输入图片说明

I have the following naïve implementation build on top of torch tensors:我在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

The code does its work but too slowly.代码完成了它的工作,但速度太慢了。 I guess because of all these for-loops and separate pixels indexing.我猜是因为所有这些 for 循环和单独的像素索引。 I would like to vectorize this code, or maybe find some C-based implementation that could do it faster.我想对这段代码进行矢量化,或者找到一些可以更快完成的基于 C 的实现。

I know there is the extract_patches_2d function from sklearn package that helps to pick random patches from the image.我知道sklearn包中的extract_patches_2d函数有助于从图像中选择随机补丁。 However, I would like to pick the patches from specific points instead of doing it randomly.但是,我想从特定点挑选补丁而不是随机进行。 I guess that I can somehow adapt the aforementioned function, or convert the implementation shown above into Cython/C code but probably someone has already done something like this before.我想我可以以某种方式调整上述函数,或者将上面显示的实现转换为 Cython/C 代码,但可能有人以前已经做过这样的事情。

Could you please advise some alternative to the code shown above, or maybe a proposal on how to make it faster?您能否为上面显示的代码提供一些替代方案,或者关于如何使其更快的建议? (Except using several parallel workers). (除了使用多个并行工作器)。

1) use numpy 1) 使用 numpy

2) select patches with index extraction. 2)选择带有索引提取的补丁。 Example:例子:

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

3) create 3 dimensional body where in 3rd dimension are patches. 3)创建3维身体,其中第3维是补丁。 [15x15xnumber of patches] [15x15x补丁数量]

4) do your bilinear int. 4)做你的双线性整数。 With numpy for all patches in the same time( insted of one pixel calculate with all pixels in 3rd dimension).同时对所有补丁使用 numpy(插入一个像素计算第 3 维中的所有像素)。

That will increase your processing beyond your imagination这将增加您超出您想象的处理能力

If you dont want to get old waiting for your job to be done forget math module.如果您不想在等待工作完成时变老,请忘记数学模块。 It has no place in datascience.它在数据科学中没有立足之地。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM