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…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...
数据库——redis
一、Redis 介绍 1. 概述 Redis(Remote Dictionary Server)是一个开源的、高性能的内存键值数据库系统,具有以下核心特点: 内存存储架构:数据主要存储在内存中,提供微秒级的读写响应 多数据结构支持&…...
