Halide: ошибка алгоритма демозаики для больших изображений. Кажется, работает для 16x16 изображений.
Я пытаюсь реализовать алгоритм демозаики для фильтра Байера, как показано в разделе 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 ответ
Это просто очень, очень неэффективный график. Каждый этап каждого вычисляет 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.
Для этого кода планирование ранних этапов как compute_root
может быть, что вы хотите, хотя вы можете g_n_est
а также w_n
определения должны быть простыми чистыми функциями (нет RDom
S вообще), которые могут быть объединены в green
, запланировано в блоках и т. д.