Halide: ошибка алгоритма демозаики для больших изображений.Кажется, работает для 16x16 изображений. - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь реализовать алгоритм демозаики для фильтра Байера, как показано в разделе 2.8 (стр. 8) этого PDF-файла: http://www.arl.army.mil/arlreports/2010/ARL-TR-5061.pdf. Я застрял при попытке реализовать функцию через RDom.Когда я использую изображение 16x16, трассировки фактически заканчиваются, но когда я использую изображение большего размера, например 768x1280, трассировка застревает:

Store green.0(767, 1279);

Ниже приведена упрощенная версия моего кода:

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

using namespace Halide;


int main(int argc, char **argv) {

    Buffer<uint8_t> input = Tools::load_image(argv[1]);

    RDom r(2, input.width() - 4, 2, input.height() - 4);
    r.where((r.x % 2 == 0 && r.y % 2 == 0) || (r.x % 2 == 1 && r.y % 2 == 1));

    Var x("x"), y("y");

    Func g_n, w_n, g_n_est, green("green");

    g_n(x, y) = cast<float> (0);
    w_n(x, y) = cast<float> (0);
    g_n_est(x, y) = cast<float> (0);
    green(x, y) = cast<uint8_t> (0);


    printf("width: %d\n", input.width());
    printf("height: %d\n", input.height());
    printf("channels: %d\n", input.channels());

    g_n(r.x, r.y) = abs(cast<float>(input(r.x, r.y + 1) - input(r.x, r.y - 1))) + abs(cast<float>(input(r.x, r.y) - input(r.x, r.y - 2)));
    w_n(r.x, r.y) = cast<float>(1 / (1 + g_n(r.x, r.y)));
    g_n_est(r.x, r.y) = cast<float>(input(r.x, r.y - 1) + (input(r.x, r.y) - input(r.x, r.y - 2))) / 2;

    green(r.x, r.y) = cast<uint8_t>(w_n(r.x, r.y) * g_n_est(r.x, r.y));
    green.trace_stores();



    Buffer<uint8_t> temp = green.realize(input.width(), input.height());

    Tools::save_image(temp, "result.png");

}

Это ошибка в Halide?В этом случае код завершает выполнение и сохраняет выходное изображение для ввода 16x16, но застревает в трассировке для больших изображений.

1 Ответ

0 голосов
/ 11 июля 2018

Это просто очень, очень неэффективный график.Каждый этап каждый вычисляет O (n) пикселей в своих определениях обновлений каждый раз, когда они реализуются (сейчас это большое значение RDom r), но каждый этап также встроен в следующий.В результате каждая точка в green рекурсивно вычисляет целое изображение g_n_est и w_n, а затем для каждого из своих пикселей она рекурсивно вычисляет целое изображение g_n.

ЧтоВы видите, что остановка на green.0(767, 1023) на самом деле правильная после она закончила вычислять чистое определение green(x,y) = 0 для последнего пикселя, и в этот момент ему действительно нужно вечно вычислять все этапы обновленияиз-за работы O (n ^ 3) , которую он выполняет.

Это тот случай, когда агрессивное включение большего количества трассировок сделает проблему более ясной.Вы можете включить отслеживание реализаций или отдельных хранилищ глобально при настройке компиляции: https://github.com/halide/Halide/wiki/Debugging-Tips#tracing.

Для этого кода планирование более ранних этапов как compute_root может быть тем, что вы хотите, хотя на самом деле вы можете захотетьОпределения g_n_est и w_n представляют собой простые чистые функции (без RDom с), которые можно объединить в green, запланировать в блоках и т. Д.

...