4. LSC参数数据结构:RK平台LSC参数表格式与增益量化
在瑞芯微RK平台ISP调试中,LSC(Lens Shading Correction)阴影校正参数以结构体 struct rkisp_lsc_config 为核心载体。理解该结构体的内存布局、增益量化方式及存储格式,是进行高效调试与固件集成的关键前提。本章将深入解析该数据结构的每一个字段,并揭示增益值从浮点运算到定点存储的完整映射过程。
4.1 核心数据结构:struct rkisp_lsc_config
该结构体定义于内核头文件 rkisp1-config.h 或 rkisp2-config.h 中,根据芯片代际略有差异,但核心字段保持一致。下表列出了RK3588/RK356x系列通用的LSC配置结构体成员:
| 字段名 | 数据类型 | 描述 | 调试影响 |
|---|---|---|---|
sector_size |
struct isp2x_cif_isp_lsc_sector_size |
定义每个扇区(Sector)的宽度和高度(像素单位) | 决定校正网格的密度,直接影响校正精度与计算开销 |
config_addr |
u32 |
LSC配置表在ISP内部SRAM/DDR中的基地址 | 驱动层DMA搬运的起始地址,调试时需确保内存对齐 |
gain_table |
u16 * |
指向增益表的指针,存储所有扇区顶点的增益值 | 用户态传递增益数据的核心通道 |
gain_table_len |
u32 |
增益表的长度(以u16为单位) | 校验数据完整性,防止越界访问 |
sector_count_x |
u8 |
水平方向扇区数量 | 与sensor分辨率相关,典型值为15~17 |
sector_count_y |
u8 |
垂直方向扇区数量 | 与sensor分辨率相关,典型值为11~13 |
vignetting_en |
u8 |
渐晕校正使能标志 | 调试阶段建议置1,关闭则旁路LSC |
sector_count_x 和 sector_count_y 通常由ISP驱动根据输入分辨率自动计算,但用户态可通过 struct rkisp_lsc_config 覆盖默认值。建议在首次调试时保持驱动默认值,仅调整增益表内容。
4.2 扇区划分与网格结构
LSC校正基于“网格插值”模型:将图像传感器平面划分为M×N个矩形扇区,每个扇区的四个顶点存储一个增益值。ISP硬件在运行时,根据像素坐标所在的扇区,对四个顶点的增益进行双线性插值,得到该像素的最终增益。
上图展示了6×6的扇区网格(实际应用中通常为17×13或15×11)。每个蓝色/绿色/橙色等节点代表一个增益顶点,顶点总数 = (sector_count_x + 1) × (sector_count_y + 1)。
4.3 增益值量化与定点存储
RK平台LSC增益采用 Q4.8定点格式 存储,即1个符号位 + 4位整数位 + 8位小数位,总宽度16位(u16)。这种格式在精度与存储效率之间取得了平衡。
4.3.1 量化公式
从浮点增益到定点存储的转换公式如下:
// 浮点增益 → 定点存储
uint16_t gain_q48 = (uint16_t)(round(gain_float * 256.0f));
// 定点存储 → 浮点增益
float gain_float = (float)gain_q48 / 256.0f;
其中,256.0f 对应2^8,即8位小数部分的缩放因子。
4.3.2 量化范围与精度
| 参数 | 值 | 说明 |
|---|---|---|
| 整数位宽 | 4 bit | 最大整数部分为15 |
| 小数位宽 | 8 bit | 量化步长 = 1/256 ≈ 0.0039 |
| 最大可表示增益 | 15.9961 | 实际调试中增益通常不超过4.0 |
| 最小可表示增益 | 0.0039 | 小于1.0的增益用于减光校正 |
| 量化误差 | ±0.00195 | 对8bit图像而言,误差可忽略 |
4.4 增益表内存布局
增益表 gain_table 是一个一维数组,按 行优先(Row-major) 顺序存储所有顶点的增益值。假设网格有 W = sector_count_x + 1 列,H = sector_count_y + 1 行,则顶点 (row, col) 对应的数组索引为:
index = row * W + col
以下代码展示了如何填充一个5×4网格的增益表(实际项目中通常使用17×13网格):
#define SECTOR_X 4 // 水平扇区数
#define SECTOR_Y 3 // 垂直扇区数
#define GRID_W (SECTOR_X + 1) // 5
#define GRID_H (SECTOR_Y + 1) // 4
uint16_t gain_table[GRID_H * GRID_W];
// 假设中心增益为1.0,边缘增益为2.0
float center_gain = 1.0f;
float edge_gain = 2.0f;
for (int row = 0; row < GRID_H; row++) {
for (int col = 0; col < GRID_W; col++) {
// 计算归一化距离(0~1),中心为0,边缘为1
float dx = (float)col / (GRID_W - 1) - 0.5f;
float dy = (float)row / (GRID_H - 1) - 0.5f;
float dist = sqrtf(dx * dx + dy * dy) * 2.0f; // 归一化到0~1
// 线性插值增益
float gain = center_gain + (edge_gain - center_gain) * dist;
// 量化到Q4.8格式
gain_table[row * GRID_W + col] = (uint16_t)(gain * 256.0f + 0.5f);
}
}
4.5 增益值存储的字节序与对齐
RK平台ISP硬件采用 小端字节序(Little-Endian)。在ARM64架构的RK芯片上,uint16_t 的低字节存储在低地址,高字节存储在高地址。驱动层通过DMA将增益表搬运到ISP内部SRAM时,要求增益表基地址 32字节对齐,以满足AXI总线突发传输要求。
V4L2_CID_ISP_LSC_CONFIG)传递增益表时,必须确保 gain_table 指针指向的内存是 dma_alloc_coherent 分配的连续物理内存,或者使用 dma_buf 机制。使用普通的 malloc 堆内存会导致DMA传输错误,表现为图像出现条纹或校正失效。
4.6 数据结构与ISP硬件流水线的交互流程
下图展示了从用户态配置到ISP硬件执行的完整数据流:
4.7 多通道与Bayer分量的增益独立存储
对于Bayer格式的RAW图像,RK平台LSC支持对 R、Gr、Gb、B 四个通道分别存储增益表。在 struct rkisp_lsc_config 中,通过 gain_table 指针指向一个包含4个通道增益表的连续内存块:
// 内存布局:| R通道增益表 | Gr通道增益表 | Gb通道增益表 | B通道增益表 |
// 每个通道的增益表大小相同,均为 GRID_H * GRID_W 个 u16
uint16_t *r_gain = gain_table;
uint16_t *gr_gain = gain_table + (GRID_H * GRID_W);
uint16_t *gb_gain = gain_table + 2 * (GRID_H * GRID_W);
uint16_t *b_gain = gain_table + 3 * (GRID_H * GRID_W);
| 通道 | 偏移量(u16单位) | 典型增益范围 | 调试关注点 |
|---|---|---|---|
| R | 0 | 1.0 ~ 3.5 | 红色通道衰减通常最大,增益值最高 |
| Gr | GRID_H * GRID_W | 1.0 ~ 2.5 | 与Gb通道的差异反映水平渐晕 |
| Gb | 2 * GRID_H * GRID_W | 1.0 ~ 2.5 | 与Gr通道的差异反映垂直渐晕 |
| B | 3 * GRID_H * GRID_W | 1.0 ~ 3.0 | 蓝色通道衰减通常介于R和G之间 |
4.8 数据结构版本差异(RK356x vs RK3588)
不同RK芯片代际的LSC结构体存在细微差异,调试时需根据目标平台选择对应的头文件:
| 芯片平台 | 头文件路径 | 结构体名称 | 差异点 |
|---|---|---|---|
| RK3566/RK3568 | include/uapi/linux/rkisp1-config.h |
rkisp1_isp_lsc_config |
扇区数量固定为17×13,增益表使用Q4.8格式 |
| RK3588/RK3576 | include/uapi/linux/rkisp2-config.h |
rkisp2_cif_isp_lsc_config |
扇区数量可配置(最大33×25),支持增益表动态重载 |
| RK3528 | include/uapi/linux/rkisp1-config.h |
rkisp1_isp_lsc_config |
与RK356x兼容,但增益表长度需按分辨率计算 |
struct rkisp_lsc_config 的 sector_count_x 和 sector_count_y 字段可能被驱动忽略,强制使用默认值。务必查阅目标芯片的 TRM(技术参考手册)确认字段有效性。
4.9 本章小结
- 核心结构体:
struct rkisp_lsc_config包含扇区尺寸、增益表指针、扇区数量、使能标志等字段,是用户态与驱动交互的唯一接口。 - 增益量化:采用Q4.8定点格式(u16),浮点增益乘以256后取整存储,精度为1/256。
- 内存布局:增益表按行优先存储,四个Bayer通道的增益表连续排列,每个通道占用
(sector_count_x+1) × (sector_count_y+1)个u16。 - 硬件交互:增益表通过DMA搬运到ISP内部SRAM,硬件在每帧VSYNC后加载并执行双线性插值。
- 平台差异:RK356x与RK3588在结构体字段和扇区灵活性上存在差异,调试前需确认目标平台。