ISP算法之黑电平BLC校正

devtools/2024/12/23 4:36:57/

黑电平形成原因

Sensor本身问题

CMOS Sensor本身的电路会存在暗电流(dark current),在没有光照条件下,感光器件等也会存在流动的电流,在光敏二极管器的伏安特性曲线中反向截止区电流并不为零(如下图)。导致在Sensor遮黑状态下光电转换输出的电压不是零,且这个暗电流与温度、电压稳定性、曝光时间(按行来计算)、模拟增益都有关系且不同的位置暗电流一般是不同的。如果这个暗电流比较大,在拍摄正常图像的时候就会有色差。

曝光时间:非全局曝光的CMOS Sensor(卷帘曝光Rolling Shutter),曝光控制是以行为单位进行的(最小单位为行),在对1行进行曝光前,需将其reset(清0),然后等待一段时间(曝光时间,以行为单位),再读取这1行,读完这1行才算曝光完毕,在下一次reset之前,这些行处于自由曝光状态。因此曝光时间越长,暗电流积攒的越多。

模拟增益:在上述CMOS Sensor构造中,有一个AMP(amplifier),也就是放大器,这个放大器是用于控制模拟增益的,因此模拟增益越大,暗电流增益也会越大

并且对于Bayer滤光片来说,四个通道(R、Gr、Gb、B)的这个暗电流值也有可能是不一样的。

AD转换过程添加的固定值

在CMOS Sensor中有一个ADC模数转换过程,目的是将光电感应的模拟电压转换为10/12/14位的数字信号(RAW10//RAW12/RAW14),而AD芯片都会有一个灵敏度,当电压低于这个阈值的时候无法进行AD转换,从而导致暗态细节损失。所以通常会在ADC模数转换之前添加一个稳定的参考电压REF,使整体信号值放大,有效保留了电压值很小的暗部细节,使得低于阈值部分的电压也能被转换。而这个固定的REF电压模数转换后是一个固定的偏移,对于Bayer图像的四个通道来说应该是一样的。因此这个值一般在ISP端减去固定值即可,一般厂家会给出,没给出就得自己标定了,且不一定准,因为由于暗电流引起的黑电平存在不好确定。

黑电平BLC校正

通常Sensor端的黑电平在Sensor端已经处理好了,例如下列OV5640手册给出的像素阵列。

在感光阵列中会有一片遮黑区域(光学暗区OB区域),这些区域镀的膜是不透光的,通过该区域可以统计出当前Bayer四个通道的暗电流值,遮黑区域与其他正常的像素区域经过相同的曝光时间和模拟增益后经过ADC后会有一个BLC数值,后续将正常像素区域的值减去遮黑区域的均值(分通道进行)合并为一路即可。如下OV5640手册中描述:

而在后续ISP中,只需要减去为了AD转换而认为添加的一个固定偏移即可(我自己使用的Mate30拍摄出来的DNG RAW图给出的这个值四个Bayer通道值都是256,是RAW12 RGGB格式的)。

当然也有的CMOS Sensor这些遮黑区域的值也是可以读出的,这就需要在ISP端同时对这两种黑电平进行处理,处理算法也可以自行设计。

其他的方法参考文末其他优秀的博客,这里 不过多解释。

MATLAB仿真

%raw_image:输入RAW
%Bayer_Pattern:RAW格式
%width:宽度
%height:高度
%BITS:RAW像素深度
%blacklevel:黑电平值
function  raw_out = blc(raw_image, Bayer_Pattern, width, height, BITS, blacklevel)
raw_image = int32(raw_image);   %涉及减法需要转为有符号数
raw_out = zeros(height,width);% raw_out = raw_image - blacklevel;for row = 1:heightfor col =1:widthpix_tmp = raw_image(row,col) - blacklevel;  %对四个通道减去的固定值都相同if(pix_tmp<0)raw_out(row,col) = 0;    %钳位为0elseraw_out(row,col) = pix_tmp;endend
endend

Verilog设计:

/*************************************************************************> File Name: isp_blc.v************************************************************************/
`timescale 1 ns / 1 ps/** ISP - Black Level Correction*/module isp_blc
#(parameter BITS = 8,parameter WIDTH = 1280,parameter HEIGHT = 960,parameter BAYER = 0 //0:RGGB 1:GRBG 2:GBRG 3:BGGR
)
(input pclk,input rst_n,input [BITS-1:0] black_r,    //黑电平参数input [BITS-1:0] black_gr,input [BITS-1:0] black_gb,input [BITS-1:0] black_b,input in_href,input in_vsync,input [BITS-1:0] in_raw,output out_href,output out_vsync,output [BITS-1:0] out_raw
);reg odd_pix;     //奇偶列判断always @ (posedge pclk or negedge rst_n) beginif (!rst_n)odd_pix <= 0;else if (!in_href)odd_pix <= 0;elseodd_pix <= ~odd_pix; endreg prev_href;always @ (posedge pclk or negedge rst_n) beginif (!rst_n) prev_href <= 0;elseprev_href <= in_href;end	reg odd_line;    //奇偶行判断always @ (posedge pclk or negedge rst_n) beginif (!rst_n) odd_line <= 0;else if (in_vsync)odd_line <= 0;else if (prev_href & (~in_href))odd_line <= ~odd_line;elseodd_line <= odd_line;endwire [1:0] format = BAYER[1:0] ^ {odd_line, odd_pix}; //pixel format 0:[R]GGB 1:R[G]GB 2:RG[G]B 3:RGG[B]reg [BITS-1:0] raw_now;assign out_raw = raw_now;always @ (posedge pclk or negedge rst_n) begin          //该模块仅需一个时钟周期的延时if (!rst_n) raw_now <= 0;elseraw_now <= blc_sub(in_raw, format);end//该模块仅占用一个时钟周期,控制信号也打一拍对齐时序reg href_now, vsync_now;always @(posedge pclk) href_now <= in_href;always @(posedge pclk) vsync_now <= in_vsync;assign out_href = href_now;assign out_vsync = vsync_now;//该函数减去黑电平,且保证输出值不小于0(产生负数会回滚)function [BITS-1:0] blc_sub;input [BITS-1:0] value;input [1:0] format;//0:R 1:Gr 2:Gb 3:Bcase (format)2'b00: blc_sub = value > black_r ? value - black_r : {BITS{1'b0}};       2'b01: blc_sub = value > black_gr ? value - black_gr : {BITS{1'b0}};2'b10: blc_sub = value > black_gb ? value - black_gb : {BITS{1'b0}};2'b11: blc_sub = value > black_b ? value - black_b : {BITS{1'b0}};default: blc_sub = {BITS{1'b0}};endcaseendfunction
endmodule

需要注意的是:

当Black Level值扣除过少时,整体图像画面灰蒙蒙的,整画面对比度没有那么高,画面偏亮偏粉。

当Black Level值扣除过多时,整体画面暗沉沉,动态范围变低细节损失多,黑色部分偏色无法通过白平衡纠正,画面偏绿(黑电平是加性参数,而白平衡增益是乘性参数)。

如有任何问题,欢迎大家批评指正!!!

参考

黑电平校正BLC-Black Level Correction)-CSDN博客

ISP——BLC(Black Level Correction)_blc为什么在dpc之前-CSDN博客

ISP之黑电平矫正 - 知乎


http://www.ppmy.cn/devtools/144582.html

相关文章

二、使用langchain搭建RAG:金融问答机器人--数据清洗和切片

选择金融领域的专业文档作为源文件 这里选择 《博金大模型挑战赛-金融千问14b数据集》&#xff0c;这个数据集包含若干公司的年报&#xff0c;我们将利用这个年报搭建金融问答机器人。 具体下载地址 这里 git clone https://www.modelscope.cn/datasets/BJQW14B/bs_challenge_…

聚观早报 | 百度回应进军短剧;iPad Air将升级OLED

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 12月18日消息 百度回应进军短剧 iPad Air将升级OLED 三星Galax S25 Ultra配色细节 一加Ace 5系列存储规格 小米…

JAVA数字人创作文案视频链接提取数字人源码小程序+公众号+APP+H5

JAVA数字人创作文案提取与生成系统&#xff1a;全能型内容创作与运营解决方案 在当今数字化内容井喷的时代&#xff0c;如何高效、创新地生产并传播内容&#xff0c;成为了众多内容创作者、商户乃至企业面临的重要课题。我们的JAVA数字人创作文案提取与生成系统&#xff0c;正…

【橘子微服务】spring cloud function的编程模型

简介 在我们初探了saga的分布式事务之后&#xff0c;我们后面会基于springcloud function(简称:scf)和springcloud stream(scs)实现一下Choreography模式的saga。所以在此之前我们需要了解一下这两个组件的知识。首先我们来看scf的一些概念。 一、简单使用 在进入概念之前&a…

datasets 笔记:加载数据集(基本操作)

参考了huggingface的教程 1 了解数据集基本信息&#xff08; load_dataset_builder&#xff09; 在下载数据集之前&#xff0c;通常先快速了解数据集的基本信息会很有帮助。数据集的信息存储在 DatasetInfo 中&#xff0c;可能包括数据集描述、特征和数据集大小等信息。&…

数据结构期末复习题

第一次作业——绪论 1.数据结构被形式地定义为(D,R),其中D是&#xff08; B &#xff09;的有限集。 A.算法 B.数据元素 C.数据操作 D.逻辑结构 2.数据结构是一门研究非数值计算的程序设计问题中计算机的&#xff08; A &#xff09;以及它们之间的关系和运算等的学科。 …

从 0 到 1 掌握 Java 类加载器:踩坑与反转的奇妙之旅

前言 Java 类加载器&#xff0c;看似一个晦涩难懂的概念&#xff0c;却在整个 Java 应用的生命周期中扮演着极为重要的角色。它负责加载类到 JVM 中&#xff0c;并且控制着类的访问与隔离。在你深入理解 Java 应用时&#xff0c;类加载器可能是一个你避而不谈的“黑箱”&#…

如何在Qt中应用html美化控件

在Qt中应用HTML美化控件&#xff0c;主要可以通过以下几种方式&#xff1a; 使用QWebEngineView&#xff1a;QWebEngineView是基于Chromium引擎的控件&#xff0c;用于显示和交互HTML内容。它支持现代Web标准和技术&#xff0c;如HTML5、CSS3和JavaScript。你可以通过以下步骤…