5.10.4. GDC Tool
5.10.4.1. GDC Tool 介绍
GDC Tool 是一种可在 PC 上进行处理效果仿真的工具。用户可准备 jpg 模式的图像, load 到 gdc-tool 中进行离线校正,校正完成后可以直接保存 bin 文件用于硬件校正,也可用保存 layout.json 文件生成 bin 进行硬件校正。
GDC Tool 启动
1.window 环境
安装环境:依赖于 Node.js。参考下载:https://nodejs.cn/download/。
工具获取:从发布包下载 gdc 工具 ( gdc-tool-xxxx-windows ) ,路径:/X5_LNX_SDK/LNX6.1.83_PLx_Vx.x.xx/software_tools/gdc_tools/。
安装依赖:在 Windows 命令行中,进入 gdc 工具目录下( 如 gdc-tool-gui-xxxx-windows ), 执行 npm install express。
启动应用:在 Windows 命令行中,进入 gdc 工具目录( 如 gdc-tool-gui-xxxx-windows ),执行 node.exe app.js,使用 Chrome 浏览器登录 http://localhost:3000/。
2.unix 环境
安装环境: mac: brew install node。
安装依赖:文件目录下执行 npm install -production。
启动应用:执行 node app.js,打开网页登录 http://localhost:3000/。
3.开始仿真
使用 GDC Tool 一般需要以下步骤:

上图的绿色箭头和下面的步骤一一对应。
登录网页成功后,参考上传准备好的 sensor 采集到的图像上传,上传前需要将采集到的图像的 YUV 图像转换为 jpg 图像。
准备 jpg 图像:可以使用 ffmpeg 将 sensor 获取到的 YUV 文件转换成 jpg 图像进行上传,方法参考如下。
ffmpeg -s 1920x1080 -pix_fmt yuv420p -i handle_100197_isp_chn0_1920x1080_stride_1920_frameid_0_ts_2411352368066.yuv output.jpg
根据使用场景确认使用的变换模式。设置 Transformation 为对应的变换模式,如果使用的是 custom 模式,需要同时准备 GDC 的矫正标定参数文件上传。
根据变换模式配置 GDC 的参数信息,配置图中 Input 。详细请查看章节 变换模式参数说明 。
根据变换模式配置 GDC 的参数信息,配置图中 Output。 详细请查看章节 变换模式参数说明 。
根据变换模式配置 GDC 的参数信息,配置图中 Settings。 详细请查看章节 变换模式参数说明 。
配置 GDC 的参数信息成功后,点击 Preview 进行预览,确认是否符合预期。
确认仿真效果符合预期后,可以导出
layout.json文件进行使用。使用方法可以参考 GDC 示例代码 sample_gdc 章节。确认仿真效果符合预期后,可以导出 bin 文件进行使用。使用方法可以参考 GDC 示例代码 sample_gdc 章节。
GDC Tool 中的变换模式
GDC Tool 提供六种变换模式: Affine, Equisolid, Equisolid(cylinder), Equidistant, Custom, Keystone+dewarping,这些模式与软件中的变换模式对应关系见 GDC Bin API 文档中的 transformation_t 描述。
下表是各个变换的用途。
| 变换模式 | 用途 |
|---|---|
| Affine | 一种线性变换,简单的图像旋转功能,没有畸变校正 |
| Equisolid | 全景变换,变换网格最大 |
| Equisolid (cylinder) | 圆柱形变换 |
| Equidistant | 等距变换,变换后的距离等距 |
| Keystone + dewarping | 相对于 Equidistant, dewarp_keystone 多了两个参数 trapezoid_left_angle 和 trapezoid_right_angle。默认情况下这两个参数 90 度,效果和 Equidistant 一样 |
| Custom | 用户定制变换 |
所有转换类型都有以下三个常用参数 Pan、 Tile、 Zoom( 举例:等距变换,输入 / 输出分辨率 1280x720 ):
以下输出图像中的蓝色矩形表示仅将特殊参数设置为该值,并且一个转换中的其他参数保持默认值。
Pan
水平方向 ( -1280, +1280 )通过给定的像素数,偏移变换网格。如下所示:

Tile
垂直方向 ( -720, +720 )通过给定的像素数,偏移变换网格。如下所示:

Zoom
按提供的因子 ( 0, +∞ )缩放变换输出,( 0, 1 )表示值大于 0 且小于 1 。如下所示:

Affine
【功能描述】
提供线性的变换。

【成员说明】
| 成员 | 含义 |
|---|---|
| int32_t pan | default 0, 不修改 |
| int32_t tilt | default 0, 不修改 |
| zoom | 按提供的因子缩放转换输出 |
| double angle (rotation) | 0/90/180/270 |
Equisolid
【功能描述】
此转换提供等实体( 全景 panoramic )校正,并将结果显示为平面上的投影。

【成员说明】
| 成员 | 含义 |
|---|---|
| int32_t pan | default 0, 不修改 |
| int32_t tilt | default 0, 不修改 |
| zoom | 按提供的因子缩放转换输出 |
| double strength | 沿 X 轴的变换强度 ( 非负参数 ) |
| double strengthY | 沿 Y 轴的变换强度 ( 非负参数 ) |
| double angle (rotation) | 0/90/180/270 |
strength x 调试效果,在 X 轴的转换强度,取值( 0, +∞ )。如下所示:

strength y 调试效果,在 Y 轴的转换强度,取值( 0, +∞ )。如下所示:

Rotation 调试效果,取值( -180, 180 )。如下所示:

Equisold(cylinder)
【功能描述】
此变换为将结果图像投影到柱面全景图的完整鱼眼帧提供等实体校正。

【成员说明】
| 成员 | 含义 |
|---|---|
| int32_t pan | default 0, 不修改 |
| int32_t tilt | default 0, 不修改 |
| zoom | 按提供的因子缩放转换输出 |
| strength | 转换的强度 |
| double angle (rotation) | 0/90/180/270 |
strength 调试效果,转换的强度( 0 ,+∞ )。如下所示:

rotation 调试效果,取值范围( -180,+180 )。如下所示:

Equidistant
【功能描述】
等距变换包含许多参数,这些参数允许它为投影提供一系列不同的目标平面。这使用户可以更自由地选择要变换的鱼眼帧的所需区域。

【成员说明】
| 成员 | 含义 |
|---|---|
| int32_t pan | 水平方向通过给定的像素数,偏移变换网格 |
| int32_t tilt | 垂直方向通过给定的像素数,偏移变换网格 |
| zoom | 按提供的因子缩放转换输出 |
| double angle(rotation) | 图像旋转的角度 |
| double elevation | 定义了投影轴的仰角,范围 0 到 90 |
| double azimuth | 定义了投影轴的方位角度。如果仰角参数 elevation 为 0 ,则方位角将没有可见效果 |
| int32_t keep_ratio | 当“保持比率”参数打开时, FOV 高度参数将被忽略,其值将自动计算,以在水平和垂直方向上保持相同的拉伸强度 |
| double FOV_h | 描述水平维度中输出视图字段的大小(以度为单位 )。有效值的范围是从 0 到 180 |
| double FOV_w | 描述垂直维度中输出视图字段的大小(以度为单位 )。有效值的范围是从 0 到 180 |
| double cylindricity_y | 描述目标投影沿 Y 轴的球面度。此值从 0 到 1 ,其中 1 是球形的。如果此值设置为 1 ,而“圆柱度 X”值设置为 0 ,则投影将沿 Y 轴形成圆柱体 |
| double cylindricity_x | 描述目标投影沿 X 轴的球面度。此值从 0 到 1 ,其中 1 是球形的。如果此值设置为 1 ,并且“圆柱度 Y”值设置为 0 ,则投影将沿 X 轴形成圆柱体 |
输入输出尺寸的宽应保持 16 像素对齐。
正常的视力值大约是 90 度。对于圆柱度(见下文 )等于“ 0”的变换,视场宽度和高度 180 的值将导致图像无限拉伸。
如果 cylindricity_x 和 cylindricity_y 圆柱度值都设置为 1 ,则投影将是球形的。如果两者都是 0 ,则变换将是矩形的。
elevation 调试效果:

azimuth 调试效果:

rotation 调试效果:

cylindricity x 调试效果:
描述目标投影沿 X 轴的球形程度。该值的范围为 0 到 1 ,其中 1 为球形。如果该值设置为 1 ,圆柱度 Y 值设置为 0 ,则投影将沿 X 轴形成圆柱。如下所示:

cylindricity y 调试效果:
描述目标投影沿 Y 轴的球形程度。该值的范围为 0 到 1 ,其中 1 为球形。如果该值设置为 1 ,圆柱度 X 值设置为 0 ,则投影将沿 Y 轴形成一个圆柱体。如下所示:

Custom
【功能描述】
采用 custom 变换后,输入图像中的每个多边形都会变换为正方形。换句话说,任何形状的任何四个邻近输入点在转换后都是正方形,如下图所示。但是,多边形的形状和位置在变换后会发生变化。

它们用于创建任何提供的转换都无法描述的转换。为了纠正任意失真,必须向 GDC 工具提供一个特殊的校准文件。如下图:

【成员说明】
| 成员 | 含义 |
|---|---|
| int32_t pan | 水平方向通过给定的像素数,偏移变换网格 |
| int32_t tilt | 垂直方向通过给定的像素数,偏移变换网格 |
| zoom | 按提供的因子缩放转换输出 |
| char custom_file[128] | 采样点文件名称 |
| custom_tranformation_t custom | 解析的自定义转换结构 |
采样点文件解释
采样点文件规则:
第一行是在像素计算中使能 full tile, 1 是 enable, 0 是 disable。
第二行是如果使能了 full tile,则要跳过的像素数量;这些值需要大于 0 ,数字越小, libgdc 的性能越慢(性能越慢是指 libgdc 生成的 bin 文件的大小更大, libgdc 生成 bin 的时间更长 )。
第三行是垂直方向和水平方向采样点的个数, 第一个值 Y = 1081 指的是垂直方向有 1081 个采样点,第二个值 X = 1921 指的水平是方向有 1921 个采样点。
第四行是选中区域的中心点,通常是 (Y-1)/2 、(X-1)/2 。
采样点必须是大于等于 0 的 int 或 float 类型、相邻两行的采样点不能重复。
eg. 下图是截取的其中的一部分数据图片,第五行到第九行就是采样点在源图的坐标值,格式是 Y: X。以下图为例,一共有 1081x1921 个采样点。

由于采样点必须是等距离的,这意味着输出图片的分辨率取决于采样点的点数。

eg. 输出图片的 Width = 100 , Height 计算为 340 ,计算过程如下: 100/height = (96-1)/(324-1)
下图是更简单的 3x3 坐标点转换的示例图:

降采样
skip_point函数用来判断当前点是否可以跳过,以达到降采样的目的。
注意宽高为实际宽高加1:width + 1, height + 1
uint32_t skip_point(uint32_t width, uint32_t height, uint32_t x, uint32_t y)
{
const uint32_t sample_points = 32;
uint32_t step_x = floor((ceil(((float)width) / (sample_points - 4)) + 1) / 2.) * 2;
uint32_t step_y = floor((ceil(((float)height) / (sample_points - 4)) + 1) / 2.) * 2;
uint32_t grid_fit_x = ((x % step_x == step_x / 2) || (x - 1) % step_x == step_x / 2 ||
(x % step_x == 0) || (x - 1) % step_x == 0 || x == 0 || x == 1);
uint32_t grid_fit_y = ((y % step_y == step_y / 2) || (y - 1) % step_y == step_y / 2 ||
(y % step_y == 0) || (y - 1) % step_y == 0 || y == 0 || y == 1);
return !((grid_fit_x && grid_fit_y) || (x >= width - 2) || (y >= height - 2));
}
使用举例,以下对宽608,高600采样点做降采样:
int row_start = 0, row_end = 601;
int col_start = 0, col_end = 609;
int necessary_point = 1;
for (int i = row_start; i < row_end; i++) {
for (int j = col_start; j < col_end; j++) {
int x = j - col_start;
int y = i - row_start;
necessary_point = skip_point(col_end - col_start, row_end - row_start, x, y);
if (necessary_point) {
//idx_x, idx_y为采样点坐标
file_out << idx_y[i * 609 + j] << ":" << idx_x[i * 609 + j] << " "; //必要点,写到采样点文件中
} else {
file_out << 0.0 << ":" << 0.0 << " "; //非必要点,写0到采样点文件,相当于跳过该点
}
}
file_out << std::endl;
}
Keystone+dewarping
【功能描述】

【成员说明】
| 成员 | 含义 |
|---|---|
| int32_t pan | 水平方向通过给定的像素数,偏移变换网格 |
| int32_t tilt | 垂直方向通过给定的像素数,偏移变换网格 |
| zoom | 按提供的因子缩放转换输出 |
| double angle(rotation) | 图像旋转的角度 |
| double elevation | 定义了投影轴的仰角,范围 0 到 90 |
| double azimuth | 定义了投影轴的方位角度。如果仰角参数 elevation 为 0 ,则方位角将没有可见效果 |
| int32_t keep_ratio | 当“保持比率”参数打开时, FOV 高度参数将被忽略,其值将自动计算,以在水平和垂直方向上保持相同的拉伸强度 |
| double FOV_h | 描述水平维度中输出视图字段的大小( 以度为单位 )。有效值的范围是从 0 到 180 |
| double FOV_w | 描述垂直维度中输出视图字段的大小( 以度为单位 )。有效值的范围是从 0 到 180 |
| double cylindricity_y | 描述目标投影沿 Y 轴的球面度( 范围 0 到 1 )。 1 表示球形。如果此值为 1 而 cylindricity_x 为 0 ,则投影沿 Y 轴形成圆柱体 |
| double cylindricity_x | 描述目标投影沿 X 轴的球面度( 范围 0 到 1 )。 1 表示球形。如果此值为 1 而 cylindricity_y 为 0 ,则投影沿 X 轴形成圆柱体 |
| double trapezoid_left_angle | 默认 90 ;范围 0.1 到 90 。变换网格中,左边边界相对于底边边界的角度,见实际效果 |
| double trapezoid_right_angle | 默认 90 ;范围 0.1 到 90 。变换网格中,右边边界相对于底边边界的角度,见实际效果 |
变换模式参数说明
配置文件可由 GDC tool 生成,以 layout.json 存在。不同的变换模式有不同的参数,以 custom 模式和 keystone+dewarping 模式为例,说明配置参数。
keystone+dewarping 模式
{
"inputRes": [
1920, -- 输入图像尺寸的宽
1080 -- 输入图像尺寸的高
],
"param": {
"fov": 180, -- 输入图像的视场角
"diameter": 1080, -- 输入图像的直径,可控制变换网格的整体大小
"offsetX": 0, -- 变换网格在水平方向的偏移
"offsetY": 0 -- 变换网格在垂直方向的偏移
},
"outputRes": [
1920, -- 输出图像尺寸的宽
1080 -- 输出图像尺寸的高
],
"transformations": [
{
"transformation": "Dewarp_keystone", -- 变换模式
"position": [ -- 输出图像的 ROI 区域设定
0, -- 输出图像的 ROI 水平方向的偏移
0, -- 输出图像的 ROI 垂直方向的偏移
1920, -- 输出图像的 ROI 的宽
1080 -- 输出图像的 ROI 的高
],
"param": {
"left_base_angle": 90, -- 默认 90 ; 0.1 到 90 ;变换网格中,左边边界相对于底边边界的角度
"right_base_angle": 90, -- 默认 90 ; 0.1 到 90 ;变换网格中,右边边界相对于底边边界的角度
"azimuth": 90, -- 定义了投影轴的方位角度。如果仰角参数 elevation 为 0 ,则方位角将没有可见效果
"elevation": 0, -- 定义了投影轴的仰角,范围 0 到 90
"rotation": 0, -- 输出图像要旋转的角度
"fovWidth": 90, -- 描述水平维度中输出视图字段的大小( 以度为单位 )。数值越大,变换网格水平方向越宽,有效值的范围是从 0 到 180
"fovHeight": 90, -- 描述垂直维度中输出视图字段的大小( 以度为单位 )。数值越大,变换网格垂直方向越宽,有效值的范围是从 0 到 180
"keepRatio": 0, -- 当“保持比率”参数为 1 时候, fovHeight 参数将被忽略,其值将自动计算,以在水平和垂直方向上保持相同的拉伸强度
"cylindricityX": 1, -- 描述目标投影沿 X 轴的球面度。此值从 0 到 1 ,其中 1 是球形的。如果此值设置为 1 ,并且“圆柱度 Y”值设置为 0 ,则投影将沿 X 轴形成圆柱体。
"cylindricityY": 1 -- 描述目标投影沿 Y 轴的球面度。此值从 0 到 1 ,其中 1 是球形的。如果此值设置为 1 ,并且“圆柱度 X”值设置为 0 ,则投影将沿 Y 轴形成圆柱体。
},
"ptz": [
0, --pan 参数
0, --tile 参数
1 --zoom 参数
],
"roi": { -- 输入图像 ROI 区域设定
"x": 0, -- 输入图像 ROI 区域的水平方向偏移
"y": 0, -- 输入图像 ROI 区域的垂直方向偏移
"w": 1920, -- 输入图像 ROI 区域的宽
"h": 1080 -- 输入图像 ROI 区域的高
}
}
],
"mode": "semiplanar420", -- 处理的格式设定
"eccMode": "eccDisabled", -- 处理的 ecc 模式
"colourspace": "yuv" -- 处理的数据格式
}
custom 模式
{
"inputRes": [
1280, -- 输入图像尺寸的宽
720 -- 输入图像尺寸的高
],
"param": {
"fov": 192, -- 输入图像的视场角
"diameter": 720, -- 输入图像的直径,可控制变换网格的整体大小
"offsetX": 0, -- 变换网格在水平方向的偏移
"offsetY": 0 -- 变换网格在垂直方向的偏移
},
"outputRes": [
560, -- 输出图像尺寸的宽
258 -- 输出图像尺寸的高
],
"transformations": [
{
"transformation": "Custom", -- 变换模式
"position": [ -- 输出图像的 ROI 区域设定
0, -- 输出图像的 ROI 水平方向的偏移
0, -- 输出图像的 ROI 垂直方向的偏移
560, -- 输出图像的 ROI 的宽,小于等于 outputRes 的宽
258 -- 输出图像的 ROI 的高,小于等于 outputRes 的高
],
"ptz": [
0, --pan 参数
0, --tile 参数
1 --zoom 参数
],
"roi": { --custom 模式下无效
"x": 0, --custom 模式下无效
"y": 0, --custom 模式下无效
"w": 0, --custom 模式下无效
"h": 0 --custom 模式下无效
},
"param": {
"customTransformation": "/path_to/camera_0_gdc.txt" -- 坐标点文件的在板子中的路径
}
}
],
"mode": "semiplanar420", -- 处理的格式设定
"eccMode": "eccDisabled", -- 处理的 ecc 模式
"colourspace": "yuv" -- 处理的数据格式
}
1. ecc mode 统一填写 ecc is disable。可选 ecc mode 使能,但没有实际效果。
2. 当参数为小数时,保证精度为浮点运算以后 8 位小数及以上,否则可能生成的 bin 不一致。
3. 用户填充数据结构或者 json 时填充的信息应该包含各种模式示例所有项。
4. 非 custom 模式,配置文件中的 roi 参数代表输入图片的 roi。
5. 配置文件中的 position 参数代表输出图片的 roi。
Affine
配置文件内容如下:
{
"inputRes": [
1920,
1080
],
"param": {
"fov": 160,
"diameter": 1080,
"offsetX": 0,
"offsetY": 0
},
"outputRes": [
1920,
1080
],
"transformations": [
{
"transformation": "Affine",
"position": [
0,
0,
1920,
1080
],
"param": {
"rotation": 0
},
"ptz": [
0,
0,
1
],
"roi": {
"x": 0,
"y": 0,
"w": 1920,
"h": 1080
}
}
],
"mode": "semiplanar420",
"eccMode": "eccDisabled",
"colourspace": "yuv"
}
输入图片加变换网格如下:

输出图片如下:

Equisolid
配置文件内容如下:
{
"inputRes": [
1920,
1080
],
"param": {
"fov": 160,
"diameter": 1080,
"offsetX": 0,
"offsetY": 0
},
"outputRes": [
1920,
1080
],
"transformations": [
{
"transformation": "Panoramic",
"position": [
0,
0,
1920,
1080
],
"param": {
"strength": 1,
"strengthY": 1,
"rotation": 0
},
"ptz": [
0,
0,
1
],
"roi": {
"x": 0,
"y": 0,
"w": 1920,
"h": 1080
}
}
],
"mode": "semiplanar420",
"eccMode": "eccDisabled",
"colourspace": "yuv"
}
输入图片加变换网格如下:

输出图片如下:

Equisolid(cylinder)
配置文件内容如下:
{
"inputRes": [
1920,
1080
],
"param": {
"fov": 160,
"diameter": 1080,
"offsetX": 0,
"offsetY": 0
},
"outputRes": [
1920,
1080
],
"transformations": [
{
"transformation": "Stereographic",
"position": [
0,
0,
1920,
1080
],
"param": {
"strength": 1,
"rotation": 0
},
"ptz": [
0,
0,
1
],
"roi": {
"x": 0,
"y": 0,
"w": 1920,
"h": 1080
}
}
],
"mode": "semiplanar420",
"eccMode": "eccDisabled",
"colourspace": "yuv"
}
输入图片加变换网格如下:

输出图片如下:

Equidistant
配置文件内容如下:
{
"inputRes": [
1920,
1080
],
"param": {
"fov": 160,
"diameter": 1080,
"offsetX": 0,
"offsetY": 0
},
"outputRes": [
1920,
1080
],
"transformations": [
{
"transformation": "Universal",
"position": [
0,
0,
1920,
1080
],
"param": {
"azimuth": 0,
"elevation": 0,
"rotation": 0,
"fovWidth": 90,
"fovHeight": 90,
"keepRatio": 0,
"cylindricityX": 1,
"cylindricityY": 1
},
"ptz": [
0,
0,
1
],
"roi": {
"x": 0,
"y": 0,
"w": 1920,
"h": 1080
}
}
],
"mode": "semiplanar420",
"eccMode": "eccDisabled",
"colourspace": "yuv"
}
输入图片加变换网格如下:

输出图片如下:

Custom
输入 1280x720 ,输出 560x258 。配置文件内容如下:
{
"inputRes": [
1280,
720
],
"param": {
"fov": 192,
"diameter": 720,
"offsetX": 0,
"offsetY": 0
},
"outputRes": [
560,
258
],
"transformations": [
{
"transformation": "Custom",
"position": [
0,
0,
560,
258
],
"ptz": [
0,
0,
1
],
"roi": {
"x": 0,
"y": 0,
"w": 1280,
"h": 720
},
"param": {
"customTransformation": "/path_to/camera_0_gdc_config_3.1.txt"
}
}
],
"mode": "semiplanar420",
"eccMode": "eccDisabled",
"colourspace": "yuv"
}
输入图片加变换网格如下:

输出图片如下:

Keystone+dewarping
配置文件内容如下:
{
"inputRes": [
1920,
1080
],
"param": {
"fov": 180,
"diameter": 1080,
"offsetX": 0,
"offsetY": 0
},
"outputRes": [
1920,
1080
],
"transformations": [
{
"transformation": "Dewarp_keystone",
"position": [
0,
0,
1920,
1080
],
"param": {
"left_base_angle": 90,
"right_base_angle": 90,
"azimuth": 0,
"elevation": 0,
"rotation": 0,
"fovWidth": 90,
"fovHeight": 90,
"keepRatio": 0,
"cylindricityX": 1,
"cylindricityY": 1
},
"ptz": [
0,
0,
1
],
"roi": {
"x": 0,
"y": 0,
"w": 1920,
"h": 1080
}
}
],
"mode": "semiplanar420",
"eccMode": "eccDisabled",
"colourspace": "yuv"
}
输入图片加变换网格如下:

输出图片如下:
