【VS开发】【图像处理】相机中白平衡的算法模拟实现
相机主要技术点为3A算法。
而3A算法主要指的是自动对焦(AF)、自动曝光(AE)及自动白平衡(AWB)。自动白平衡:根据光源条件调整图片颜色的保真程度。
网上时常有类似招聘如下的招聘信息:
---------------------------------------------- ----------------------------------------------
Camera/ISP 算法工程师摄像机3A算法软件工程师
这里随机摘录一些具体要求。
任职要求:
1、本科以上学历,天文,物理,机电、工业自动化,电子相关专业,硕士学历优先考虑;
2、本科毕业3年以上,硕士毕业1年以上的相关行业相关工作经验要求;
3、熟练掌握C/C++或者FPGA 开发语言,数据结构,MATLAB,信号和系统;
4、掌握数字色度学,数字图像处理,数字影像处理的基本知识;
5、熟悉摄像机成像原理;
6、掌握3A(AF,AE,AWB)算法之一;
7、对于自动化控制,数字信号采样,滤波,负反馈,PID算法有实际经验;
8、理解从镜头到SENSOR,电机,ISP,编码器,采集,显示通道一些列变化。
任职要求:
1. 精通camera的3A(AE,AWB,AF)算法原理和设计思路, 有3A算法的设计经验为佳
2. 具备丰富ISP(图象处理器) 开发经验,熟悉MTK,QUALCOMM, OV等便携式终端上应用的ISP开发环境。有上述环境下开发经验为佳。
3. 精通数字图像处理原理和基础知识。
4. 熟悉C/C++语言,有开发经验为佳
5. 有手机/便携式相机3A算法实现/应用经验
6. 精通CMOS sensor的工作原理
---------------------------------------------- ----------------------------------------------
而这类职位一般都是高薪待遇。
然后问题来了,市面上3A算法相关资料都非常稀少,就连相关书籍都很少提及算法细节,而他们基本上都会要求精通3A算法至少之一。
而关于白平衡算法,比较不错的资料是这份:
基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果
之前多次与博主laviewpbt探讨相关的知识,受益匪浅。
而据我所知,绝大多数的相机采用的基础算法便是灰度世界算法,然后在这算法的基础上再改进。
贴一下《 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果 》灰度世界法的大概内容。
---------------------------------------------- ----------------------------------------------
灰度世界算法(Gray World)
是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像, R、 G、 B 三个分量的平均值趋于同一个灰度K。一般有两种方法来确定该灰度。
(1)直接给定为固定值, 取其各通道最大值的一半,即取为127或128;
(2)令 K = (Raver+Gaver+Baver)/3,其中Raver,Gaver,Baver分别表示红、 绿、 蓝三个通道的平均值。
算法的第二步是分别计算各通道的增益:
Kr=K/Raver;
Kg=K/Gaver;
Kb=K/Baver;
算法第三步为根据Von Kries 对角模型,对于图像中的每个像素R、G、B,计算其结果值:
Rnew = R * Kr;
Gnew = G * Kg;
Bnew = B * Kb;
对于上式,计算中可能会存在溢出(>255,不会出现小于0的)现象,处理方式有两种。
a、 直接将像素设置为255,这可能会造成图像整体偏白。
b、 计算所有Rnew、Gnew、Bnew的最大值,然后利用该最大值将将计算后数据重新线性映射到[0,255]内。实践证明这种方式将会使图像整体偏暗,建议采用第一种方案。
---------------------------------------------- ----------------------------------------------
算法的大概思路就是评估一张图片RGB三个通道的中最能表达该通道富含信息的值,然后以该值为基准重新调整像素。
这样就会存在评估不够准确的问题,导致各通道像素信息差距过大,形成噪点以及偏色等现象。
而laviewpbt在博文中写道,建议采用第一种方案,这个我认为也不妥,因为如果采用取最大值的方案就会导致在特定情况明显不均衡,例如该通道大多数的值落在最小值周围,而却存在一个遥远处的最大值,那么就会导致像素信息差距过大,就很糟糕了。
所以在第二种思路上进行进一步改进比较稳妥,因为可用的信息比较多,不容易出问题。
第二种思路,最简单的另一种改进就是采用灰度法。
均值法: K = (Raver+Gaver+Baver)/3
我们知道常用的视频采集编码是YUV。
YUV相关见百度百科: YUV
其中的Y为:
Y =0.299*R + 0.587*G+0.114*B
故灰度法相应可对应为:
K=0.299*Raver + 0.587*Gaver+0.114*Baver
经过实测,这样的处理后效果还不错。
贴上对比图:
原图
均值法
灰度法
单从肉眼上去分辨两张图片,的确很难分出优劣。
不过我也只是大概点一下这个思路而已,有所积累的人,看到这,应该可以发散出更多的想法。
接下来我要说的是具体相机中的钨丝灯等手动白平衡是如何实现的。
简单的说就是色温条件。
那么基于灰度世界这个白平衡算法可以怎么实现这种调节呢?!
这里贴出简单实现的C代码:
switch (preset)
{
case AUTO:
Raver = (SumR / numberOfPixels);
Gaver = (SumG / numberOfPixels);
Baver = (SumB / numberOfPixels);
break;
case CLOUDY:
Raver = (SumR *1.953125 / numberOfPixels);
Gaver = (SumG*1.0390625 / numberOfPixels);
Baver = (SumB / numberOfPixels);
break;
case DAYLIGHT:
Raver = (SumR *1.2734375 / numberOfPixels);
Gaver = (SumG / numberOfPixels);
Baver = (SumB*1.0625 / numberOfPixels);
break;
case INCANDESCENCE:
Raver = (SumR *1.2890625 / numberOfPixels);
Gaver = (SumG / numberOfPixels);
Baver = (SumB*1.0625 / numberOfPixels);
break;
case FLUORESCENT:
Raver = (SumR *1.1875 / numberOfPixels);
Gaver = (SumG / numberOfPixels);
Baver = (SumB*1.3125 / numberOfPixels);
break;
case TUNGSTEN:
Raver = (SumR / numberOfPixels);
Gaver = (SumG*1.0078125 / numberOfPixels);
Baver = (SumB*1.28125 / numberOfPixels);
break;
default:
break;
}
enum WB_PRESET{
//自动白平衡
AUTO,
//阴天 7500k
CLOUDY,
//日光 6500k
DAYLIGHT,
//白热光 5000k
INCANDESCENCE,
//日光灯 4400k
FLUORESCENT,
//钨丝灯 2800k
TUNGSTEN,
};
阴天
日光
白热光
日光灯
钨丝灯
这里只是起到一个演示作用,具体的参数,可按实际需求酌情进行修改。
【VS开发】【图像处理】相机中白平衡的算法模拟实现的更多相关文章
- 基于FPGA的中值滤波算法实现
在这一篇开篇之前,我需要解决一个问题,上一篇我们实现了基于FPGA的均值滤波算法的实现,最后的显示效果图上发现有一些黑白色的斑点,我以为是椒盐噪声,然后在做基于FPGA的中值滤波算法的实验时,我发现黑 ...
- 再谈AR中的图像识别算法
之前在<浅谈移动平台创新玩法>简单的猜测了easyar中使用的图像识别算法,基于图片指纹的哈希算法的图片检索 .后再阿里引商大神的指点下,意识到图片检测只适用于静态图片的识别,只能做AR脱 ...
- 源代码方式向openssl中加入新算法完整具体步骤(演示样例:摘要算法SM3)【非engine方式】
openssl简单介绍 openssl是一个功能丰富且自包括的开源安全工具箱.它提供的主要功能有:SSL协议实现(包括SSLv2.SSLv3和TLSv1).大量软算法(对称/非对称/摘要).大数运算. ...
- openresty开发系列30--openresty中使用全局缓存
openresty开发系列30--openresty中使用全局缓存 Nginx全局内存---本地缓存 使用过如Java的朋友可能知道如Ehcache等这种进程内本地缓存.Nginx是一个Master进 ...
- openresty开发系列26--openresty中使用redis模块
openresty开发系列26--openresty中使用redis模块 在一些高并发的场景中,我们常常会用到缓存技术,现在我们常用的分布式缓存redis是最知名的, 操作redis,我们需要引入re ...
- 【Matlab开发】matlab中bar绘图设置与各种距离度量
[Matlab开发]matlab中bar绘图设置与各种距离度量 标签(空格分隔): [Matlab开发] [机器学习] 声明:引用请注明出处http://blog.csdn.net/lg1259156 ...
- 前端开发:Javascript中的数组,常用方法解析
前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...
- Java中的经典算法之冒泡排序(Bubble Sort)
Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...
- 分布式数据库中的Paxos 算法
分布式数据库中的Paxos 算法 http://baike.baidu.com/link?url=ChmfvtXRZQl7X1VmRU6ypsmZ4b4MbQX1pelw_VenRLnFpq7rMvY ...
随机推荐
- 关于mysql,sqlserverl,与oracle数据库连接总结
首先准备工具类,其中需要修改的地方分别做标注 代码一sqlserver为例,不同数据库只需修改我所标记的第一处和第二处 mysql 第一处应为:com.mysql.jdbc.Driver ...
- Java多线程和并发(十二),Java线程池
目录 1.利用Executors创建线程的五种不同方式 2.为什么要使用线程池 3.Executor的框架 4.J.U.C的三个Executor接口 5.ThreadPoolExecutor 6.线程 ...
- HDU 6444 Neko's loop ( 2018 CCPC 网络赛 && 裴蜀定理 && 线段树 )
题目链接 题意 : 给出一个 n 个元素的环.可以任意选择起点.选完起点后.可以行走 m 步.每次前进 k 个单位.所走到的点将产生正或负贡献.问你一开始得准备多少才能使得初始资金加上在环上获取最大利 ...
- luogu小金明qwq x
1.P1060 开心的金明 题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算, ...
- Codeforces Round #578 (Div. 2) Solution
Problem A Hotelier 直接模拟即可~~ 复杂度是$O(10 \times n)$ # include<bits/stdc++.h> using namespace std; ...
- JIRA7.13版本创建项目:工作流(二)
工作流 在上一篇文章中,我们新建了一个问题类型,并且增加到问题类型方案里了,同时又关联到我们的这个项目中.那么这些问题我们需要如何设置流程走向来表示问题的处理过程呢?这就需要设定一个流程,并将这个流程 ...
- sass用法总结(持续更新中)
官网:https://www.sass.hk/ 1,嵌套规则 1.1普通嵌套:Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器 1.2父选择器 &: ...
- 前后端分离,get请求导出
[HttpGet] public HttpResponseMessage Export(string obj) { string eventType = string.Empty; string ex ...
- linux 文件目录介绍
网上的资源 太多了,copy 过来 留给自己用吧! 摘自 : http:/ 使用linux也有一年多时间了 最近也是一直在维护网站系统主机 下面是linux目录结构说明 本人使用的是centos系 ...
- sklearn.model_selection Part 2: Model validation
1. check_cv() def check_cv(cv=3, y=None, classifier=False): if cv is None: cv = 3 if isinstance(cv, ...