Halide示例学习三

改变维度遍历起点

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

using namespace Halide;

int main(int argc, char **argv) {
    Func gradient("gradient");
    Var x("x"), y("y");
    gradient(x, y) = x + y;
    gradient.trace_stores();
    printf("Evaluating gradient from (0, 0) to (7, 7)\n");
    // 普通的起点为0的正方形
    Buffer<int> result(8, 8);
    gradient.realize(result);
    for (int y = 0; y < 8; y++) {
        for (int x = 0; x < 8; x++) {
            if (result(x, y) != x + y) {
                printf("Something went wrong!\n");
                return -1;
            }
        }
    }
    // 现在定义一个起点不为0的长方形
    Buffer<int> shifted(5, 7);  //形状尺寸
    shifted.set_min(100, 50);   //左上角的起点位置
    printf("Evaluating gradient from (100, 50) to (104, 56)\n");
    gradient.realize(shifted);
    // 等效C代码如下所示
    for (int y = 50; y < 57; y++) {
        for (int x = 100; x < 105; x++) {
            if (shifted(x, y) != x + y) {//此刻就无法读取边界外的序号点了
                printf("Something went wrong!\n");
                return -1;
            }
        }
    }
    // Halide只适合矩形的边界数据
    return 0;
}
# 结果如下所示
Begin pipeline gradient.0()
Tag gradient.0() tag = "func_type_and_dim: 1 0 32 1 2 100 5 50 7"
Store gradient.0(100, 50) = 150
Store gradient.0(101, 50) = 151
Store gradient.0(102, 50) = 152
Store gradient.0(103, 50) = 153
Store gradient.0(104, 50) = 154
Store gradient.0(100, 51) = 151
Store gradient.0(101, 51) = 152
Store gradient.0(102, 51) = 153
Store gradient.0(103, 51) = 154
Store gradient.0(104, 51) = 155
Store gradient.0(100, 52) = 152
Store gradient.0(101, 52) = 153
Store gradient.0(102, 52) = 154
Store gradient.0(103, 52) = 155
Store gradient.0(104, 52) = 156
Store gradient.0(100, 53) = 153
Store gradient.0(101, 53) = 154
Store gradient.0(102, 53) = 155
Store gradient.0(103, 53) = 156
Store gradient.0(104, 53) = 157
Store gradient.0(100, 54) = 154
Store gradient.0(101, 54) = 155
Store gradient.0(102, 54) = 156
Store gradient.0(103, 54) = 157
Store gradient.0(104, 54) = 158
Store gradient.0(100, 55) = 155
Store gradient.0(101, 55) = 156
Store gradient.0(102, 55) = 157
Store gradient.0(103, 55) = 158
Store gradient.0(104, 55) = 159
Store gradient.0(100, 56) = 156
Store gradient.0(101, 56) = 157
Store gradient.0(102, 56) = 158
Store gradient.0(103, 56) = 159
Store gradient.0(104, 56) = 160
End pipeline gradient.0()

多计算图组合示例

#include "Halide.h"
#include <stdio.h>
using namespace Halide;
#include "halide_image_io.h"
using namespace Halide::Tools;

int main(int argc, char **argv) {
    Var x("x"), y("y"), c("c");

    // 这里使用多计算图,先垂直后水平
    {
        // 得到一个全彩图片
        Buffer<uint8_t> input = load_image("../../images/vscode.jpg");
        // 提升精度到16bit
        Func input_16("input_16");
        input_16(x, y, c) = cast<uint16_t>(input(x, y, c));
        // 水平模糊:水平方向取邻近像素均值
        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;
        // 垂直模糊:垂直方向取邻近像素均值
        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;
        // 降低精度为8bit
        Func output("output");
        output(x, y, c) = cast<uint8_t>(blur_y(x, y, c));
        // Halide中,计算图都是前向计算图
        // 下述的实例化代码是需要考虑到边界溢出的问题,所以这里的尺寸需要减2,同时起点需要偏移到(1,1)
        Buffer<uint8_t> result(input.width() - 2, input.height() - 2, 3);
        result.set_min(1, 1);
        output.realize(result);
        save_image(result, "../../images/blurry_parrot_1.png");
    }

    // 一样的操作,但是采用了截断操作来防止边界溢出的报错
    {
        Buffer<uint8_t> input = load_image("../../images/vscode.jpg");
        Func clamped("clamped");
        // 使用Halide::clamp函数,可以把索引限制在边界内
        Expr clamped_x = clamp(x, 0, input.width() - 1);
        Expr clamped_y = clamp(y, 0, input.height() - 1);
        clamped(x, y, c) = input(clamped_x, clamped_y, c);
        Func input_16("input_16");
        input_16(x, y, c) = cast<uint16_t>(clamped(x, y, c));
        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;
        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;
        Func output("output");
        output(x, y, c) = cast<uint8_t>(blur_y(x, y, c));

        // 此时就不需要继续在实例化的时候再进行边界检查
        Buffer<uint8_t> result = output.realize({input.width(), input.height(), 3});
        save_image(result, "../../images/blurry_parrot_2.png");
    }

    printf("Success!\n");
    return 0;
}

示例图结果如下所示:

  • 原图(112x61)

在这里插入图片描述

  • 不使用截断(110x59)

在这里插入图片描述

  • 使用截断(112x61)

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值