S32V234 软件系列 – ISP | debayer_rgb_simple_interleaved ISP 算子解析

一、S32V ISP 架构介绍

S32V234 集成了图像处理模块 Image Signal Processor ( ISP )。该模块可以处理摄像头采集的图像数据,替代摄像头模组的 ISP,可以为用户节省成本。在 S32V234 的 ISP 上可实现主流 ISP 的一些功能。

S32V234 的视频数据流向如下图所示,Camera 采集的图像数据通过 MIPI 或者 VIU 接口读取到 SRAM,再通过 Stream DMA 读取到 IPU 进行处理,处理完后再读取到下一个 IPU 处理,如果没有下一个 IPU 任务,那就通过 Stream DMA 输出到 Fast DMA,最后将处理结果输出到 DRAM,之后就可以调用该数据进入 DCU 模块显示或者进入 APEX 进行进一步处理。整个数据流的处理过程,需要在 Sequencer 的调度下完成。

         

通过对 IPU 中运行的 kernel 算子的编程,配合 NXP 提供的 S32DS 开发工具,我们可以在图形可视化的界面修改参数,添加 IPU ,调整 Kernel 算子,实现具体的 ISP 功能,优化图像质量。


二、使用 S32DS 开发环境创建工程

我们这里使用 OV9716 这颗 sensor 来讲解怎样搭建一个工程,并添加 debayer_rgb_simple_interleaved 这个 kernel 算子,最终通过 ISP 模块输出图像。

 

1、搭建 OV9716 的 S32DS 工程的 Graph

(1)搭建 OV9716 的 S32DS 工程的 Graph 流程图

         

(2)MIPI Engine 设置如下,我们的 eagle eye 开发板的 MIPICSI0 已经板载了一颗解串器,所以只有 MIPICSI1 可以外接转接板,所以这里 Engine Type 选择 MIPICSI1

         

(3)MIPI Engine 输出端口设置如下

         

 

(4)MIPI 的 SRAM Buffer 设置,[0][1] 通道没有需要设置的参数

         

 

(5)根据模组厂提供的配置,摄像头输出的是 RAW12 的数据,我们这里选择一个简单的 Debayer 插值算法算子 debayer_rgb_simple_interleaved 来进行图像处理,IPUS Kernel 算子设置如下

         
         

 

(6)Debayer 的 SRAM Buffer 设置, [0] 通道没有需要设置的参数

         

(7)FastDMA 的设置

         

(8)FastMDA 输出 DDRBuffer 设置

         


2、建立新的 Application 项目

(1)建立新的 ISP Application 工程

         

         

          

(2)回到 Graph,右键空白处选择,验证 ISP 数据流程图

         

(3)进行 Emit 设置(由自己绘制的 Graph 生成代码的相关设置)

         

(4)有两个页面需要设置,第一个是 [Main],左侧选定绘制的 ISP Graph 工程,右侧确定自己 isp 文件,以及通过 ISP Graph 生成的代码文件的输出 (Output) 位置

         

(5)第二个需要设置的页面是 [Common],把配置文件设置到 Application 下

         

3、修改 Application 代码

(1)确认 A53_gen 目录下生成的文件

         

(2)把上面的头文件添加到 main.cpp 中

         


(3)在 main.cpp 的 io_config 函数中添加如下代码分配内存空间接收图像数据

         

(4)把 isp_user_define.h 中把 #define DCU_BPP DCU_BPP_YCbCr422 修改为 #define DCU_BPP DCU_BPP_24,表示接收到的数据是 RGB888 的数据

         

(5)保存修改之后选择 [A53] 编译,在控制台中显示如下信息即完成编译。

         

         



(6)最终生成的 elf 文件放入 Demo 板即可运行。

         

(7)isp_tiub964_ov9716_Application.elf 放入 Eagle eye 开发板的运行效果如下

         


三、debayer_rgb_simple_interleaved 算子解析

1、查找算子

(1)可以看到在上面 Graph 中的使用的算子是“debayer_rgb_simple_interleaved”

         

(2)在 S32DS 左侧 Project 中的 ISP_kernels 目录中可以找到该算子文件。

         

(3)双击即可在右侧打开。

         

2、算子解析

这里 demo 所用的 “debayer_rgb_simple_interleaved” 算子到底是怎么处理的呢,接下来让我们逐步解析一下。

 

(1) 1~14 行代码解析,如下代码中,带 “//” 的是该句代码作用的解析

         

.global debayer_rgb_simple_interleaved_start   //.global 定义一个全局函数的入口

debayer_rgb_simple_interleaved_test_start: //debayer_rgb_simple_interleaved 函数入口

done debayer_rgb_simple_interleaved_test_d0,i //i 参数表示移入一个像素组件到输入矩阵中,完
//成后跳转到标号 debayer_rgb_simple_interleaved_d0

debayer_rgb_simple_interleaved_d0: //标号

done debayer_rgb_simple_interleaved _d2,i //i 参数表示移入一个像素组件到输入矩阵,完成后
//跳转到标号 debayer_rgb_simple_interleaved _d2

debayer_rgb_simple_interleaved _d2: //标号

 

(2)15~26 行代码解析,主要为寄存器配置和寄存器赋值

         

mov confalu, (0 /* unsigned*/ | (1<<1) /*saturate*/ | (8<< 4) /* SHR: 16.0*/)  
//对 CONFALU 寄存器进行配置,具体配置参
//《S32V234 Reference Manual》

mov gpr0,400 //把立即数 400 存入通用寄存器 gpr0
mov gpr2,490 //把立即数 490 存入通用寄存器 gpr2

lsl zero,ypos,15 //把行数按二进制左移 15 位,即借用行数最后一
//位是 0 还是 1 来判断奇偶

bne debayer_rgb_simple_interleaved_loop_odd: //使用 bne 指令判断,ZERO 不为 0,即跳转到
//标号debayer_rgb_simple_interleaved_loop_odd

debayer_rgb_simple_interleaved_loop_odd: //标号,从名称来看,即奇数行的处理

lsl zero,ypos,15 //把行数按二进制左移 15 位,即借用行数最后一位
//是 0 还是 1 来判断奇偶

 

(3)27~49 行代码解析,这部分是讲偶数行数据的处理

         

debayer_rgb_simple_interleaved_loop_even:    //标号,从名称看后面是偶数行的处理

mulh ina3,ina3,gpr2 //把通用寄存器 gpr2 的值与输入矩阵 ina3 的寄存
//器的值相乘,结果存入输入矩阵ina3寄存器中

mulh ina1,ina1,gpr0 //同上,gpr0*ina1,把结果存入 ina1

dout ina3,debayer_rgb_simple_interleaved_eg0,o //把 ina3 的值移入输出矩阵 OUT0 后跳转到标号
//debayer_rgb_simple_interleaved_eg0,带 o 参数表示执
//行完 dout 语句后,通过输出矩阵的输出通道执行输
//出周期

debayer_rgb_simple_interleaved_eg0: //标号

dout ina0,debayer_rgb_simple_interleaved_er0,o //ina0 的值放入 OUT0 后跳转,然后输出

debayer_rgb_simple_interleaved_er0: //标号

dout ina1,debayer_rgb_simple_interleaved_eb1,ixo
//把 ina1 的值放入 OUT0 后跳转,i 表示移入下一个
//像素,x 表示 “XPOS” 会按照 “XSTEP” 的配
//置递增,一旦达到设置的横向像素 “XSIZE”,将停
//止执行的指令,即完成水平方向的执行周期

debayer_rgb_simple_interleaved_eb1: //标号

dout ina4,debayer_rgb_simple_interleaved_eg1,o //把 ina4 的值放入 OUT0 后跳转,然后输出

debayer_rgb_simple_interleaved_eg1: //标号

dout ina1,debayer_rgb_simple_interleaved_er1,o //把 ina1 的值放入 OUT0 后跳转,然后输出

debayer_rgb_simple_interleaved_er1: //标号

dout ina2,debayer_rgb_simple_interleaved_loop_even,ixo
//把 ina2 的值放入 OUT0 后跳转到偶数行开始处理
//的标号 debayer_rgb_simple_interleaved_loop_even
//处进行循环处理,i 表示移入下一个像素,x 表示
//“XPOS” 会按照 “XSTEP” 的配置递增,一旦达
//到设置的横向像素 “XSIZE”,将停止执行的指令,
//即完成水平方向的执行周期


(4)50~70 行代码解析,这里是奇数行数据处理

         

奇数行处理和偶数行处理是类似的,因此不再赘述


(5)71~75 行代码解析,算子计算结束退出

         

.global debayer_rgb_simple_interleaved_end  //定义一个全局函数的出口
debayer_rgb_simple_interleaved_end: // debayer_rgb_simple_interleaved 的出口


以上就是 debayer_rgb_simple_interleaved 这个算子进行 debayer 的处理过程,总的来说就是根据一定规则取 ISP 矩阵中的一组 R、G、B、值组成一个 RGB888 像素值,这样就可以把 RAWDATE 图像转化为 RGB 图像了。

接下来我们也会不断更新更多 S32V234 相关的开发博文, 同时我们也会持续推出更多 ADAS 相关(i.MX8、Hi3566V100、Hi3559AV100、Hi3518EV300,硬件、软件、算法等)的技术开发博文, 如需更深入交流,欢迎在博文下方评论或者关注给我留言。



【参考资料】:

     [1]  S32V234RM_Rev2.1.pdf






★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论