Встроенная фильтрация изображения

Я пытаюсь сравнить производительность двухпроходного, раздельного подхода в Halide с подходом к блочной фильтрации на основе интегрального изображения, чтобы лучше понять планирование 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

Но этот пример использует реализацию для вычисления интегрального изображения в качестве буфера по фиксированной области и не использует определение интегрального изображения как функции в определении последующей функции.

Когда я запускаю этот код, я наблюдаю, что:

  1. Вычисление интегрального изображения происходит очень медленно (моя конвейерная программа перемещается на 0 кадров в секунду).
  2. Я получаю неправильный ответ. Я чувствую, что каким-то образом неправильно определяю свой целостный образ.

У меня также есть связанный с этим вопрос: как лучше всего запланировать вычисление интегрального изображения в сценарии такого типа в Halide?


person Alex Taylor    schedule 03.06.2016    source источник
comment
Проблема определенно связана с моим определением IntegerImage. Если я изменю определение на: IntegerImage(imageDomain.x,imageDomain.y,c) = ip(imageDomain.x,imageDomain.y,c) + IntegerImage(imageDomain.x-1,imageDomain.y,c) + IntegerImage( imageDomain.x,imageDomain.y-1,c) - IntegerImage(imageDomain.x-1,imageDomain.y-1,c);   -  person Alex Taylor    schedule 04.06.2016


Ответы (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 для вычисления интегрального изображения, но я повторно опубликую его как более конкретный вопрос, поскольку мой текущий пост был открытым.

Кроме того, в приведенном выше коде есть вторая проблема, заключающаяся в том, что заполнение входного изображения обрабатывается неправильно.

person Alex Taylor    schedule 04.06.2016