相机主要技术点为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开发】【图像处理】相机中白平衡的算法模拟实现的更多相关文章

  1. 基于FPGA的中值滤波算法实现

    在这一篇开篇之前,我需要解决一个问题,上一篇我们实现了基于FPGA的均值滤波算法的实现,最后的显示效果图上发现有一些黑白色的斑点,我以为是椒盐噪声,然后在做基于FPGA的中值滤波算法的实验时,我发现黑 ...

  2. 再谈AR中的图像识别算法

    之前在<浅谈移动平台创新玩法>简单的猜测了easyar中使用的图像识别算法,基于图片指纹的哈希算法的图片检索 .后再阿里引商大神的指点下,意识到图片检测只适用于静态图片的识别,只能做AR脱 ...

  3. 源代码方式向openssl中加入新算法完整具体步骤(演示样例:摘要算法SM3)【非engine方式】

    openssl简单介绍 openssl是一个功能丰富且自包括的开源安全工具箱.它提供的主要功能有:SSL协议实现(包括SSLv2.SSLv3和TLSv1).大量软算法(对称/非对称/摘要).大数运算. ...

  4. openresty开发系列30--openresty中使用全局缓存

    openresty开发系列30--openresty中使用全局缓存 Nginx全局内存---本地缓存 使用过如Java的朋友可能知道如Ehcache等这种进程内本地缓存.Nginx是一个Master进 ...

  5. openresty开发系列26--openresty中使用redis模块

    openresty开发系列26--openresty中使用redis模块 在一些高并发的场景中,我们常常会用到缓存技术,现在我们常用的分布式缓存redis是最知名的, 操作redis,我们需要引入re ...

  6. 【Matlab开发】matlab中bar绘图设置与各种距离度量

    [Matlab开发]matlab中bar绘图设置与各种距离度量 标签(空格分隔): [Matlab开发] [机器学习] 声明:引用请注明出处http://blog.csdn.net/lg1259156 ...

  7. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  8. Java中的经典算法之冒泡排序(Bubble Sort)

    Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...

  9. 分布式数据库中的Paxos 算法

    分布式数据库中的Paxos 算法 http://baike.baidu.com/link?url=ChmfvtXRZQl7X1VmRU6ypsmZ4b4MbQX1pelw_VenRLnFpq7rMvY ...

随机推荐

  1. :last-child的坑-CSS3选择器

    CSS3选择器之:last-child - Eric 真实经历 最近开发项目的时候发现了一个这么多年忽略的问题,和大家分享一下.项目使用的是Antd组件库,有一个搜索框是这样的: 为了保证下拉框的内容 ...

  2. k8s命令集锦

    集群环境相关命令$kubectl vertion --short=true #显示当前使用的客户端及服务端程序版本信息$kubectl cluster-info #获取集群信息$kubectl api ...

  3. linux的逻辑运算符

    1:expression :用于计算括号中的组合表达式,如果整个表达式的计算按结果为真,则测试结果也为真. 2:!exp:客队表达式进行逻辑非运算,即对测试结果求反 3:符合 -a 或者 && ...

  4. django之路由层(反向解析)总结

    表关系的建立方式 表与表之间的关系就三种 一对一 OneToOne(to='') # to后面可以跟字符串的表名 也可以直接跟变量名表名(该表名必须在上面提前定义出来) 一对多 ForeignKey( ...

  5. 前端js之JQuery

    目录 jQuery介绍 jQuery的优势 jQuery内容 jQuery对象 jQuery基础语法结构 jQuery 使用注意事项 查找标签 基本选择器 层级选择器 基本选择器 属性选择器 表单筛选 ...

  6. Angular 如何修改启动的端口

    在默认的情况下 Angular 启动使用的是端口 4200. 如果修改这个启动的端口,比如说我们希望再  4100 端口上启动? 可以在启动的时候添加端口参数 --port. 例如使用下面的启动命令: ...

  7. JDK_API剖析之java.net包

    为实现网络应用程序提供类.(按照字母顺序排序) 1.Authenticator 抽象类 自1.2开始有 无父类和接口 Authenticator 类表示懂得如何获得网络连接验证的对象.通常,它通过提示 ...

  8. Sonar页面Author页面展示

    文主要记录通过Jenkins集成git .svn .sonarqube,获取源码后自动构建进行sonar scanner代码审查,并分析在sonar能够展示Author的原因. 一.Sonar通过je ...

  9. JS基础_Null和Undefind

    1.Null Null类型的值只有一个值,就是null null专门用来表示一个为空的对象 var a=null; console.log(a);//nulltypeof a //object 2.U ...

  10. LeetCode 120. 三角形最小路径和(Triangle)

    题目描述 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小路径 ...