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)

关键代码

  1. 在文件camxeepromdriver.xsd添加Crosstalk对应的QSC数据属性可以模仿SPC的填写方法,如在eeprom的xml文件模仿SPC的数据格式填写如下。
    <QSC>
       <!--Specifies the availability of the specified data and type of endianness
            element for operation  -->
       <QSCData description="Memory Type">
         <!--Specifies whether a particular OTP data available or not -->
         <isAvailable>true</isAvailable>
         <!--Type of the Endianness
             Valid 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>
  1. 在仓库camx中,先将EEPROM中的crosstalk校准数据读取出来,主要实现在src/core/camxeepromdata.cpp中的FormatQSCData();FormatQSCData函数在构造函数EEPROMData::EEPROMData()中调用。FormatQSCData函数是模仿者FormatSPCData函数写的。如下:
 
  /// EEPROMData::FormatQSCData
  
  VOID 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 increments
					  
                      Utils::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校准数据写入了感光芯片对应的寄存器中呢?

  1. 首先验证确保从EEPROM中crosstalk校准数据读取正确,这可以通过checksum和dump数据来分别验证。
  
  /// EEPROMDataDump::DumpQSCData
  
  VOID 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);
      }
  }
  1. 如何确保将crosstalk校准数据准确地写入了sensor对应的寄存器0x53c0 ~ 0x54df中,最简单的思路就是去读取写入后寄存器的值。遗憾的是,这些寄存器都是只写寄存器。
    于是,想到找效果同事去验证下Xtalk补偿回写前后高像素模式拍照图片对比。使用效果专用软件发现,补偿后的图片在放大后的效果字体更加清晰,说明补偿有不错的收益。

代码评审问题

  1. Xtalk补偿回写是在什么时候写入的?是在使用高像素模式的时候进行回写补偿吗?
  2. sensor寄存器0x5380(值0x0f)默认打开 Xtalk补偿回写,有没有副作用?

参考文章

https://blog.csdn.net/qq_41897352/article/details/117336884

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/791661.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MyBatis】——入门基础知识必会内容

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

Covalent Network(CXT)通过社区投票将代币迁移并更名为 CXT,以推动人工智能更深层次的创新

专注于人工智能和 Web3 的模块化数据基础设施 Covalent Network&#xff08;CXT&#xff09;宣布&#xff0c;其治理提案已通过社区投票并顺利实施&#xff0c;即将原生代币 CQT 迁移为新的 CXT 代币&#xff0c;并部署至新的合约。这一关键性转变标志着 Covalent Network&…

Android焦点之InputWindows的更新(一)

找到焦点窗口后&#xff0c;回到DisplayContent的updateFocusedWindowLocked方法中继续往下走 执行到此处会进行InputWindows的更新 InputMonitor#setInputFocusLw&#xff1a;以上过程伴随日志&#xff1a;WindowManager: Input focus has changed to Window{a44139a u0 Noti…

linux系统中SPI驱动框架以及代码的详解

大家好,今天给大家分享一下,如何使用SPI子系统,详细实现以及具体的操作方法。 第一:SPI驱动框架模板 参考内核头文件:include\linux\spi\spi.h。 1、SPI平台总线设备驱动模型 Linux驱动程序开始基于“平台总线设备驱动模型”,将驱动程序分为两块: * 左边注册一个platfo…

算法力扣刷题记录 四十一【N叉树遍历】

前言 依然是遍历问题。由二叉树扩展到N叉树遍历。 记录 四十一【N叉树遍历】 一、【589. N叉树的前序遍历】 题目 给定一个 n 叉树的根节点 root &#xff0c;返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示&#xff0c;每组子节点由空值 null 分隔…

FLinkCDC引起的生产事故(二)

背景&#xff1a; 最近在做实时数据的抽取工作&#xff0c;利用FLinkCDC实时抽取目标库Oracle的数据到Doris中&#xff0c;但是在抽取的过程中&#xff0c;会导致目标库的生产库数据库非常卡顿&#xff0c;为了避免对生产环境的数据库造成影响&#xff0c;对生产环境的数据库利…

Android 自定义Edittext 和TextView 提示文字和填入内容不同的粗细组件

近期项目中又EditText 以及TextView 这两个组件需要用到提示文字 以及 填入文字要保持不同的粗细程度,所以记录一下 首先 是EditText 组件的自定义 BLEditText 继承的这个组件是一个三方的组件,可以在很大程度上减少drawable的编写,有兴趣的可以去相关的Git去看一下 点击查看,…

Redis 主从复制,集群与高可用

虽然Redis可以实现单机的数据持久化&#xff0c;但无论是RDB也好或者AOF也好&#xff0c;都解决不了单点宕机问题&#xff0c;即一旦单台 redis服务器本身出现系统故障、硬件故障等问题后&#xff0c;就会直接造成数据的丢失 此外,单机的性能也是有极限的,因此需要使用另外的技…

合合信息大模型加速器亮相WAIC大会:文档解析与文本识别新突破

合合信息大模型加速器亮相WAIC大会&#xff1a;文档解析与文本识别新突破 文章目录 合合信息大模型加速器亮相WAIC大会&#xff1a;文档解析与文本识别新突破前言合合信息TextIn平台&#xff1a;智能文档处理的领军者文档解析引擎&#xff1a;百页文档秒级处理大模型的发展背景…

TortoiseSVN-VisualSVNServer-软件代码文本资源版本控制管理-版本比较及差异文件

文章目录 1.VisualSVNServer安装2.TortoiseSVN安装2.1.检出2.2.提交资源2.3.更新资源2.4.返回版本2.5.比较软件可更改2.6.在此创建版本库3.TortoiseSVN版本差异文件1.VisualSVNServer安装 从官网下载,或者csdn下载链接: https://download.csdn.net/download/m0_67316550/8952…

C语言笔记32 •单链表经典算法OJ题-4.查找链表的中间结点•

1.问题 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 2.代码实现&#xff08;快慢指针&#xff09; //4.查找链表的中间结点 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #in…

Win11系统文件夹预览无法预览PDF文件,PDF阅读器是adobe acrobat

三步走 首先&#xff0c;打开文件夹预览功能 然后&#xff0c;设置adobe acrobat为默认PDF打开应用 最后&#xff0c;打开在Windows资源管理器中启用PDF缩略图&#xff0c;正常设定后&#xff0c;会显示配置文件&#xff0c;稍等一会。

防火墙练习实验

一、实验拓扑 二、实验要求 1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内9&#xff1a;00-18&#xff1a;00&#xff09;可以访问&#xff0c;生产区的设备全天可以访问&#xff1b; 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网&#xff1…

git查看版本,查看安装路径、更新版本

git version 查看版本 git update-git-for-windows 更新版本 git version 查看版本

顶顶通呼叫中心中间件实现随时启动和停止质检(mod_cti基于FreeSWITCH)

文章目录 前言联系我们拨号方案启动停止ASR执行FreeSWITCH 命令接口启动ASR接口停止ASR接口 通知配置cti.json配置质检结果写入数据库 前言 顶顶通呼叫中心中间件的实时质检功能是由两个模块组成&#xff1a;mod_asr 和 mod_qc。 mod_asr&#xff1a;负责调用ASR将用户们在通…

beyond Compare连接 openWrt 和 VsCode

连接步骤总结 1. 新建会话 -> 文件夹比较 2.点击浏览文件夹 3.在弹出页面 配置 ftp 3.1&#xff09;选中ftp 配置文件 3.2)选中ssh2 3.3)填写我们需要远端连接的主机信息 先点击连接并浏览 得到下方文件夹 弹出无效登录&#xff0c;说明需要密码 我们返回右键刚刚创建的新 …

旷野之间12 - 内容创作用的最佳大模型评测

​​​​​​ 我正在做一个项目,需要我找出最适合内容创作的 LLM。我查看了 lmsys 排行榜上的顶级模型,阅读了其他人对这些模型的评价,查看了顶级 LLM 的模型卡,在没有明确答案后,我决定对所有这些 LLM 进行测试,以完成不同的内容创作任务。 评估模型 我想要评估的模型…

【软件测试】 1+X初级 功能测试试题

培训进修模块需求说明书 普通员工登录系统&#xff0c;在“培训进修”模块&#xff0c;可以查看个人培训进修的信息。 培训进修需求包括用户&#xff08;UI&#xff09;页面、业务规则两部分。 UI 界面 培训进修&#xff1a;列表页 培训进修&#xff1a;查看培训信息 业务规…

【Git基本操作】添加文件 | 修改文件 | 及其各场景下.git目录树的变化

目录 1. 添加文件&add操作和commit操作 2. .git树状目录的变化 3. git其他操作 4. 修改文件 4.1 git status 4.2 git diff 1. 添加文件&add操作和commit操作 add操作&#xff1a;将工作区中所有文件的修改内容 添加进版本库的暂存区中。commit操作&#xff1a;…

springboot轻松音乐-计算机毕业设计源码48092

目 录 摘要 1 绪论 1.1研究背景与意义 1.2研究现状 1.3论文结构与章节安排 2 基于微信小程序的轻松音乐系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2 经济可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.3 系统用例分析 2.4 系统…