积分图像框过滤

时间:2016-06-03 13:25:10

标签: image filtering box halide

我试图将Halide中的2通道可分离方法与基于积分图像的盒式滤波方法进行比较,以更好地理解Halide调度。我在Halide中找不到任何积分图像创建的例子,其中积分图像函数用于定义后续函数。

ImageParam input(type_of<uint8_t>(), 3, "image 1");

Var x("x"), y("y"), c("c"), xi("xi"), yi("yi");

Func ip("ip");

ip(x, y, c) = cast<float>(BoundaryConditions::repeat_edge(input)(x, y, c));

Param<int> radius("radius", 15, 1, 50);

RDom imageDomain(input);
RDom r(-radius, radius, -radius, radius);

// Make an integral image
Func integralImage = ip;
integralImage(x, imageDomain.y, c) += integralImage(x, imageDomain.y - 1, c);
integralImage(imageDomain.x, y, c) += integralImage(imageDomain.x - 1, y, c);

integralImage.compute_root(); // Come up with a better schedule for this

// Apply box filter to integral image
Func outputImage;

outputImage(x,y,c) = integralImage(x+radius,y+radius,c)
                + integralImage(x-radius,y-radius,c)
                - integralImage(x-radius,y+radius,c)
                - integralImage(x-radius,y+radius,c);

Expr normFactor = (2*radius+1) * (2*radius+1);
outputImage(x,y,c) = outputImage(x,y,c) / normFactor;
result(x,y,c) = cast<uint8_t>(outputImage(x,y,c));

result.parallel(y).vectorize(x,8)

我确实在测试中找到了以下代码:

https://github.com/halide/Halide/blob/master/test/correctness/multi_pass_reduction.cpp

但是这个例子使用realize来计算积分图像作为固定域上的缓冲区,并且不会使用整数图像的定义作为后续函数定义中的函数。

当我运行此代码时,我发现:

  1. 积分图像的计算非常慢(将我的管道移动到0 fps)
  2. 我得到了错误的答案。我觉得我必须以某种方式错误地定义我的整体形象
  3. 我还有一个相关的问题,如何最好地安排在Halide中这类场景中计算积分图像?

1 个答案:

答案 0 :(得分:1)

我的问题在于我的积分图像的定义。如果我将实现更改为积分图像的标准一次通过定义,我会得到预期的行为:

Func integralImage;
integralImage(x,y,c) = 0.0f; // Pure definition
integralImage(intImDom.x,intImDom.y,c) = ip(intImDom.x,intImDom.y,c)
                  + integralImage(intImDom.x-1,intImDom.y,c)
                  + integralImage(intImDom.x,intImDom.y-1,c)
                  - integralImage(intImDom.x-1,intImDom.y-1,c);

integralImage.compute_root();

我仍然对Halide中用于计算整数图像的最有效算法/时间表存在疑问,但我会将其重新发布为更具体的问题,因为我目前的帖子是开放式的。

顺便说一句,上面的代码中存在第二个问题,即输入图像的填充处理不正确。