Halide入门教程02


// Halide tutorial lesson 2: Processing images
// Halide入门第二课: 处理图像// This lesson demonstrates how to pass in input images and manipulate
// them.
// 本课展示了如何读入图像数据,并操作像素// On linux, you can compile and run it like so:
// 在linux操作系统,你可以按照如下方式编译和运行该代码
// 运行之前确保操作系统安装了libpng和libjpeg库,可以到对应的sourceforge上找到对应的代码编译安装,
// 或者采用linux系统的包管理系统进行安装,debian系操作系统
// sudo apt-get install libpng
// sudo apt-get install libjpeg
// g++ lesson_02*.cpp -g -I ../include -I ../tools -L ../bin -lHalide `libpng-config --cflags --ldflags` -ljpeg -lpthread -ldl -o lesson_02 -std=c++11
// LD_LIBRARY_PATH=../bin ./lesson_02// On os x:
// g++ lesson_02*.cpp -g -I ../include -I ../tools -L ../bin -lHalide `libpng-config --cflags --ldflags` -ljpeg -o lesson_02 -std=c++11
// DYLD_LIBRARY_PATH=../bin ./lesson_02// If you have the entire Halide source tree, you can also build it by
// running:
//    make tutorial_lesson_02_input_image
// in a shell with the current directory at the top of the halide
// source tree.// The only Halide header file you need is Halide.h. It includes all of Halide.
#include "Halide.h"// Include some support code for loading pngs.
// halide_image_io.h提供了png格式图片的读写函数
#include "halide_image_io.h"
using namespace Halide::Tools;int main(int argc, char **argv) {// This program defines a single-stage imaging pipeline that// brightens an image.// 该程序定义了一个阶段的图像处理pipeline,将图像对应的像素点放大一定倍数// 达到提升图像亮度的目的。// First we'll load the input image we wish to brighten.// halide_image_io.h提供的图像IO函数,读入要处理的图像数据Halide::Buffer<uint8_t> input = load_image("images/rgb.png");// See figures/lesson_02_input.jpg for a smaller version.// Next we define our Func object that represents our one pipeline// stage.// 接下来定义Func对象,Func对象表示我们将要进行的图像亮度提升pipelineHalide::Func brighter;// Our Func will have three arguments, representing the position// in the image and the color channel. Halide treats color// channels as an extra dimension of the image.// 接下来定义操作图像像素的索引,即Var(变量)x(column),y(row),c(channel)// x,y为坐标索引,c为颜色通道索引。Halide::Var x, y, c;// Normally we'd probably write the whole function definition on// one line. Here we'll break it apart so we can explain what// we're doing at every step.// For each pixel of the input image.// value表达式表示c通道(x,y)坐标处的像素值Halide::Expr value = input(x, y, c);// Cast it to a floating point value.// 为了进行浮点计算,先将数据类型转换成单精度浮点类型value = Halide::cast<float>(value);// Multiply it by 1.5 to brighten it. Halide represents real// numbers as floats, not doubles, so we stick an 'f' on the end// of our constant.// 将c通道(x,y)坐标处的像素值放大1.5倍value = value * 1.5f;// Clamp it to be less than 255, so we don't get overflow when we// cast it back to an 8-bit unsigned int.// 为了防止数据溢出,将放大后的像素值clip到[0,255]区间,并转换成8位无符号整型value = Halide::min(value, 255.0f);// Cast it back to an 8-bit unsigned integer.value = Halide::cast<uint8_t>(value);// Define the function.// 定义函数,将亮度提升后的像素值,赋值给函数对象的(x,y,c)点brighter(x, y, c) = value;// The equivalent one-liner to all of the above is://// brighter(x, y, c) = Halide::cast<uint8_t>(min(input(x, y, c) * 1.5f, 255));//// In the shorter version:// - I skipped the cast to float, because multiplying by 1.5f does//   that automatically.// - I also used an integer constant as the second argument in the//   call to min, because it gets cast to float to be compatible//   with the first argument.// - I left the Halide:: off the call to min. It's unnecessary due//   to Koenig lookup.// Remember, all we've done so far is build a representation of a// Halide program in memory. We haven't actually processed any// pixels yet. We haven't even compiled that Halide program yet.// 上述所有操作知识在内存中建立Halide程序,告诉Halide怎么去进行算法操作,即对算法进行了定义。// 实际上还没有开始进行任何像素的处理。甚至Halide程序还没有进行编译// So now we'll realize the Func. The size of the output image// should match the size of the input image. If we just wanted to// brighten a portion of the input image we could request a// smaller size. If we request a larger size Halide will throw an// error at runtime telling us we're trying to read out of bounds// on the input image.// 现在将要实现函数。输出图像的尺寸必须和输入图像的尺寸相匹配。如果我们只想提高输入图像部分区域//像素点的亮度,可以指定一个小一点的尺寸。如果需要一个更大尺寸的输出,Halide在运行时会抛出一个//错误告诉我们,边界超出输入图像。Halide::Buffer<uint8_t> output =brighter.realize(input.width(), input.height(), input.channels());// Save the output for inspection. It should look like a bright parrot.// 写下被处理过的图像save_image(output, "brighter.png");// See figures/lesson_02_output.jpg for a small version of the output.printf("Success!\n");return 0;
}

在终端中编译并执行代码:

$ g++ lesson_02*.cpp -g -I ../include -I ../tools -L ../bin -lHalide `libpng-config --cflags --ldflags` -ljpeg -lpthread -ldl -o lesson_02 -std=c++11
// 注: 可以将Halide的bin目录添加到环境变量中,或者在实验时
// export LD_LIBRARY_PATH=../bin
// 这样就不需要每次都指定halide动态链接库所在路径
$ ./lesson_02

输出结果:

$ Success!

处理前图像rgb.png

亮度提升后图像brighter.png

流程总结:

1. 读取待处理图像数据
2. 定义变量,表达式
3. 定义Func,算法实现(此时只是内存中的算法,并没有开始对像素点进行操作)
4. 算法调度,调用Func的realize成员变量,实现算法(开始对像素进行操作,进行图像处理)
5. 将output数据写回硬盘

Halide学习笔记----Halide tutorial源码阅读2相关推荐

  1. python学习笔记之三——MakeHuman源码阅读

    1.@装饰器的用法 简单的说,@装饰器就是用来提供调用的, def funA(arg):print 'A'a=arg()@funA def funB():print 'B' 此处的@相当于funA(f ...

  2. C-libev学习笔记-事件库源码阅读6-API-ev_default_loop(),ev_init()

    ev_default_loop() 声明: EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) ...

  3. JUC.Condition学习笔记[附详细源码解析]

    JUC.Condition学习笔记[附详细源码解析] 目录 Condition的概念 大体实现流程 I.初始化状态 II.await()操作 III.signal()操作 3个主要方法 Conditi ...

  4. K8s基础知识学习笔记及部分源码剖析

    K8s基础知识学习笔记及部分源码剖析 在学习b站黑马k8s视频资料的基础上,查阅了配套基础知识笔记和源码剖析,仅作个人学习和回顾使用. 参考资料: 概念 | Kubernetes 四层.七层负载均衡的 ...

  5. LOAM笔记及A-LOAM源码阅读

    转载出处:LOAM笔记及A-LOAM源码阅读 - WellP.C - 博客园 导读 下面是我对LOAM论文的理解以及对A-LOAM的源码阅读(中文注释版的A-LOAM已经push到github,见A- ...

  6. Vuex 4源码学习笔记 - 通过Vuex源码学习E2E测试(十一)

    在上一篇笔记中:Vuex 4源码学习笔记 - 做好changelog更新日志很重要(十) 我们学到了通过conventional-changelog来生成项目的Changelog更新日志,通过更新日志 ...

  7. Netty学习笔记 - 1 (带源码分析部分)

    2021年12月 北京 xxd 一.Netty是什么 Netty 是由 JBOSS 提供的一个 Java 开源框架,现为 Github 上的独立项目. Netty 是一个异步的.基于事件驱动的网络应用 ...

  8. The Things Network LoRaWAN Stack V3 学习笔记 1.2 源码编译

    前言 源码编译是重头戏,这节笔记记录如何使用 make 命令编译相关部件.由于部分包在墙外,带来了一点麻烦,还分享一个 replace 方式来翻墙的办法. 小能手这段时间在学习 The Things ...

  9. 【从线性回归到 卷积神经网络CNN 循环神经网络RNN Pytorch 学习笔记 目录整合 源码解读 B站刘二大人 绪论(0/10)】

    深度学习 Pytorch 学习笔记 目录整合 数学推导与源码详解 B站刘二大人 目录传送门: 线性模型 Linear-Model 数学原理分析以及源码详解 深度学习 Pytorch笔记 B站刘二大人( ...

  10. The Things Network LoRaWAN Stack V3 学习笔记 1.2 源码编译 - 190821

    文章目录 前言 1 依赖包替换 2 编译准备 3 编译 3.1 cli 编译 3.2 stack 编译 3.3 前端编译 END 前言 源码编译是重头戏,这节笔记记录如何使用 make 命令编译相关部 ...

最新文章

  1. mysql带where条件导出数据表以及部分错误解析
  2. 时间序列挖掘-DTW加速算法FastDTW简介
  3. 很好很强大,这款AI开发神器的图像标注吊打labelme
  4. 图的根节点-数据结构作业。。
  5. 巧用 maxTimeMS 服务端超时,避免承载亿级用户的腾讯云数据库MongoDB服务雪崩
  6. 枚举遍历法,你能循环遍历所有的枚举值吗?
  7. 你是在用计算机算你的人生经历吗,计算机人生规划
  8. 服务端架构中的“网关服务器”
  9. 漫画丨那些年,我们一起被毁过的“三观”…
  10. Oracle 忘记/修改密码
  11. 魔兽世界忘记账号角色服务器,魔兽世界里我知道了他的游戏角色名字怎样查到他的战网通行证...
  12. 入门机器学习(西瓜书+南瓜书)神经网络总结(python代码实现)
  13. PHP支付宝转账到支付宝账号
  14. System32、SysWOW64与SysNative文件夹
  15. WebRTC 教程二:WebRTC API 和 Leak
  16. js中的DOM事件之冒泡和捕获事件详解
  17. [Python从零到壹] 五十九.图像增强及运算篇之图像锐化Scharr、Canny、LOG实现边缘检测
  18. Python——时间与时间戳之间的转换
  19. 车联网也需要“走对路”,用户需求“导航”小度车载OS持续领先
  20. 重装 UOS Deepin V20 后必安装软件(个人习惯)

热门文章

  1. 大数据架构师之路-大数据框架大全
  2. 自动秘钥密码(Autokey)
  3. jQuery入门选择器
  4. 分享十次Android面试经验总结,已收字节,阿里,从三流Android外包到秒杀阿里P7,
  5. Lua学习第二课_初探lua和lua语法
  6. LaTeX入门|(2)定制专属模板
  7. Angular入门到精通系列教程(6)- Angular的升级
  8. 什么是Java中的迭代器?如何使用它
  9. 在天翼云服务器部署程序不能被外网访问的问题
  10. T100——q查询,子母查询(汇总——明细)练习笔记