如何获得针对x的不同值进行不同计算的函数?

时间:2019-07-18 07:41:59

标签: image-processing halide


    Func support("support");

    Expr left_x = clamp(x, 0, left_buffer.width() / 4);
    RDom scan_left(0, left_buffer.width() / 4, 0, left_buffer.height());
    scan_left.where(scan_left.x != left_x && scan_left.y != y);
    support(x, y) = argmin(abs(output_x(left_x, y) - output_x(scan_left.x, scan_left.y)) + abs(output_y(left_x, y) - output_y(scan_left.x, scan_left.y)));

    Expr center_x = clamp(x, left_buffer.width() / 4, left_buffer.width() * 3/4);
    RDom scan_center(-left_buffer.width() / 4, left_buffer.width() / 2, 0, left_buffer.height());
    scan_center.where(scan_center.x != 0 && scan_center.y != 0);
    support(x, y) = argmin(abs(output_x(center_x, y) - output_x(center_x + scan_center.x, scan_center.y)) + abs(output_y(center_x, scan_center.y) - output_y(center_x + scan_center.x, scan_center.y)));

    Expr right_x = clamp(x, left_buffer.width() * 3/4, left_buffer.width());
    RDom scan_right(left_buffer.width() * 3/4, left_buffer.width() / 4, 0, left_buffer.height());
    scan_right.where(scan_right.x != right_x && scan_right.y != y);
    support(x, y) = argmin(abs(output_x(right_x, y) - output_x(scan_right.x, scan_right.y)) + abs(output_y(right_x, y) - output_y(scan_right.x, scan_right.y)));

    support.trace_stores();

    Realization r = support.realize(left_buffer.width(), left_buffer.height());

函数“ support”的计算应取决于x值。对于x = [0,width / 4],请根据第一个定义进行计算;对于x = [width / 4,width * 3/4],请根据第二个定义进行计算,对于x = [width * 3/4] ,width]根据第三个定义进行计算。我认为将边界条件与这些更新定义相关联,然后在整个缓冲区上实现将可以解决问题。但是,现在,以前的定义已被覆盖。既然这似乎行不通,我想考虑做三个实现,但是由于我们只讨论一个图像,所以这似乎很微不足道。是否可以在一个实现中实现结果,还是必须分为三个实现? 我也尝试过RDoms:

Func support("support");
    support(x, y) = Tuple(i32(0), i32(0), f32(0));

    RDom left_x(0, left_buffer.width() / 4);
    RDom scan_left(0, left_buffer.width() / 4, 0, left_buffer.height());
    scan_left.where(scan_left.x != left_x && scan_left.y != y);
    support(left_x, y) = argmin(scan_left, abs(output_x(left_x, y) - output_x(scan_left.x, scan_left.y)) + abs(output_y(left_x, y) - output_y(scan_left.x, scan_left.y)));

    RDom center_x(left_buffer.width() / 4, left_buffer.width() / 2);
    RDom scan_center(-left_buffer.width() / 4, left_buffer.width() / 2, 0, left_buffer.height());
    scan_center.where(scan_center.x != 0 && scan_center.y != 0);
    support(center_x, y) = argmin(scan_center, abs(output_x(center_x, y) - \
    output_x(center_x + scan_center.x, scan_center.y)) + abs(output_y(center_x, scan_center.y) - \
    output_y(center_x + scan_center.x, scan_center.y)));

    RDom right_x(left_buffer.width() * 3/4, left_buffer.width() / 4);
    RDom scan_right(left_buffer.width() * 3/4, left_buffer.width() / 4, 0, left_buffer.height());
    scan_right.where(scan_right.x != right_x && scan_right.y != y);
    support(right_x, y) = argmin(scan_right, abs(output_x(right_x, y) - output_x(scan_right.x, scan_right.y)) + abs(output_y(right_x, y) - output_y(scan_right.x, scan_right.y)));

    support.compute_root();
    support.trace_stores();

    Realization r_left = support.realize(left_buffer.width(), left_buffer.height());

但是此代码在以下几行中给出错误:

scan_left.where(scan_left.x != left_x && scan_left.y != y);
...
scan_right.where(scan_right.x != right_x && scan_right.y != y);

1 个答案:

答案 0 :(得分:0)

解决此问题的一种简单方法是使用Halide的select方法(给定示例here)。这样的事情应该起作用:

Func support("support");

Expr left_x = clamp(x, 0, left_buffer.width() / 4);
RDom scan_left(0, left_buffer.width() / 4, 0, left_buffer.height());
scan_left.where(scan_left.x != left_x && scan_left.y != y);
Expr first = argmin(abs(output_x(left_x, y) - output_x(scan_left.x, scan_left.y)) + abs(output_y(left_x, y) - output_y(scan_left.x, scan_left.y)));

Expr center_x = clamp(x, left_buffer.width() / 4, left_buffer.width() * 3/4);
RDom scan_center(-left_buffer.width() / 4, left_buffer.width() / 2, 0, left_buffer.height());
scan_center.where(scan_center.x != 0 && scan_center.y != 0);
Expr second = argmin(abs(output_x(center_x, y) - output_x(center_x + scan_center.x, scan_center.y)) + abs(output_y(center_x, scan_center.y) - output_y(center_x + scan_center.x, scan_center.y)));

Expr right_x = clamp(x, left_buffer.width() * 3/4, left_buffer.width());
RDom scan_right(left_buffer.width() * 3/4, left_buffer.width() / 4, 0, left_buffer.height());
scan_right.where(scan_right.x != right_x && scan_right.y != y);
Expr third = argmin(abs(output_x(right_x, y) - output_x(scan_right.x, scan_right.y)) + abs(output_y(right_x, y) - output_y(scan_right.x, scan_right.y)));

int width = left_buffer.width();
# select based on x value
support(x, y) = select(x < width / 4, first, x < width * 3 / 4, second, third);

support.trace_stores();

Realization r = support.realize(left_buffer.width(), left_buffer.height());

`