OPPO相机相关

1. 相机驱动开发

https://blog.csdn.net/weixin_45023644/article/details/116016176

一、修改文件和内容简述

文件路径 控制内容
device/mediatek/common/kernel-headers/kd_imgsensor.h 定义设备的SENSOR_ID和SENSOR_DRVNAME
device/mediateksample/k65v1_64_bsp/ProjectConfig.mk 配置系统前后摄的名称和镜头,修改要全编译。
kernel-4.9/arch/arm64/configs/k65v1_64_bsp_defconfig 配置用户CONFIG_CUSTOM_KERNEL_IMGSENSOR的名称
kernel-4.9/arch/arm64/configs/k65v1_64_bsp_debug_defconfig 为debug配置用户CONFIG_CUSTOM_KERNEL_IMGSENSOR的名称
kernel-4.9/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor.h 内核定义设备的SENSOR_ID和SENSOR_DRVNAME
kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_hw.c 内核定义设备识别方法和顺序
kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.c 内核定义驱动文件夹的宏对应驱动接口,注意大小写
kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.h 内核引用驱动函数声明
kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/ov5648sub_mipi_raw/ov5648submipi_Sensor.c 添加驱动文件夹以及驱动文件
kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/ov5648sub_mipi_raw/ov5648submipi_Sensor.h 添加驱动文件夹以及驱动文件
kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/ov5648sub_mipi_raw/Makefile 内核驱动编译文件添加obj-y +=XXX.o
kernel-4.9/drivers/misc/mediatek/lens/main/common/dw9718af/DW9718AF.c 添加可能的主镜头文件
kernel-4.9/drivers/misc/mediatek/lens/sub/common/dw9718af/DW9718AF.c 添加可能的前摄镜头文件
vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/cfg_setting_imgsensor.cpp 调整镜头旋转方向角度0、90、180、270
vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/sensorlist.cpp HaL定义设备的SENSOR_ID和SENSOR_DRVNAME
vendor/mediatek/proprietary/custom/mt6765/hal/lens/src/lenslist.cpp 镜头类型对应
vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_metadata/ov5648sub_mipi_raw 镜头参数文件
vendor/mediatek/proprietary/custom/mt6765/hal/sendepfeature/ov5648sub_mipi_raw/config.ftbl.ov5648_mipi_raw.h 镜头参数文件
vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor/ver1/ov5648sub_mipi_raw/ 镜头参数文件夹
vendor/mediatek/proprietary/custom/mt6765/hal/camera_3a/ver1/isp_tuning_custom.cpp 镜头参数文件
vendor/mediatek/proprietary/custom/mt6765/hal/camera_3a/ver1/isp_tuning_custom.cpp 镜头参数文件

二、device配置

1、修改SENSOR_ID和驱动名称

文件位置:

device/mediatek/common/kernel-headers/kd_imgsensor.h

码示例:

#define OV5648SUBMIPI_SENSOR_ID 0x5648
......
#define SENSOR_DRVNAME_OV5648SUB_MIPI_RAW "ov5648sub_mipi_raw"

2、修改系统配置

文件位置:

device/mediateksample/k65v1_64_bsp/ProjectConfig.mk
注意:该文件修改后全编译才可以生效,文件夹名称随平台变换。

修改配置:

CUSTOM_HAL_IMGSENSOR = imx214_mipi_raw ov5648sub_mipi_raw
CUSTOM_HAL_LENS = dw9714af dummy_lens 
......
CUSTOM_HAL_SUB_IMGSENSOR = ov5648sub_mipi_raw
CUSTOM_HAL_SUB_LENS = dummy_lens
......
CUSTOM_KERNEL_IMGSENSOR = imx214_mipi_raw ov5648sub_mipi_raw
CUSTOM_KERNEL_LENS = dw9714af dummy_lens
......
CUSTOM_KERNEL_MAIN_IMGSENSOR = imx214_mipi_raw
CUSTOM_KERNEL_MAIN_LENS = dw9714af 
......
CUSTOM_KERNEL_SUB_IMGSENSOR = ov5648sub_mipi_raw
CUSTOM_KERNEL_SUB_LENS = dummy_lens

3、修改用户配置

文件位置:

kernel-4.9/arch/arm64/configs/k65v1_64_bsp_defconfig
kernel-4.9/arch/arm64/configs/k65v1_64_bsp_debug_defconfig
注意:该文件修改后不需要全编译,文件夹名称随平台变换。带debug的是编译debug版本时候使用,不嫌麻烦就将两个文件都修改了吧。

修改配置:

CONFIG_CUSTOM_KERNEL_IMGSENSOR="imx214_mipi_raw ov5648sub_mipi_raw"
#CONFIG_SPECIFY_IMGSENSOR=y
#CONFIG_IMGSENSOR_MAIN="imx214_mipi_raw"
#CONFIG_IMGSENSOR_SUB="ov5648sub_mipi_raw"

注释的配置是前后摄相同时使用

三、修改内核配置

1、配置ID和名称

文件位置:

kernel-4.9/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor.h

修改配置:

#define OV5648SUBMIPI_SENSOR_ID 0x5648
......
#define SENSOR_DRVNAME_OV5648SUB_MIPI_RAW "ov5648sub_mipi_raw"

2、配置前后相同的摄像头

如果前后摄像头不同,则直接跳过。

mtk android 9.0 camera kernel4.9和以前做了较大改动 特别是上电这一块做了高度集成, 在我们使用前后摄像头相同的情况话有可能会出现前摄像头识别成了后摄像头的情况,导致前摄的lens也误判为后摄的。但是在代码中有集成这块代码,通过宏来做区分,文件路径:

kernel-4.9/drivers/misc/mediatek/imgsensor/inc/kd_imgsensor.h

......
#if defined(CONFIG_IMGSENSOR_MAIN)  || \
                        defined(CONFIG_IMGSENSOR_SUB)        || \
                        defined(CONFIG_IMGSENSOR_MAIN2) || \
                        defined(CONFIG_IMGSENSOR_SUB2) || \
                        defined(CONFIG_IMGSENSOR_MAIN3)


        char *pcustomize_sensor = NULL;
#endif


#if defined(CONFIG_IMGSENSOR_MAIN)  || \
                defined(CONFIG_IMGSENSOR_SUB)   || \
                defined(CONFIG_IMGSENSOR_MAIN2) || \
                defined(CONFIG_IMGSENSOR_SUB2) || \
                defined(CONFIG_IMGSENSOR_MAIN3)

        if (curr_sensor_name == NULL)
                return IMGSENSOR_RETURN_ERROR;

        switch (sensor_idx) {
#ifdef CONFIG_IMGSENSOR_MAIN
        case IMGSENSOR_SENSOR_IDX_MAIN:
                pcustomize_sensor = IMGSENSOR_STRINGIZE(CONFIG_IMGSENSOR_MAIN);
                
                printk("CONFIG_IMGSENSOR_MAIN pcustomize_sensor=%s\n",pcustomize_sensor);
                break;
#endif
#ifdef CONFIG_IMGSENSOR_SUB
        case IMGSENSOR_SENSOR_IDX_SUB:
                pcustomize_sensor = IMGSENSOR_STRINGIZE(CONFIG_IMGSENSOR_SUB);
                printk("CONFIG_IMGSENSOR_SUB pcustomize_sensor=%s\n",pcustomize_sensor);
                break;
#endif
#ifdef CONFIG_IMGSENSOR_MAIN2
        case IMGSENSOR_SENSOR_IDX_MAIN2:
                pcustomize_sensor = IMGSENSOR_STRINGIZE(CONFIG_IMGSENSOR_MAIN2);
                break;
#endif
#ifdef CONFIG_IMGSENSOR_SUB2
        case IMGSENSOR_SENSOR_IDX_SUB2:
                pcustomize_sensor = IMGSENSOR_STRINGIZE(CONFIG_IMGSENSOR_SUB2);
                break;
#endif
#ifdef CONFIG_IMGSENSOR_MAIN3
        case IMGSENSOR_SENSOR_IDX_MAIN3:
                pcustomize_sensor = IMGSENSOR_STRINGIZE(CONFIG_IMGSENSOR_MAIN3);
                break;
#endif
        default:
                break;
        }


        if (pcustomize_sensor != NULL &&
                strlen(pcustomize_sensor) > 2 &&
                !strstr(pcustomize_sensor, curr_sensor_name))
                return IMGSENSOR_RETURN_ERROR;
#else
        if (curr_sensor_name == NULL)
                return IMGSENSOR_RETURN_ERROR;
#endif

3、配置内核驱动接口列表和声明

文件位置:

kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.c //内核定义驱动文件夹的宏对应驱动接口,注意大小写
kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_sensor_list.h //内核引用驱动函数声明

imgsensor_sensor_list.c清单修改或添加配置:

#if defined(OV5648SUB_MIPI_RAW)//大写,对应驱动文件夹名称,文件夹名称为小写
	{OV5648SUBMIPI_SENSOR_ID,//ID名称
	SENSOR_DRVNAME_OV5648SUB_MIPI_RAW,//驱动名称
	OV5648SUBMIPISensorInit},//初始化函数接口名称
#endif

imgsensor_sensor_list.h内核声明:

UINT32 OV5648SUBMIPISensorInit(struct SENSOR_FUNCTION_STRUCT **pfFunc);

4、配置添加内核驱动程序

添加驱动文件夹以及驱动文件路径:

kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/ov5648sub_mipi_raw/ov5648submipi_Sensor.c
kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/ov5648sub_mipi_raw/ov5648submipi_Sensor.h

此文件是驱动核心文件,首先,文件夹的名称要和对应配置的名称。前面已经提及,驱动文件供应商一般都会有提供,但索要程序前请告知的当前平台。其次,我添加进去后看编译是否有.h文件有没有找到,修改对应ID名称、初始化函数名称等。最后,还要怀疑是够有编译到该驱动文件。这里就要说到.make文件了,路径和驱动文件一样:

kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/ov5648sub_mipi_raw/Makefile

文件中添加如下内容:

obj-y += ov5648submipi_Sensor.o

5、添加内核镜头驱动程序

如果程序中已经有对应的镜头驱动,那就跳过此步骤。
添加镜头文件路径:
kernel-4.9/drivers/misc/mediatek/lens/main/common/dw9718af/DW9718AF.c //添加可能的主镜头文件
kernel-4.9/drivers/misc/mediatek/lens/sub/common/dw9718af/DW9718AF.c //添加可能的前摄镜头文件

getSensorOrientation()
{
    static SensorOrientation_T const inst = {
        .u4Degree_0 = 270,   //  main sensor in degree (0, 90, 180, 270)
        .u4Degree_1 = 90,    //  sub  sensor in degree (0, 90, 180, 270)
        .u4Degree_2 = 90,   //  main2 sensor in degree (0, 90, 180, 270)
        .u4Degree_3 = 270,   //  sub2 sensor in degree (0, 90, 180, 270)
        .u4Degree_4 = 90,   //  main3 sensor in degree (0, 90, 180, 270)
    };
    return inst;

}

四、修改摄像头参数

1、修改镜头方向

vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/cfg_setting_imgsensor.cpp

根据硬件结构设计实际方向的调整镜头旋转方向角度,可以选择0、90、180、270度。如果有加速度传感器,就会有自动预览转向的功能。

2、修改HAL层名称定义

HaL定义设备的SENSOR_ID和SENSOR_DRVNAME路径:

vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_src/sensorlist.cpp

增加内容:

......
#if defined(OV5648SUB_MIPI_RAW)
    RAW_INFO(OV5648SUBMIPI_SENSOR_ID, SENSOR_DRVNAME_OV5648SUB_MIPI_RAW, NULL),
#endif

3、修改镜头类型

修改路径:

vendor/mediatek/proprietary/custom/mt6765/hal/lens/src/lenslist.cpp
vendor/mediatek/proprietary/custom/mt6765/hal/lens/dummy_lens

镜头类型对应的清单加入:如果是定焦镜头就选择Dummy,务必保证Hal/lens文件目录下有对应的镜头驱动。
添加的代码如下示例:

MSDK_LENS_INIT_FUNCTION_STRUCT LensList_sub[MAX_NUM_OF_SUPPORT_LENS] =
{
    {DUMMY_SENSOR_ID,   DUMMY_MODULE_ID, DUMMY_LENS_ID,      "Dummy",       pDummy_getDefaultData},
	{IMX214_SENSOR_ID,  DUMMY_MODULE_ID, DW9718AF_LENS_ID,    "DW9718AF", pDW9718AF_getDefaultData},  
	{IMX214SUB_SENSOR_ID,  DUMMY_MODULE_ID, DW9718AF_LENS_ID, "DW9718AF", pDW9718AF_getDefaultData},
    {IMX230SUB_SENSOR_ID,  DUMMY_MODULE_ID, DW9714AF_LENS_ID, "DW9714AF", pDW9714AF_getDefaultData}, 
	+{OV5648SUBMIPI_SENSOR_ID,  DUMMY_MODULE_ID, DUMMY_LENS_ID, "Dummy", pDummy_getDefaultData},   
};

4、修改摄像头主参数

​ 主要的参数可以先使用以前同平台同品牌同型号或类似型号的参数,后面约FAE现场调试,重点要注意修改文件名称和文件中对应的ID和宏名称,其主要有以下几个文件路径:

vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor_metadata/ov5648sub_mipi_raw
vendor/mediatek/proprietary/custom/mt6765/hal/sendepfeature/ov5648sub_mipi_raw/config.ftbl.ov5648_mipi_raw.h
vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor/ver1/ov5648sub_mipi_raw/
vendor/mediatek/proprietary/custom/mt6765/hal/camera_3a/ver1/isp_tuning_custom.cpp
vendor/mediatek/proprietary/custom/mt6765/hal/camera_3a/ver1/isp_tuning_custom.cpp

vendor/mediatek/proprietary/custom/mt6765/hal/imgsensor/ver1/ov5648sub_mipi_raw/的文件夹下的 文件较多,容易编译出问题,除了找供应商索取,也可以使用之前该品牌在像素接近的驱动参数验证。

五、上电配置(参考相应sensor的datasheet)

sensor上电顺序
/drivers/misc/mediatek/imgsensor/src/{platform}/camera_hw/imgsensor_cfg_table.c

struct IMGSENSOR_HW_CFG imgsensor_custom_config[] = {
    {
      IMGSENSOR_SENSOR_IDX_MAIN,
      IMGSENSOR_I2C_DEV_0,
      {
        {IMGSENSOR_HW_ID_MCLK, IMGSENSOR_HW_PIN_MCLK},
        {IMGSENSOR_HW_ID_REGULATOR, IMGSENSOR_HW_PIN_DVDD},
        {IMGSENSOR_HW_ID_GPIO, IMGSENSOR_HW_PIN_AVDD},
        {IMGSENSOR_HW_ID_REGULATOR, IMGSENSOR_HW_PIN_DOVDD},
        {IMGSENSOR_HW_ID_GPIO, IMGSENSOR_HW_PIN_PDN},
        {IMGSENSOR_HW_ID_GPIO, IMGSENSOR_HW_PIN_RST},
        {IMGSENSOR_HW_ID_NONE, IMGSENSOR_HW_PIN_NONE},
      },
    },
    ...
    }
 ...
 ...
 struct IMGSENSOR_HW_POWER_SEQ sensor_power_sequence[] = {
 ...
 \#if defined(GC8034_KXXX_MIPI_RAW)
      {
        SENSOR_DRVNAME_GC8034_KXXX_MIPI_RAW,
        {
          
          {PDN, Vol_Low, 0},
          {RST, Vol_Low, 0},
          {DOVDD, Vol_1800, 1},
          {DVDD, Vol_1200, 1},
          {AVDD, Vol_2800, 1},
          {SensorMCLK, Vol_High, 1},
          {AFVDD, Vol_2800, 1},
          {PDN, Vol_High, 1},
          {RST, Vol_High, 5}
        },
      },
 \#endif
 ...
 }

上面供电配置指明是PMIC直接供电还是LDO供电,sensor供电配置指明上电顺序,电压,延迟时间。
上电顺序、电压是比较重要的,严格按照datasheet上的配置,不然很可能点不亮,延迟时间的话没有绝对,按照datasheet上的适当延迟即可。

1.使用LDO供电的,需要配置GPIO口来控制。

举个例子 AVDD需要LDO供电。首先在原理图上看到AVDD是需要LDO供电,顺着找到其GPIO的编号,查询该平台GPIO表,找到该GPIO编号如W5,其对应是GPIO99,然后在

kernel-4.9 / arch/arm/boot/dts/cust_mt6761_camera.dtsi

直接在里面配置或者在dct tool里面打开dts文件,配置后,会在编译时自动生成dtsi文件。

6. 配置I2C总线

2. 相机原理

数字成像系统流程综述

不同于胶卷相机和单反相机,手机中的Camera已经集成为一个整体的模组,感光sensor(芯片)为核心器件,其它组成器件包括镜头、音圈马达、eeprom等。其中的sensor IC,音圈马达和eeprom需要通过I2C进行控制,图像数据通过MIPI协议进行传输。其基本工作原理为:景物通过镜头生成光学图像投射到图像传感器表面上,产生电信号,经过A/D转换后变为数字图像信号,再将数字图像信号输出至手机的图像处理芯片(ISP)中。

相机模组的主要部件和图像处理关键节点:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jFJWA64n-1667137915688)(数字成像系统流程综述.assets/image-20221020102136528-16662324997013.png)]

​ ISP全称 Image Signal Processing,即图像信号处理,主要用来对前端图像传感器输出信号进行处理,匹配不同厂商的camera模组。事实上,ISP 除了图片上提到的主要功能外,还需要支持 DENOISE,CONTRAST,SATURATION,SHARPNESS 等调整功能,3A技术即自动对焦(AF)、自动曝光(AE)和自动白平衡(AWB) 3A数字成像技术利用了AF自动对焦算法、AE自动曝光算法及AWB自动白平衡算法来实现图像对比度增大、改善相机拍摄物过曝光或曝光不足情况、使画面在不同光线照射下的色差得到补偿,最终呈现出较高画质的图像信息,保证图像具有比较精准的色彩还原度。
在这里插入图片描述

模组结构的剖视图:

img

IR cut filter,即红外截止滤光片,它放在于Lens与Sensor之间。因人眼与CMOS Sensor对各波长的响应不同,人眼看不到红外光但sensor会感应,因此需要IR cut filter隔绝红外光,减少ghost图像,蓝玻璃是用来增加特定波段的蓝光。

模组结构的爆炸图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uylrnYlg-1667137915688)(数字成像系统流程综述.assets/image-20221020102821653-166623290347610-166623290562712.png)]

曝光

快门的工作原理:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ssl4Cew7-1667137915689)(数字成像系统流程综述.assets/image-20221020103153719-166623311534615.png)]
数码相机的快门有两道闸门,分别是:前帘、后帘。如上图所示,靠近镜头的闸门被称为“前帘”,靠近传感器的闸门被称为“后帘”。
在进行拍摄时,后帘从下往上打开,这个时候不会有光量,因为前帘还是闭合的。当后帘从下往上打开,然后前帘从上往下打开,画面从上往下进行曝光,这就是“咔”。等曝光结束后,后帘开始从上往下闭合,后帘闭合之后,整个曝光就结束了,这就是“嚓”。所以拍照时咔嚓、咔嚓、咔嚓的声音就是这么来的。等到前帘闭合后,就可以进行下一次曝光了。相机之所以有两个快门帘,就是为了能从上往下曝光,也能从上往下结束曝光。如果相机只有一个前帘,那么是从上往下开始曝光,当曝光结束就要从下往上了,这就会导致上面的曝光比下面多,如果你用非常快的快门速度进行拍摄,会导致画面的曝光程度不一致。

曝光由光圈、曝光时间、ISO三者共同决定,对于手机以及其他电子产品使用的微型摄像头,光圈大小是固定的,所以手机拍照的曝光由曝光时间和增益 (gain) 来控制。自动曝光就是自动调节曝光时间、光圈、ISO进行曝光,使得所摄物体亮度正常。

对焦马达

对焦马达可分自动对焦AF、对比度对焦CAF和相位对焦PDAF,如果没有对焦功能,则该模组采用定焦FF。
(1)原理
VCM(音圈马达)的Driver IC是使用I2C控制,当AF算法找到焦点步数时,会利用I2C让Driver IC输出电流给VCM,VCM再移动镜头到实际位置。镜头在线圈中,线圈处在磁场中,线圈改变电流大小控制磁场的强弱,移动位置,实现了自动对焦。

镜头(lens)

镜头是将拍摄景物在传感器上成像的器件,它通常由几片透镜组成。从材质上看,摄像头的镜头可分为塑胶透镜和玻璃透镜。
(1)光圈
光圈是安装在镜头上控制通过镜头到达传感器的光线多少的装置,光圈F值越小,光圈越大,进光量越多。
(2)景深
景深是指在摄影机镜头前能够取得清晰图像的成像所测定的被摄物体前后距离范围。光圈越大,景深越小,平时在拍人像时背景朦胧效果就是小景深的一种体现。
(3)焦距
焦距是从镜头的中心点到传感器平面上所形成的清晰影像之间的距离。根据成像原理,镜头的焦距决定了该镜头拍摄的物体在传感器上所形成影像的大小。比如在拍摄同一物体时,焦距越长,就能拍到该物体越大的影像,长焦距类似于望远镜。

Sonser主要分为两种,CMOS和CCD ,目前手机模组里用到的就是CMOS,CMOS图像传感器本质是一块芯片,主要包括:感光区阵列(Bayer阵列,或叫像素阵列)、时序控制、模拟信号处理以及模数转换等模块,主要作用把光信号转化成电信号 ,然后通过ADC 转化成数字信号。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HZnP8ne2-1667137915691)(数字成像系统流程综述.assets/image-20221020112435264-16662362769063.png)]

bayer格式数据排列?
答:Bayer格式是相机内部的原始图片, 即RAW图,是isp处理前的原始图片,由于人眼对绿色较为敏感,所以一般bayer格式的图片绿色格式的像素是r和g像素的和,bayer色彩滤波阵列,由一半的G,1/4的R ,1/4的B组成。

在这里插入图片描述

bayer格式图像传感器硬件:

在这里插入图片描述

Bayer感光阵列示意图:
柯达公司的拜耳提出一种解决方案,只用一个图像传感器,但是在图像传感器的前面放置一个滤光层,滤光层的滤光点与图像传感器的像素一一对应,每个滤光点只能通过红、绿、蓝三种光其中之一。

这种可以通过不同颜色滤光点的排列是有规律的,每个绿色点的左上、右上、左下、右下分布的绿点,上下分布的是红点,左右分布的是蓝点。研究发现人眼对绿色最为敏感,所以绿点的数量是红点或者蓝点数量的两倍。
那么图像传感器的每个像素只可能取四种可能的值:红、绿、蓝、黑(没有光透过)。
现在得到的图像也只有四种颜色,显然还无法表达真实世界的颜色。所以还需要根据每个像素周围的颜色来近似恢复它原来的值,最后得到彩色图像。这个过程叫做“去马赛克(demosaicing)”。

RAW data格式

​ RAW图像就是CMOS或者CCD图像感应器将捕捉到的光源信号转化为数字信号的原始数据,RAW文件是一种记录了数码相机传感器的原始信息,同时记录了由相机拍摄所产生的一些元数据(Metadata,如ISO的设置、快门速度、光圈值、白平衡等)的文件。RAW是未经处理、也未经压缩的格式,可以把RAW概念化为“原始图像编码数据”或更形象的称为“数字底片”。sensor的每一像素对应一个彩色滤光片,滤光片按Bayer pattern分布。将每一个像素的数据直接输出,即RAW RGB data,Raw data(Raw RGB)经过彩色插值 (DEMOSAIC ) 就变成RGB。

RGB565 与 RGB888转化关系,代码实现如下:

#define RGB888_RED      0x00ff0000
#define RGB888_GREEN    0x0000ff00
#define RGB888_BLUE     0x000000ff

#define RGB565_RED      0xf800
#define RGB565_GREEN    0x07e0
#define RGB565_BLUE     0x001f 
unsigned short RGB888ToRGB565(unsigned int n888Color){ 
	 unsigned short n565Color = 0;  
	 // 获取RGB单色,并截取高位 
	 unsigned char cRed   = (n888Color & RGB888_RED)   >> 19; 
	 unsigned char cGreen = (n888Color & RGB888_GREEN) >> 10; 
	 unsigned char cBlue  = (n888Color & RGB888_BLUE)  >> 3;  
	 // 连接 
	 n565Color = (cRed << 11) + (cGreen << 5) + (cBlue << 0); 
	 return n565Color;
}
unsigned int RGB565ToRGB888(unsigned short n565Color){
	 unsigned int n888Color = 0;  
	 // 获取RGB单色,并填充低位 
	 unsigned char cRed   = (n565Color & RGB565_RED)    >> 8; 
	 unsigned char cGreen = (n565Color & RGB565_GREEN)  >> 3; 
	 unsigned char cBlue  = (n565Color & RGB565_BLUE)   << 3;  
	 // 连接 
	 n888Color = (cRed << 16) + (cGreen << 8) + (cBlue << 0); 
	 return n888Color;
}

MIPI数据与RAW数据的转换

传感器采集的RAW数据通常为10bit(RAW8,RAW10,RAW12),存储RAW数据需要两个Byte,而其中有6个bit位是空着的,这样就有存储空间浪费。MIPI RAW数据充分利用了这个特性,采用5个Byte,共40bit存储4个RAW数据。那么怎么理解这个意思呢,下面通过一张图来解释(主要通过10bits来解释,其他格式是类似的)
所以MIPI的方式存放4个10bits的数据只需要5个字节,节省很多空间。

ISP的主要内容和Bayer Raw的处理

ISP 通过一系列数字图像处理算法完成对数字图像的效果处理。主要包括3A、坏点校正、去噪、强光抑制、背光补偿、色彩增强、镜头阴影校正等处理。ISP 包括逻辑部分以及运行在其上的firmware。
ISP 的控制结构如图,lens 将光信号投射到sensor 的感光区域后,sensor 经过光电转换,将Bayer 格式的原始图像送给ISP,ISP 经过算法处理,输出RGB 空间域的图像给后端的视频采集单元。在这个过程中,ISP 通过运行在其上的firmware 对ISP逻辑,lens 和sensor 进行相应控制,进而完成自动光圈、自动曝光、自动白平衡等功能,其中,firmware的运转靠视频采集单元的中断驱动,PQ Tools 工具通过网口或者串口完成对ISP 的在线图像质量调节。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sN6QfQ0z-1667137915692)(数字成像系统流程综述.assets/image-20221020141229804-166624635157811.png)]

ISP 的Firmware 包含三部分,一部分是ISP 控制单元和基础算法库,一部分是AE/AWB/AF 算法库,一部分是sensor 库。Firmware 设计的基本思想是单独提供3A 算法库,由ISP 控制单元调度基础算法库和3A 算法库,同时sensor 库分别向 ISP 基础算法库和 3A 算法库注册函数回调,以实现差异化的sensor 适配,ISP firmware 架构如图:
在这里插入图片描述

不同的sensor 都以回调函数的形式,向ISP 算法库注册控制函数。ISP 控制单元调度基础算法库和3A 算法库时,将通过这些回调函数获取初始化参数,并控制sensor,如调节曝光时间、模拟增益、数字增益,控制 lens 步进距离或旋转光圈等。

RGBToYUV

YUV 是一种基本色彩空间, 人眼对亮度改变的敏感性远比对色彩变化大很多, 因此, 对于人眼而言, 亮度分量 Y 要比色度分量 U、 V 重要得多。 另外,YUV色彩空间分为YUV444,YUV422,YUV420等格式,这些格式有些比原始RGB图像格式所需内存要小很多,这样亮度分量和色度分量分别存储之后,给视频编码压缩图像带来一定好处。YUV也是一种颜色编码方法,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的带宽。

RGB、YUV和YCbCr三种颜色空间

首先要说明,RGB、YUV和YCbCr都是人为规定的彩色模型或颜色空间(有时也叫彩色系统或彩色空间),其用途是在某些标准下用人眼可接受的方式对彩色加以说明,本质上,彩色模型是坐标系统和子空间的阐述。

RGB
RGB(红绿蓝)是依据人眼识别的颜色定义出的空间,可表示大部分颜色。但在科学研究一般不采用RGB颜色空间,因为它的细节难以进行数字化的调整。它将色调,亮度,饱和度三个量放在一起表示,很难分开。它是最通用的面向硬件的彩色模型。该模型用于彩色监视器和一大类彩色视频摄像。
YUV
YUV是北美NTSC系统和欧洲PAL系统中模拟电视信号编码的基础。在 YUV 空间中,每一个颜色有一个亮度信号 Y,和两个色度信号 U 和 V。亮度信号是强度的感觉,它和色度信号断开,这样的话强度就可以在不影响颜色的情况下做出改变。YUV 使用RGB的信息,但它从全彩色图像中产生一个黑白图像,然后提取出三个主要的颜色变成两个额外的信号来描述颜色,把这三个信号组合回来就可以产生一个全彩色图像。

为什么视频编码使用YUV420而不是rgb,原因如下:

RGB格式:
该格式是从颜色发光的原理进行设计的,打个比方,每个像素点都有RGB这3个分量,相当于有红、绿、蓝这3盏灯,它们的光混在一起,颜色混在一起,亮度相加。
YUV格式:
相比于RGB格式,该格式可以节省内存,传输阶段可以节省带宽,根据对色彩的需求,调整UV分量的比例,使用起来方便灵活。所以从内存的角度来说,YUV格式的像素使用的内存更低,但是不影响显示效果,也可以认为RGB格式过度绘制图像,把人眼无法分辨的区域也进行了绘制。

3. logcat

解锁相关
1.首先挂载好手机(如果没有解锁先解锁)
2.进入 system/priv-app/WingCamera 下面删除掉WingCamera.apk或者更改后缀都行(WingCamera.apk.bak)
3.重启,查看下桌面是否没有相机图标了
4.没有的话就执行 adb install *******/WingCamera.apk 或者 adb push 本地apk路径 system/priv-app/WingCamera,然后重启

解锁方式:
1,打开开发选项
2,开发选项里边把OEM Unlock 打开
3,adb reboot bootloader
4,fastboot flashing unlock(需要要fastboot环境)
5,按音量上键(或者下键,不同项目不一样)—-看到 finish后
6,长按power键或者 fastboot reboot

在抓取log前,可输入命令:adb logcat -c 清除旧日志信息
输入命令:adb logcat -v time > logcat.log 开始抓取日志,同时在手机上复现问题

抓取kernel日志adb 命令:
adb root
adb shell setprop persist.sys.kernel.log logcat
adb shell dmesg > kernel.lo

log开关

adb root
adb remount
adb shell setenforce 0
adb logcat -c
adb shell logcat -G 20M
adb shell setprop log.tag V
adb shell setprop vendor.debug.mtkcam.loglevel 4
adb shell setprop persist.vendor.mtk.camera.log_level 4
adb shell setprop vendor.debug.camera.log 1
adb shell setprop vendor.debug.ae_mgr.enable 1
adb shell pkill camera*
adb root: root 权限
adb remount: 挂载分区
adb push A B: 将文件A放在路径B中
adb install A:安装A文件(360相机)
adb reboot: 重启
adb shell “echo A >> B/C” 将语句A写到路径B下的C文件中
adb reboot bootloader: 进去fastboot模式
fastboot flash boot boot.img 在fastboot模式下烧录对应分区的IMAGE
fastboot flash dtbo dtbo.img
fastboot reboot: 退出fastboot并重启

问题

1.I2C不通的情况下怎么检查?

I2C地址,址的宽度,总线配
确认sensor的i2c地址是否配置正确,由于i2c通信地址是7bit,而不同的平台可能存在差异。有些配置7bit;有些则配置8bit,最后一位是读写标志

检查上电时序
确认驱动中,是否在上电过程中,都按照sensor datasheet的上电流程配置电源和将reset,pwdn拉到相应的电平状态

检查上电电压是否正确
检查mclk
硬件测量是否正确
是否与别的I2C地址冲突

2.mipi不通的情况下怎么检查?

确认硬件mipi lane上是否有正确数据
检查mipi端口
降低mipi Rate
降低mclk
bandwidth不足,降帧率
mipi是几lane

3. Qcom或MTK平台下如何bring up 一个sensor/af/flash/pdaf ?

根据软、硬件接口文档查看camera外围硬件接口,包括:i2c/mipi lane/AVDD/DVDD/IOVDD/AFVDD/PWD/RESET等
根据原理图check CAMERA外围接口,包括GPIO端口分配、I2C端口号,mipi端口及mipi lane数量,mclk(24m/19m)
根据camera模组资料查看模组基本信息,包括:I2C地址,模组光圈、焦距、FOV等EXIF信息
根据软硬件接口文档,配置camera设备树DTSI信息,包括:I2C地址、PWD、RESET、AVDD、DVDD、IOVDD、AFVDD、MCLK等。
根据DataSheet中的信息,配置驱动配置参数,重点包括:
slaver info 相关信息
mipi相关信息
上下电时序
曝光相关设置信息
preview、capture、video setting相关信息
hts/vts/vt_pixel/op_pixel_clk等分辨率和时钟相关信息
outinfo输出相关信息

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2024 lk
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信