环视图像拼接示例

该示例介绍了使用了 hbVPStitchhbVPRemaphbVPJPEGDecodehbVPJPEGEncode 等API,涉及到stitch、gdc和codec硬件ip,完成一次360环视场景拼接的应用。

该示例实现的功能为:对使用车上鱼眼摄像头拍摄的四张前视、右视、后视、左视畸变图,进行去畸变与环视拼接,完成一次360环视场景拼接的应用。 首先会为四张畸变图创建map,使用codec硬件ip读取鱼眼畸变图转换为nv12数据,然后运行gdc硬件ip,将畸变图变为俯视图,接着会运行stitch硬件ip,将俯视图进行拼接成环视拼接图。

代码主要分为以下步骤:

  1. 初始化log和环境变量。
  2. 设置后视、前视、左视、右视的相机参数,调用 ProcessIpmRois() 接口,得到俯视图在IPM(图像透视映射的坐标系)上的roi。
  3. 使用gdc硬件生成四个视角的俯视图map,使用codec硬件ip读取鱼眼畸变图转换为nv12数据,将鱼眼畸变数据转换为俯视图数据,并释放四个map。
  4. 创建lut表和准备拼接区的信息。
  5. 使用stitch硬件生成环视拼接图。
  6. 释放lut表和申请的内存。

概念声明

  1. VCS(Vehicle Coordinate System) 车辆的坐标系:
x [front] ^ y <──────┼────── [left] │ [VCS](Vehicle Coordinate System)

VCS坐标系描述了车辆的坐标系。坐标轴x对应车辆的前方,y对应车辆的左侧,z对应车辆的顶部。这个坐标系的原点不是车辆的中心,而是车辆后轴的中心。

  1. IPM(Image Perspective Mapping)图像透视映射的坐标系:
| | ──────┼──────> x | | v y [IPM](Image Perspective Mapping)

IPM坐标系描述了图像透视映射的坐标系。

鱼眼畸变图转换map生成详述

生成map主要目的为使用remap功能,可以生成像素映射关系:

image

创建将鱼眼畸变图转换为俯视图的核心函数为 TransformMapGenerate(),主要逻辑如流程图所示:

VP6_avm1

其中,TransformMapGenerate() 中使用的 CalculateExtrinsicTransform(),对应流程图中的倒数第二步,作用为将车辆坐标系数据转换到相机坐标系,主要逻辑如流程图所示:

VP6_avm1

其中:

  1. IntrinsicXYZ2R() 作用为:将欧拉角表示的旋转(Roll-Pitch-Yaw)转换为一个旋转矩阵,用于描述三维空间中的旋转变换。旋转矩阵能够将旋转操作以矩阵乘法的形式应用到向量上。
  2. adas相机到相机坐标系的变换矩阵中:
  • 第一行表示新的 x 轴在相机坐标系中的方向,指向 ADAS 相机坐标系的 z 轴方向。
  • 第二行表示新的 y 轴在相机坐标系中的方向,指向 ADAS 相机坐标系的负 x 轴方向。
  • 第三行表示新的 z 轴在相机坐标系中的方向,指向 ADAS 相机坐标系的负 y 轴方向。
  • 最后一行表示平移部分,其中最后一个元素为1,表示没有平移。

这个矩阵的作用是将 ADAS 相机坐标系下的点转换到相机坐标系下,实现坐标系的变换和对齐。这种变换在计算机图形学和计算机视觉中常常被使用。

stitch lut表生成详述

lut表函数的作用为:表示每个像素点融合状况,主要目的为生成过渡带,形成模糊效果。

解释:lut表的dump出情况如下图。0和255是对立关系,255是取src0,0是取src1。0<x<255,则表示取部分src0,取部分src1。128或127为强制过渡带,两边数字渐小直到0或渐大到255,形成渐变模糊效果。

image

运行方法

该示例位于 vp_samples/script/05_avm 目录下,包含以下脚本:

05_avm/ ├── README.md └── run_avm.sh

运行命令行说明

run_avm.sh:该脚本实现四张鱼眼畸变图环视拼接的示例功能。run_avm.sh脚本中命令行内容如下:

bin=../aarch64/bin/avm_sample lib=../aarch64/lib export LD_LIBRARY_PATH=${lib}:${LD_LIBRARY_PATH} export PATH=${bin}:${PATH} export HB_DSP_ENABLE_DIRECT_MODE=true export HB_DSP_ENABLE_CONFIG_VDSP=true export HB_DSP_LOG_LEVEL=3 export HB_DSP_VDSP_LOG_LEVEL=3 # Usage: ${bin} ${bin}

${bin}:编译好的可执行文件

使用的时候,进入 vp_samples/script/05_avm 目录,然后直接执行run_avm.sh即可,如下代码块所示:

root@j6dvb: /vp_samples/script/05_avm# sh run_avm.sh [I][27075][08-16][14:01:36:373][avm_example.cpp:84][avm_sample][VP_AVM] AVM sample start. ...

结果说明

示例运行结束后会在当前目录下生成可视化图像。部分结果如下所示:

原图:

camera0(后视)
VP6_avm_camera_0
camera1(前视)
VP6_avm_camera_1
camera0(左视)
VP6_avm_camera_2
camera1(右视)
VP6_avm_camera_3

去畸变+俯视图:

camera0(后视)
VP6_topview_camera_0_trans
camera1(前视)
VP6_topview_camera_1_trans
camera0(左视)
VP6_topview_camera_2_trans
camera1(右视)
VP6_topview_camera_3_trans

拼接环视图:

VP6_avm1
注意
  1. 该示例的remap默认运行在gdc上。

  2. 如需替换图片,请将图片对应的相机参数配置数据进行修改,否则运行会有问题。

  3. 环境变量:

    HB_AVM_GDC_MAP_DUMP 选择是否dump gdc的map。

    # 设为1可以dump map export HB_AVM_GDC_MAP_DUMP=1

    HB_AVM_GDC_RES_DUMP 选择是否dump俯视图的结果。

    # 设为1可以dump gdc的图片 export HB_AVM_GDC_RES_DUMP=1

    HB_AVM_LOG_LEVEL log等级,1为debug。

    export HB_AVM_LOG_LEVEL=1
  4. 当YUV图像dump为JPG文件时,如果YUV图像的宽度或者高度不满足Codec对齐规则,则默认使用opencv的方式进行dump。