前言
接上, 学习Halide lesson 7: Multi-stage pipelines
** Now we’ll express a multi-stage pipeline that blurs an image first horizontally, and then vertically. **
main
Var x("x"), y("y"), c("c");
Buffer<uint8_t> input = load_image("images/rgb.png");
//Upgrade it to 16-bit, so we can do math without it overflowing.
Func input_16("input_16");
input_16(x, y, c) = cast<uint16_t>(input(x, y, c));
// Blur it horizontally:
Func blur_x("blur_x");
blur_x(x, y, c) = (input_16(x - 1, y, c) + 2 * input_16(x, y, c) + input_16(x + 1, y, c)) / 4;
// Blur it vertically:
Func blur_y("blur_y");
blur_y(x, y, c) = (blur_x(x, y - 1, c) + 2 * blur_x(x, y, c) + blur_x(x, y + 1, c)) / 4;
// Convert back to 8-bit.
Func output("output");
output(x, y, c) = cast<uint8_t>(blur_y(x, y, c));
//
//
//防止上面的计算越界
Buffer<uint8_t> result(input.width() - 2, input.height() - 2, 3);
result.set_min(1, 1);
output.realize(result);
//The same pipeline, with a boundary condition on the input.
Buffer<uint8_t> input = load_image("images/rgb.png");
// This time, we'll wrap the input in a Func that prevents reading out of bounds:
Func clamped("clamped");
clamped = BoundaryConditions::repeat_edge(input);
Func input_16("input_16");
input_16(x, y, c) = cast<uint16_t>(clamped(x, y, c));
;;;
Buffer<uint8_t> result = output.realize({ input.width(), input.height(), 3 });
;;;
End
本章同样比较简单:
Multi-stage pipelines:
1. 读取uint8_t图像;
2. 转uint16_t, 防止计算溢出;
3. 水平模糊;
4. 垂直模糊;
5. 转回uint8_t;
6. 保存出图像;
重点问题: 计算越界问题
可以缩小输出的尺寸;
也可以clamped;
BoundaryConditions::repeat_edge;