3A之自动白平衡(AWB)篇
在手机相机的专业模式中,可以看到有一个白平衡(WB)调节的选项
什么是AWB
人眼视觉系统具有颜色恒常性的特点,对物体的观察不受光源的影响。本质上是白色的物体,在不同色温,反射光线颜色不同的场景下,经过人眼的视觉系统矫正后还是白色;而对于Camera来说,不同色温,反射光线颜色不同,直接成像会有偏色现象发生。如下图所示,可以看到阴影区域的白色部分偏蓝:
为了在不同的色温环境下,消除光源对图像传感器成像的影响,模拟人眼视觉系统的颜色恒常性,保证在任何场景下看到的白色为正常的白色,ISP的流水线中添加了白平衡WB模块来处理色温引起的偏色问题
色温
色温是表示光线中包含颜色成分的一种计量单位,用“K”(开尔文)表示。
绝对黑体从绝对零度(-273℃)开始加温后,黑体的颜色会逐渐由黑变红,转黄,发白,最后发出蓝色光,当加热到一定温度,黑体发出的光所含的光谱成分,就成为这一温度下的色温。
如果某光源发出的光,与某一温度下黑体发出的光所包含的光谱成分相同,就称为某K色温。
如100W灯泡发出的光的颜色,与绝对黑体在2527℃时的颜色相同,那么这个灯泡发出的光的色温就是:(2527+273)K=2800K
Camera中设置AWB
Camera1中通过Paramters进行设置
// 1. get support awb mode
/**
* @see #WHITE_BALANCE_AUTO
* @see #WHITE_BALANCE_INCANDESCENT
* @see #WHITE_BALANCE_FLUORESCENT
* @see #WHITE_BALANCE_WARM_FLUORESCENT
* @see #WHITE_BALANCE_DAYLIGHT
* @see #WHITE_BALANCE_CLOUDY_DAYLIGHT
* @see #WHITE_BALANCE_TWILIGHT
* @see #WHITE_BALANCE_SHADE
*/
mParameters.getSupportedWhiteBalance();
// 2. set wb to auto
mParameters.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO)
Camera2中通过CaptureRequest.Builder进行设置
// 1. get support awb mode
characteristics.get(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES);
// 2. set wb to auto
builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
相机AWB流程
在Turning阶段准备矫正参数:在不同色温下按照一定梯度拍几张白纸作为色温照,然后对色温照的R/G/B通道进行矫正,让偏色的白纸照变为白色,并记录各个通道的矫正参数(实际只需矫正R和B通道,得到Rgain,Bgain),最后利用插值得到的色温-RG-BG的曲线图,大致如下:
图片来自参考资料一
在成像阶段只要计算出当前帧图像的色温,然后利用色温曲线图获取Rgain,Bgain进行颜色矫正即可。如何准确计算色温就是一个好的基于色温估计的AWB算法的核心和竞争力的体现了。
常见的AWB图像处理算法
常见的AWB图像处理算法有基于灰度世界,完美反射,动态阈值等图像自动白平衡算法和基于色温估计的自动白平衡算法。
这里简单说说灰度世界AWB,该算法基于灰度世界假设:在一幅有着大量色彩变化的图像中,其R,G,B三个分量的平均值趋于同一个灰度K,算法流程分为三个步骤:
- 计算平均灰度K,两种方式:第一种直接设定固定值,取各个颜色通道的最大值的一半,即127或128;第二种是计算各个颜色通道的平均值Raver,Gaver,Baver,然后对三个均值再求平均;
- 计算R,G,B通道的增益;
- 根据增益重新计算颜色值,计算中可能存在溢出(大于255),两种处理方式:第一种直接clamp,溢出的设置为255,这种方式可能造成图像整体偏白;第二种是计算所有新颜色中R,G,B通道的最大值,然后重新做线性映射到[0, 255],这种方式可能导致图像整体偏暗,一般直接采用第一种方案
核心代码如下:
原图效果:
白平衡处理后(原图中的晚霞效果,独特的红色被修正为了普通晴天的样子,这种就算过度的修正了):
一个正常效果的例子:
灰度世界法AWB算法计算简单,在复杂的场景下能呈现较好的效果,在颜色和物体单一的情况下,通常都会白平衡失败,容易受到噪声,渐晕,有限动态范围的影响
参考文章
1. https://blog.csdn.net/wzwxiaozheng/article/details/38434391
2. https://blog.csdn.net/wzwxiaozheng/article/details/40586293
3. https://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html
- Office高级威胁漏洞在野利用分析
- 10行代码告诉你,为什么说Python数据可视化是一件艺术品
- 没想到你是这样的Linux | 终端下有趣的命令合集
- PhEmail:基于Python的开源网络钓鱼测试工具
- 数据库中间件mysql-proxy细节【mysql官方的中间件】
- Office CVE-2017-8570远程代码执行漏洞复现
- Java 并发包中的读写锁及其实现分析
- 深入理解 Spring 事务原理
- Chrome开发者工具的小技巧
- Java Web中JSP中6种动作概况知识点总结——每日一语法学习
- 从Flash到Silverlight进阶教程-用代码来创建动画
- 从Flash到Silverlight进阶教程-Tweener
- silverlight设置浏览器Cookies
- 一个最基本的布局控件-panel
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Netty组件之Channel注册
- 使用 kubeadm 安装单 master kubernetes 集群
- 垃圾回收算法(4)-复制算法
- Digital-Signature-Hijack:一款针对数字签名劫持的PowerShell脚本
- 使用TensorFlow物体检测模型、Python和OpenCV的社交距离检测器
- 基于OpenCV和Tensorflow的深蹲检测器
- BBPress未经身份验证的提权漏洞分析
- 开源日志管理系统Graylog之Sidecar功能实践
- CentOS-AltArch-7(ARM版)下源码编译MySQL5.7.31
- 用BurpSuit的Burpy插件搞定WEB端中的JS加密算法
- CentOS7下安装文档协作工具Confluence7.2.1
- caret包进行机器学习
- 容器化Go应用--基础镜像的未知时区问题
- 写给自己的Object和Function的3个灵魂拷问
- 48. Vue路由-使用命名视图实现经典布局