camera-qsc-crosstalk校准数据XTALK回写
问题背景
手机越做越紧凑,需要模组和芯片尺寸越做越小,在尺寸一定的基础上,高像素和大像素,对于手机摄像头来说,一直是一对矛盾的存在。
- 高像素:带来高分辨率画质
- 大像素:带来暗态下高感光度和低噪声的画质。
以上两者都非常重要,为了两者兼得4cell1感光芯片应运而生,也称之为“Tetra cell”,“Quad bayer”,“four cell”等,该芯片基于经典的Bayer阵列,将每一种颜色以4个pixel排列组合,成功可以让一款摄像头在高像素和大像素之间自由切换。现如今4cell1感光芯片兼具了常态的高像素和暗态的高感光低噪声的表现,已经成为目前手机摄像头的主力军。
同时也带来问题,如下图,左边实拍图比右图多了许多齿狀格子等伪色。主要原因是芯片本身硬件感光和Remosaic造成的,为了优化这种现象,‘CrossTalk校准’登场,去除由于信号差别造成的格子,锯齿状等色块干扰。
什么是crosstalk?
在感光芯片中,crosstalk(串扰)现象是指相邻像素之间的信号互相影响导致的一种干扰。当一个像素受到光照并转换成电信号时,其附近的像素可能会因为光电效应或其他物理机制而感应到部分光强,这不属于它们自身的光学响应,而是由于彼此之间产生的非线性相互作用。这种串扰可能导致图像质量下降,尤其是在高密度像素阵列如CMOS传感器中更为明显,因为它增加了错误信息的传播机会。为了减少crosstalk,设计者通常会采用各种技术,比如优化像素布局、增加隔离层等措施。
解决办法:crosstalk(串扰)校准。
Crosstalk校准工具,通常将全图分成多个ROI方块,计算各像素通道的能量并确定其补偿数据,芯片再使用这些校准数据让原本不均匀状态的能量分布变得更为平衡。


问题分析
一般是模组厂家在模组出厂的时候,会使用上述的crosstalk工具将校准补偿数据烧录在eeprom里面。在调试模组成像效果的时候,需要从eeprom中读取crosstalk数据(QSC),然后写入感光芯片中的特定寄存器中进行校准。
注意:
4cell1芯片还会涉及到PD补偿,坏点补偿等其他的内容,而整个流程,通常需要先补偿PD点,再做Crosstalk校准,然后再Remosaic成为正常的Bayer去应用。针对软件的Remosaic,这其中所有的步骤,通常都封装在芯片厂商提供的一个算法库里面,手机端调用该算法库,去实现4cell1芯片,兼具常态时候的高分辨率和暗态时候的高感光度,然后你就可以美美地拍照了。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_41897352/article/details/117336884
当向sensor寄存器(0x53c0 ~ 0x54df)写入Crosstalk补偿数据时候,sensor要么在sleep mode(0x0100 = 0)要么crosstalk disable(寄存器0x5000[6] = 0)
关键代码
- 在文件camxeepromdriver.xsd添加Crosstalk对应的QSC数据属性可以模仿SPC的填写方法,如在eeprom的xml文件模仿SPC的数据格式填写如下。
<QSC><!--Specifies the availability of the specified data and type of endiannesselement for operation --><QSCData description="Memory Type"><!--Specifies whether a particular OTP data available or not --><isAvailable>true</isAvailable><!--Type of the EndiannessValid values are: BIG, LITTLE --><endianness>BIG</endianness></QSCData><QSCSettings><!--Specifies memory offset value and mask information --><dataOffset><!--Offset value in the OTP memory --><offset>0x1798</offset><!--mask value which will be applied to obtain required data bits --><mask>0xFF</mask></dataOffset><!--register address value to write QSC data --><QSCAddress>0x53c0</QSCAddress><!--size of the QSC data settings --><settingsSize>288</settingsSize></QSCSettings><!--Register address / data size in bytes --><addressType range="[1,4]">2</addressType><!--Register address / data size in bytes --><dataType range="[1,4]">1</dataType><!--Delay in milli seconds. Delay is 0 if not explicitly provided --><delay>0</delay></QSC>
- 在仓库camx中,先将EEPROM中的crosstalk校准数据读取出来,主要实现在src/core/camxeepromdata.cpp中的FormatQSCData();FormatQSCData函数在构造函数EEPROMData::EEPROMData()中调用。FormatQSCData函数是模仿者FormatSPCData函数写的。如下:
/// EEPROMData::FormatQSCDataVOID EEPROMData::FormatQSCData(){QSCInfo* pQSCFormatInfo = &(m_pEEPROMDriverData->formatInfo.QSC);QSCCalibrationData* pQSCData = &(m_pSensorInfoTable->moduleCaps.OTPData.QSCCalibration);MemoryInfo dataOffset = { 0 };pQSCData->isAvailable = pQSCFormatInfo->QSCData.isAvailable;if (TRUE == pQSCFormatInfo->QSCData.isAvailable){UINT32 totalRegCount = 0;for (UINT16 i = 0; i < pQSCFormatInfo->QSCSettingsCount; ++i){totalRegCount += pQSCFormatInfo->QSCSettings[i].settingsSize;}pQSCData->settings.regSettingCount = totalRegCount;pQSCData->settings.regSetting = static_cast<RegisterSetting*>(CAMX_CALLOC(sizeof(RegisterSetting) * totalRegCount));if (NULL != pQSCData->settings.regSetting){RegisterData* pRegData = static_cast<RegisterData*>(CAMX_CALLOC(sizeof(RegisterData) * totalRegCount));if (NULL != pRegData){RegisterSetting* pCurRegOffset = pQSCData->settings.regSetting;for (UINT16 i = 0; i < pQSCFormatInfo->QSCSettingsCount; ++i){/// copy to local structures so that original offset values wont be modified because of incrementsUtils::Memcpy(&dataOffset, &pQSCFormatInfo->QSCSettings[i].dataOffset, sizeof(MemoryInfo));UINT32 dataSize = MaskLengthInBytes(dataOffset.mask);if (NULL != pQSCData->settings.regSetting){for (UINT16 index = 0; index < pQSCFormatInfo->QSCSettings[i].settingsSize; index++, pCurRegOffset++){(pCurRegOffset)->registerAddr = pQSCFormatInfo->QSCSettings[i].QSCAddress + index;(pCurRegOffset)->registerData = pRegData++;(pCurRegOffset)->registerData[0] =FormatDataTypeInteger((&dataOffset), pQSCFormatInfo->QSCData.endianness);dataOffset.offset += static_cast<UINT16>(dataSize);(pCurRegOffset)->regAddrType = pQSCFormatInfo->addressType;(pCurRegOffset)->regDataType = pQSCFormatInfo->dataType;(pCurRegOffset)->operation = OperationType::WRITE;if (0 != pQSCFormatInfo->delay){(pCurRegOffset)->delayUsExists = TRUE;(pCurRegOffset)->delayUsID = 0;(pCurRegOffset)->delayUs = pQSCFormatInfo->delay;}}}}}else{CAMX_LOG_ERROR(CamxLogGroupSensor, "Calloc failed");}}else{CAMX_LOG_ERROR(CamxLogGroupSensor, "Calloc failed");}}}
同理,也需要模仿DumpWBData函数来实现DumpQSCData
其他地方,可以参考模仿AWB,SPC的写法在SensorNode::LoadSensorConfigCmds()函数中添加,即可打通流程。
具体的说,crosstalk补偿写入是发生在配流阶段,详细可以参考
CamX-Chi 高通Android Camera HAL框架学习2-configure_streams
验证测试
验证高像素模式下修改前后的预览成像和拍照成像在手机上肉眼无法观察到明显差异。
那么如何保证已经正确地将EEPROM中的crosstalk校准数据写入了感光芯片对应的寄存器中呢?
- 首先验证确保从EEPROM中crosstalk校准数据读取正确,这可以通过checksum和dump数据来分别验证。
/// EEPROMDataDump::DumpQSCDataVOID EEPROMDataDump::DumpQSCData(){FILE* pQSCDumpFile = NULL;CHAR fileName[FILENAME_MAX] = { 0 };QSCCalibrationData* pQSCData = &(m_pSensorInfoTable->moduleCaps.OTPData.QSCCalibration);if (TRUE == pQSCData->isAvailable){OsUtils::SNPrintF(fileName, sizeof(fileName), "%s/%s_%s_%s", ConfigFileDirectory,m_pEEPROMDriverData->slaveInfo.EEPROMName, "qsc", "OTP.txt");pQSCDumpFile = OsUtils::FOpen(fileName, "w");}if (pQSCDumpFile != NULL){for (UINT16 index = 0; index < pQSCData->settings.regSettingCount; index++){OsUtils::FPrintF(pQSCDumpFile,"addr = 0x%x : value = 0x%x\n",pQSCData->settings.regSetting[i].registerAddr,pQSCData->settings.regSetting[i].registerData[0]);}OsUtils::FClose(pQSCDumpFile);}}
- 如何确保将crosstalk校准数据准确地写入了sensor对应的寄存器0x53c0 ~ 0x54df中,最简单的思路就是去读取写入后寄存器的值。遗憾的是,这些寄存器都是只写寄存器。
于是,想到找效果同事去验证下Xtalk补偿回写前后高像素模式拍照图片对比。使用效果专用软件发现,补偿后的图片在放大后的效果字体更加清晰,说明补偿有不错的收益。
代码评审问题
- Xtalk补偿回写是在什么时候写入的?是在使用高像素模式的时候进行回写补偿吗?
- sensor寄存器0x5380(值0x0f)默认打开 Xtalk补偿回写,有没有副作用?
参考文章
https://blog.csdn.net/qq_41897352/article/details/117336884
相关文章:
camera-qsc-crosstalk校准数据XTALK回写
问题背景 手机越做越紧凑,需要模组和芯片尺寸越做越小,在尺寸一定的基础上,高像素和大像素,对于手机摄像头来说,一直是一对矛盾的存在。 高像素:带来高分辨率画质大像素:带来暗态下高感光度和…...
混合贪心算法求解地铁线路调度
一、问题描述 城市轨道交通的繁荣发展,带来了车辆资源需求的日益增加。如何兼顾运营服务水平和运营成本,以最少的车底优质地完成运输任务成为一大严峻问题。本题在后续的描述中将由多辆动车和拖车组合而成的车组称为车底。在日常的运营组织中࿰…...
vue项目:关闭页面,删除本地登录信息
vue项目:关闭页面,删除本地登录信息 代码 代码 import { removeToken } from /utils/auth //区分关闭和刷新页面,关闭时退出登录 window.onload ()>{if(!window.sessionStorage["tempFlag"]){removeToken();location.reload()…...
获奖案例回顾|基于卫星遥感和无人机的水稻全流程风险减量项目
引言 在现代农业保险领域,技术创新是推动行业进步的关键。珈和科技与太平财险的合作,旨在利用先进的卫星遥感和无人机技术,解决传统农业保险面临的诸多挑战,从而提升保险效率和服务质量。本次分享的项目案例获得了《金融电子化》…...
全栈 Discord 克隆:Next.js 13、React、Socket.io、Prisma、Tailwind、MySQL笔记(一)
前言 阅读本文你需要有 Next.js 基础 React 基础 Prisma 基础 tailwind 基础 MySql基础 准备工作 打开网站 https://ui.shadcn.com/docs 这不是一个组件库。它是可重用组件的集合,您可以将其复制并粘贴到应用中。 打开installation 选择Next.js 也就是此页面…...
【Unity】制作简易计时器
一、创建计时器相关的变量 我们需要创建三个变量,分别是:计时时长、计时剩余时长、是否处于计时状态。 public float duration;//计时时长 public float remain; //计时剩余时长 public bool isCount; //是否处于计时状态 二、初始化变量 我们可以直…...
TDesign组件库日常应用的一些注意事项
【前言】Element(饿了么开源组件库)在国内使用的普及率和覆盖率高于TDesign-vue(腾讯开源组件库),这也导致日常开发遇到组件使用上的疑惑时,网上几乎搜索不到其文章解决方案,只能深挖官方文档或…...
51单片机7(点亮第一个LED)
一、LED简介 1、LED,它是一个发光二极管,它具有单向导电性,那么通过5毫安的一个电流,就可以使它发光,那么电流越大,它的发光也就越强,但是电流不能过大,过大会把这个发光二极管给烧…...
基于Vue和UCharts的前端组件化开发:实现高效、可维护的词云图与进度条组件
基于Vue和UCharts的前端组件化开发:实现高效、可维护的词云图与进度条组件 摘要 随着前端技术的迅速发展和业务场景的日益复杂,传统的整块应用开发方式已无法满足现代开发的需求。组件化开发作为一种有效的解决方案,能够将系统拆分为独立、…...
CentOS 系统监控项
在维护和优化 CentOS 系统时,实时监控硬件和资源的使用情况非常重要。为了满足工作需要,可以定时采集 CentOS 系统相关的监控数据,并将其推送到 Prometheus 进行集中监控和管理。以下是日常采集项及对应的 shell 命令,并附上每项命…...
连锁直营店小程序赋能多店如何管理
如商超便利店卖货线下场景,也有不少品牌以同城多店和多地开店经营为主,获取店铺周围客户和散流,如今线上重要性凸显,品牌电商发展是经营的重要方式之一,也是完善同城和外地客户随时便捷消费的方式之一。 多个门店管理…...
决策树算法入门到精通:全面解析与案例实现
1. 介绍决策树算法 决策树的基本概念和原理 决策树是一种基于树形结构的分类和回归方法,通过对数据集进行递归地划分,每个内部节点表示一个属性上的判断,每个叶节点代表一种类别或者数值。 决策树在机器学习中的应用场景 分类问题…...
LangChain —— 多模态大模型的 prompt template
文章目录 一、如何直接将多模态数据传输给模型二、如何使用 mutimodal prompts 一、如何直接将多模态数据传输给模型 在这里,我们演示了如何将多模式输入直接传递给模型。对于其他的支持多模态输入的模型提供者,langchain 在类中提供了内在逻辑来转化为期…...
ssh升级
文章目录 ssh升级一、解包ssh、ssl二、更新安装ssl三、手动更新手动复制库文件四、创建符号链接五、更新库路径六、验证库文件七、设置库路径环境变量八、配置、编译、安装OpenSSH:意外:缺少 zlib 的开发库解决方法: 九、刷新ssh服务、查看ss…...
51单片机10(蜂鸣器介绍)
一、蜂鸣器介绍: 1、蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于电子产品中作为发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器。 (1)压电式蜂鸣器,它主要由多谐的一个增胀器…...
Python爬虫:基础爬虫架构及爬取证券之星全站行情数据!
爬虫成长之路(一)里我们介绍了如何爬取证券之星网站上所有A股数据,主要涉及网页获取和页面解析的知识。爬虫成长之路(二)里我们介绍了如何获取代理IP并验证,涉及了多线程编程和数据存储的知识。此次我们将在…...
T113-i 倒车低概率性无反应,没有进入倒车视频界面
背景 硬件:T113-i + emmc 软件:uboot2018 + linux5.4 + QT应用 分支:longan 问题 T113-i系统倒车时偶发无反应,没有进入倒车视频界面。 倒车无反应问题排查 先在倒车驱动的中断检测接口里添加打印,以确定倒车无反应时系统是否检测到中断状态,如下图所示。 static int ca…...
【AI大模型】李彦宏从“卷模型”到“卷应用”的深度解析:卷用户场景卷能给用户解决什么问题
文章目录 一、理解李彦宏的发言1.1 李彦宏的核心观点1.2 背景分析 二、技术发展:从辨别式到生成式2.1 辨别式AI技术2.2 生成式AI技术2.3 技术发展的挑战 三、“卷应用”:聚焦实际应用与价值3.1 应用为王3.2 技术落地的关键 四、“卷场景”:多…...
25秋招面试算法题 (Go版本)
文章目录 科大讯飞 0713找01不能出现太多其他 科大讯飞 0713 找01 牛牛拥有一个长度为 n 的01 串,现在他想知道,对于每个字符,在它前面的最近的不同字符的下标是多少? 输入描述 本题为多组测试数据,第一行输入一个…...
在Ubuntu 14.04上安装和保护phpMyAdmin的方法
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 虽然许多用户需要像 MySQL 这样的数据库管理系统的功能,但他们可能不太习惯仅通过 MySQL 提示符与系统进行交互。 ph…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)
注:文章末尾网盘链接中自取成品使用演示视频、项目源码、项目文档 所用硬件:STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …...
Linux操作系统共享Windows操作系统的文件
目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项,设置文件夹共享为总是启用,点击添加,可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download(这是我共享的文件夹)&…...
CVE-2023-25194源码分析与漏洞复现(Kafka JNDI注入)
漏洞概述 漏洞名称:Apache Kafka Connect JNDI注入导致的远程代码执行漏洞 CVE编号:CVE-2023-25194 CVSS评分:8.8 影响版本:Apache Kafka 2.3.0 - 3.3.2 修复版本:≥ 3.4.0 漏洞类型:反序列化导致的远程代…...
LeetCode 0386.字典序排数:细心总结条件
【LetMeFly】386.字典序排数:细心总结条件 力扣题目链接:https://leetcode.cn/problems/lexicographical-numbers/ 给你一个整数 n ,按字典序返回范围 [1, n] 内所有整数。 你必须设计一个时间复杂度为 O(n) 且使用 O(1) 额外空间的算法。…...
