自动曝光算法原理与实现介绍
相机的自动曝光(AE)算法实际上是通过自动调整曝光时间,使得获取到的图像达到一个合理的灰度范围,比如 140 ± 20 140\pm 20 140±20。典型的判断灰度是否合理的方法是计算图像的灰度均值是否在140附近。
图像像素均值计算
设图像宽高分别为 W , H W, H W,H, x , y x, y x,y处的灰度大小为 P x , y P_{x, y} Px,y。图像左上角的点坐标为 ( x , y ) = ( 0 , 0 ) (x, y) = (0, 0) (x,y)=(0,0)
-
直接均值法
直接计算均值:
S = 1 W H ∑ x ∑ y P x , y S = \frac{1}{WH} \sum_x \sum_y P_{x,y} S=WH1x∑y∑Px,y -
高斯加权均值 - 图像中心点附近的灰度值更接近140。
对图像位置进行加权,靠近中心处的像素拥有更高的权重,权值分布为二元高斯分布
N ( μ x , μ y , σ x 2 , σ x 2 ) N(\mu_x, \mu_y, \sigma_x^2, \sigma_x^2) N(μx,μy,σx2,σx2)
,其中 μ 1 , μ 2 \mu_1, \mu_2 μ1,μ2为图像的中心点位置,如果图像为 ( W , H ) = ( 1024 , 1024 ) (W, H)=(1024,1024) (W,H)=(1024,1024)大小,那么 μ x = μ y = 512 \mu_x = \mu_y = 512 μx=μy=512, 实验表明当 σ x = σ y = 200 \sigma_x = \sigma_y = 200 σx=σy=200时,概率 P ( X > 1024 ) = P ( X < 0 ) = P ( Y > 1024 ) = P ( Y < 0 ) = 0.0053 P(X > 1024) = P(X < 0) = P(Y > 1024) = P(Y < 0) = 0.0053 P(X>1024)=P(X<0)=P(Y>1024)=P(Y<0)=0.0053非常小。因此采用这组参数作为图像的像素位置权重。那么图像像素的加权均值为:
S = ∑ x ∑ y P x , y f ( x , y ) ∑ y ∑ y f ( x , y ) S = \frac{\sum_x \sum_y P_{x,y} f(x,y)}{\sum_y \sum_y f(x, y)} S=∑y∑yf(x,y)∑x∑yPx,yf(x,y)
其中 f ( x , y ) ∼ N f(x,y) \sim N f(x,y)∼N为概率密度函数,由于所有像素点的位置相加不等于1, 因此需要除以此项。 -
垂直方向渐变加权 - 适用于地空图像,地面位于图像下方,拥有更高的权重,天空位于图像上方,拥有较少的权重
图像第 y y y行的权重为 log y , 1 ≤ y ≤ H \log y, 1 \leq y \leq H logy,1≤y≤H,那么图像的灰度均值为:
S = 1 W × ∑ y log y ∑ x ∑ y log y P x , y S = \frac{1}{W \times \sum_y \log y} \sum_x \sum_y \log y P_{x,y} S=W×∑ylogy1x∑y∑logyPx,y
Binary Search
二分搜索算法的过程,令曝光时间为ET:
- 计算图像的灰度均值mP;
- 如果 ∣ m P − 140 ∣ < = 20 |mP - 140| <= 20 ∣mP−140∣<=20,则不调整ET;
- 如果 m P − 140 > 20 mP - 140 > 20 mP−140>20,则ET更新为当前ET的一半;
- 如果 m P − 140 < − 20 mP - 140 < -20 mP−140<−20并且当前ET已达到最大ET,则ET调整为最大ET - 1;
- 如果
m
P
−
140
<
−
20
mP - 140 < -20
mP−140<−20并当前ET未达到最大ET,则ET调整为当前ET + [0, 最大ET - 当前ET]中的一个正态分布的随机数。
核心代码如下:
uint BinarySearchAEStrategy::updateET(QImage *image, uint oldET)
{
uint uET = oldET;
uchar m_pix = __meanPixelStrategyFunc__(image);
int diff = (int)m_pix - ett;
if (abs(diff) <= ett_float_range)
return uET;
if (diff > ett_float_range) // 折半减小曝光
uET >>= 1;
else if(diff < -ett_float_range && uET > max_et - 1) // 限制曝光为最大曝光值-1
uET = max_et - 1;
else if (diff < -ett_float_range && uET < max_et - 1) // 曝光补足,且限制曝光最大值
uET += (uint) min(max(0, norm_dist(random_engine) * (max_et - uET)), max_et - uET - 1);
return uET;
}
Fast and Robust Camera’s Auto Exposure Control Using Convex or Concave Model
复现论文Fast and Robust Camera’s Auto Exposure Control Using Convex or Concave Model
中关于曝光时间调整的计算方法。核心代码如下:
uint FRAEStrategy::updateET(QImage *image, uint oldET)
{
uchar pix = __meanPixelStrategyFunc__(image);
if (abs((int)pix - ett) <= ett_float_range)
return oldET;
if (oldET == max_et)
oldET = max_et - 1;
// According to equation (5) to update ET
// f_t = ett = 140
uint updateET = (256. - pix) * oldET * max_et /
(((double)ett - pix) * oldET + (256. - ett) * max_et);
return updateET;
}
下面介绍其原理:该文提出的自动曝光算法将亮度特征建模成关于曝光控制参数的凸/凹函数。该函数决定了针对一个预定义的亮度等级(比如平均灰度140)的控制参数计算方法。
以一个例子来说明该方法的过程:
设上图中横坐标 X X X为曝光速度(也就是曝光时间的倒数),纵坐标 F ( X ) F(X) F(X)为灰度等级。我们不知道曝光速度和灰度等级之间的函数关系式,但显然, F ( X ) F(X) F(X)是一个单调递减函数,该文还假设 F ( X ) F(X) F(X)是一个凸/凹函数,但实际上不必做如此假设。假设 X t X_t Xt是我们要求的的目标函数的根, F ( X t ) F(X_t) F(Xt)是一个给定值,那么由数值分析方法可以迭代求解出 X t X_t Xt,文中采用的是修正的正割法,即只需要当前曝光速度下的图像灰度值作为初始值即可,而不用原始正割法(原始正割法需要两个参数)。