(1)ISP: image signal process,图像信号处理(现今一般指数字图像信号处理)
image signal processor 图像信号处理器
ISP(Image Signal Processing) 图像信号处理。主要用来对前端图像传感器输出信号处理的单元,以匹配不同厂商的图象传感器。相机用图像处理器ISP(Image Signal Processor)。
(2)思考:什么是图像信号?
图像信号是通过光电器件和扫描产生的电信号代表图像的亮度信息。
(3)为什么需要处理?
器件或环境不理想导致图像不理想,譬如过曝光、不通透、坏点
(4)如何处理?
使用针对性算法对原始图像数据做运算处理。先天(器件、环境)不行,后天(算法)来补
(5)ISP的本质:用采集后的数字图像的运算处理修补前端的不理想,尽量提升图像质量
(6)ISP处理器:核心是数字运算能力
(1)镜头->sensor->ISP->VIU->…
(2)ISP单元可以在sensor中,或者独立,或集成到AP SoC中,现在大多在AP(Application processor)中
(3)HI3518E中内置ISP单元
(1)image quality,图像质量
(2)浅层次的图像质量问题:坏点、畸变、条纹、局部不清晰等
(3)高层次的图像质量问题:通透性、锐度、色彩饱满度、色彩还原度等
通透性:图片的清晰度,通透性低的话看起来模糊,
锐度:图片中物理的轮廓,如果很低会导致轮廓不清晰
色彩饱和度:颜色的鲜艳程度
色彩还原度:颜色的真实性
(1)IQ是目的,ISP是手段,调试是方法
(2)掌握ISP和IQ调试的关键:相关概念、海思MPP中ISP的实现、PQTool工具
(1)《HiISP开发参考》 与 《ISP_3A开发指南》
链接:https://pan.baidu.com/s/1KZqnKOG7h0TjOJLWLuogkg
提取码:q0o6
--来自百度网盘超级会员V5的分享
(2)重点是ISP的框架架构和软件流程
ISP 通过一系列数字图像处理算法完成对数字图像的效果处理。主要包括 3A(AE 自动曝光 AF 自动对焦 AWB 自动白平衡)、坏点校正、去噪、强光抑制、背光补偿、色彩增强、镜头阴影校正等处理。 ISP 包括逻辑部分以及运行在其上的 firmware。
lens 将光信号投射到 sensor 的感光区域后, sensor 经过光电转换,将 Bayer 格式的原始图像送给 ISP, ISP 经过算法处理,输出 RGB 空间域的图像给后端的视频采集单元。在这个过程中, ISP 通过运行在其上的 firmware 对 ISP逻辑, lens 和 sensor 进行相应控制,进而完成自动光圈、自动曝光、自动白平衡等功能。其中, firmware 的运转靠视频采集单元的中断驱动。 PQ Tools 工具通过网口或者串口完成对 ISP 的在线图像质量调节。
ISP 由 ISP 逻辑及运行在其上的 Firmware 组成,逻辑单元除了完成一部分算法处理外,还可以统计出当前图像的实时信息。 Firmware 通过获取 ISP 逻辑的图像统计信息,重新计算,反馈控制 lens、 sensor 和 ISP 逻辑,以达到自动调节图像质量的目的。
过曝光:进光太多
lens:镜头距离sensor的距离,不过我的开发板使用的镜头是固定的,焦距是固定的,
不可变
(3)ISP 作为前端采集部分,需要和视频采集单元( VIU)协同工作。 ISP 初始化和基本配置完成后,需要 VIU 进行接口时序匹配。一是为了匹配不同 sensor 的输入时序,二是为 ISP 配置正确的输入时序。待时序配置完成后, ISP 就可以启动 Run 来进行动态图像质量调节。此时输出的图像被 VIU 采集,进而送去显示或编码。
PQ Tools 工具主要完成在 PC 端进行动态图像质量调节,可以调节多个影响图像质量的因子,如去噪强度、色彩转换矩阵、饱和度等。
如果用户调试好图像效果后,可以使用 PQ Tools 工具提供的配置文件保存功能进行配置参数保存。在下次启动时系统可以使用 PQ Tools 工具提供的配置文件加载功能加载已经调节好的图像参数。
(1)核心代码在SAMPLE_COMM_ISP_Init函数中(mpp/sample/common/sample_comm_isp.c)
分析使用的源码在以往文章中任意选择一个皆可,我就不重复提供了。
(2)注意对照上边所讲述的架构来理解代码
参考学习:
图像sensor的特性和驱动解析(1)
图像sensor的特性和驱动解析(2)
main
SAMPLE_VENC_720P_CLASSIC
SAMPLE_COMM_VI_StartVi
SAMPLE_COMM_VI_StartIspAndVi
SAMPLE_COMM_ISP_Init
sensor_register_callback //sensor注册回调函数
cmos_init_sensor_exp_function //进行一些初始化,接口对接
HI_MPI_ISP_SensorRegCallBack //sensor向isp基础算法库注册回调函数
cmos_init_ae_exp_function
HI_MPI_AE_SensorRegCallBack//sensor向AE算法库注
cmos_init_awb_exp_function
HI_MPI_AWB_SensorRegCallBack//sensor向AWB算法库注
HI_MPI_AE_Register //AE算法库向isp基础算法库注册
HI_MPI_AWB_Register //AWB算法库向isp基础算法库注册
HI_MPI_AF_Register //AF算法库向isp基础算法库注册
HI_MPI_ISP_MemInit //初始化 ISP 外部寄存器。
HI_MPI_ISP_SetWDRMode //设置宽动态模式
HI_MPI_ISP_SetPubAttr //设置 ISP 公共属性
HI_MPI_ISP_Init //初始化 ISP firmware。
SAMPLE_COMM_ISP_Run
Test_ISP_Run
HI_MPI_ISP_Run// 运行 ISP firmware。
HI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc)
{
memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S));
pstSensorExpFunc->pfn_cmos_sensor_init = sensor_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = sensor_exit;
pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init;//初始化一些全局参数
pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode;//向sensor设置image mode;
pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode;//操作sensor的寄存器
pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default;//读取isp默认配置参数
pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_isp_black_level;//黑电平处理
pstSensorExpFunc->pfn_cmos_set_pixel_detect = cmos_set_pixel_detect;
pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info;
return 0;
}
static ISP_CMOS_DRC_S g_stIspDrc =//这些参数也是我们之后调参修改的
{
0,
10,
0,
2,
192,
60,
0,
0,
0,
{1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024}
};
HI_U32 cmos_get_isp_default(ISP_CMOS_DEFAULT_S *pstDef)
{
if (HI_NULL == pstDef)
{
printf("null pointer when get isp default value!\n");
return -1;
}
memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S));
switch (genSensorMode)
{
default:
case WDR_MODE_NONE:
memcpy(&pstDef->stDrc, &g_stIspDrc, sizeof(ISP_CMOS_DRC_S));
memcpy(&pstDef->stDemosaic, &g_stIspDemosaicLin, sizeof(ISP_CMOS_DEMOSAIC_S));
memcpy(&pstDef->stGe, &g_stIspGeLin, sizeof(ISP_CMOS_GE_S));
pstDef->stNoiseTbl.stNrCaliPara.u8CalicoefRow = DMNR_CALIB_CARVE_NUM_AR0130;
pstDef->stNoiseTbl.stNrCaliPara.pCalibcoef = (HI_FLOAT (*)[4])g_coef_calib_ar0130;
//memcpy(&pstDef->stNoiseTbl.stNrCommPara, &g_stNrCommPara,sizeof(ISP_NR_COMM_PARA_S));
memcpy(&pstDef->stNoiseTbl.stIsoParaTable[0], &g_stNrIsoParaTab[0],sizeof(ISP_NR_ISO_PARA_TABLE_S)*HI_ISP_NR_ISO_LEVEL_MAX);
memcpy(&pstDef->stRgbSharpen, &g_stIspRgbSharpen, sizeof(ISP_CMOS_RGBSHARPEN_S));
memcpy(&pstDef->stUvnr, &g_stIspUVNR, sizeof(ISP_CMOS_UVNR_S));
memcpy(&pstDef->stDpc, &g_stCmosDpc, sizeof(ISP_CMOS_DPC_S));
break;
}
pstDef->stSensorMaxResolution.u32MaxWidth = 1280;
pstDef->stSensorMaxResolution.u32MaxHeight = 720;
return 0;
}
关于这部分代码要想理解的很深刻,只能自己对着数据手册去分析代码!个人精力有限,就不去做这部分工作了,我目前的实际开发也不需要去做,只能宏观理解,抓大放小了。
注:本文章参考了《朱老师物联网大讲堂》课程笔记,并结合了自己的实际开发经历以及网上他人的技术文章,综合整理得到。如有侵权,联系删除!水平有限,欢迎各位在评论区交流。