卤化物中的可变域减少

时间:2015-04-14 22:07:19

标签: c++ variables range halide

现在我正在尝试编写一些对图像进行二次采样的Halide代码。基本上我希望每2平方2的图像缩小到一个包含最大值的像素。一个简单的例子就是改造

1 2 3 4
5 6 7 8
9 0 1 2
4 3 5 6

6 8
9 6

现在我正在尝试一些事情(我知道这会给出总和而不是最大值,但它是同一过程的玩具示例):

Halide::Image<uint8_t> input = load<uint8_t>("test.png");        
Halide::Image<uint8_t> output(input.width() / 2, input.height() / 2, input.channels());

 Halide::Func subsample;
 Halide::Var c;

 for (int i = 0; i < input.height(); i += 2) {
     for (int j = 0; j < input.width(); j += 2) {
         Halide::RDom r = Halide::RDom(i, 2, j, 2);
         subsample(i, j, c) += input(r.x, r.y, c);
     }
 }

 subsample.realize(output);
 save(output, "test.png");

但是,此代码无限运行。 (我不确定为什么)。我知道我可以使用Halide :: RDom来表示某个范围内的reduce操作。但是,在任何示例中,我都发现您可以将变量传递给随机域对象。

编辑:

在与Halide一起玩之后,我能够构建这个:

subsample(x, y, c) = Halide::max(input(2*x,2*y,c),input(2*x+1,2*y,c));
subsample(x, y, c) = Halide::max(subsample(x,y,c),input(2*x,2*y+1,c));
subsample(x, y, c) = Halide::max(subsample(x,y,c),input(2*x+1,2*y+1,c));

最多减少2x2。但是,当我把它放在一个循环中时,它不会被调用,因为它无法定义。无论如何,这是在域名减少方面吗?

3 个答案:

答案 0 :(得分:2)

我认为argmax(嵌入的Halide函数)可以用于你想要的东西:)

#include "Halide.h"
#include <stdio.h>

uint8_t data[16] = {
    1, 2, 3, 4,
    5, 6, 7, 8,
    9, 0, 1, 2,
    3, 4, 5, 6
};

using namespace Halide;

int main(int argc, char** argv) {
    Halide::Image<uint8_t> input(4, 4); 
    for(int j = 0; j < 4; j++) {
        for(int i = 0; i < 4; i++) {
            input(j, i) = data[j*4 + i];
        }
    }

    Halide::Func f, max2x2;
    Halide::Var x, y, dx, dy;
    Halide::Expr x_ = x * 2;
    Halide::Expr y_ = y * 2;

    f(x, y, dx, dy) = input(x_ + dx, y_ + dy);

    RDom r(0, 2, 0, 2);
    max2x2(x, y) = argmax(f(x, y, r.x, r.y))[2];

    Halide::Image<uint8_t> output(2, 2);
    max2x2.realize(output);

    for(int j = 0; j < 2; j++) {
        for(int i = 0; i < 2; i++) {
            printf("%d ", output(j, i));
        }
        printf("\n");
    }
    return 0;
}

答案 1 :(得分:1)

在深入了解Halide之后,我意识到我可以得到我想要的东西:

Halide::Func subsample;
Halide::Var x, y, c;

Halide::RDom r(0, size, 0, size);

subsample(x, y, c) = input(size * x, size * y, c);
subsample(x, y, c) = Halide::max(input(size*x + r.x, size*y + r.y, c), 
    subsample(x,y,c));

答案 2 :(得分:0)

我认为你只是想要一个更简单的纯函数定义(没有C ++循环,它没有做我认为你期望他们做的事情......;没有RDoms):

// using Halide::max
subsample(x,y,c) = max( max( input(2*x,2*y  ), input(2*x+1,2*y  ) ),
                        max( input(2*x,2*y+1), input(2*x+1,2*y+1) ) );