白平衡基本概念

白平衡是图像基础颜色强度(红色、绿色和蓝色通道)的调整。

白平衡也称为色彩平衡或灰平衡,用于根据各种照明条件改变图像的整体表现,以反映我们眼睛所看到的内容。

照明条件在图像的表现中起着重要作用。白平衡缩放图像中的三个颜色分量 (RGB) 以适应照明条件。

白平衡的功能

一般原始的图像是单色图像,通过将所有颜色进行插值才成为了彩色图像
也就是说通过插值方法转换为彩色图像,图像才有了颜色。

这个插值方法是什么,插值是一种在像素颜色值的子集不可用时为整个彩色图像重建颜色的方法。

在此不详细说明插值的原理,重点关注经过白平衡处理(插值)后图片会变成什么样。

下面的例子是在荧光灯(也就是日光灯)下拍摄的。上边的图像是没有白平衡处理的,下边的图像是经过白平衡,调整颜色,补偿照明条件,最后提供了更接近人眼的图像结果。

未经过白处理图片:
在这里插入图片描述
经过白平衡处理图片:
在这里插入图片描述
白平衡的理论是图像由传感器采集到的初始是“灰色”的,这意味着红色、绿色和蓝色通道的强度应该大致相等。
上面说的这种类型的色彩平衡称为灰色世界定理。
如果图像完全由绿红蓝构成,那么可以用白平衡

和曝光值是否合适类似,同样可以通过图像直方图的形式,来分析白平衡的处理是否合适,合适意味着颜色更接近人眼。
下面的例子上边的是没有经过白平衡处理的,下边的是经过白平衡处理的。

可以通过直方图明显看出,经过白平衡的图像红色、绿色和蓝色通道的强度分布更加均匀。

没有经过白平衡处理:
在这里插入图片描述
经过白平衡处理:
在这里插入图片描述

实现白平衡方法

有两种方法可以缩放各颜色通道:

  • 第一种:所有颜色通道都有各自的缩放系数
  • 第二种:其中两个颜色通得可以被缩放

在第一种方法中,为了找到每个颜色通道的缩放系数,系数不参考图像的标称亮度。
这就是为什么会有第二种方法,大多数白平衡会根据颜色参考缩放两个颜色通道。使用的典型参考颜色是绿色。

白平衡系数可以计算如下:
在这里插入图片描述
工业相机Flir Blackfly S USB3就是这样 计算白平衡系数的

自动白平衡

灰色世界定理可以实现为线性函数算法,这意味着它计算量不会太大,因此在相机上这个定义常用于计算白平衡值。

Blackfly S 相机在自动白平衡模式下对灰色世界定理做了一定修改。该算法将红色、绿色和蓝色通道相加,然后计算适当的 a和 b。

自动白平衡可以设置为在图像捕获时连续运行,以适应不同的照明条件。 Blackfly S 相机上可以配置四个参数,为用户提供对白平衡的更多控制。

  • 最大和最小目标比率
    可以配置 a和 b 的最大和最小比率,以确保自动调整不超过定义的值。

  • 阻尼常数
    阻尼常数越大,自动白平衡达到稳定状态所需的时间就越慢。 当需要快速更改颜色目标时,此功能很有用。

  • 照明配置文件
    照明配置文件估计光源的发射光谱并预先调整白平衡以确保图像色调仍然代表人眼所见。

  • ROI颜色平衡
    要基于图像中的特定区域进行色彩平衡,可以在该 ROI 进行窗口和色彩平衡测量,并将结果应用于整个图像。

如何开启自动白平衡

自动白平衡开启可以通过Flir的上位机(SpinView)或者在Spinnaker API

通过SpinView 设置自动白平衡

步骤如下:

  • 1 打开设置菜单
  • 2 设置Balance White Auto 为 Continuous
    在这里插入图片描述
  • 3 打开Features菜单
  • 4 选择white balance auto profile 为indoor或者outdoor
  • 5 设置自动白平衡的上下限
  • 6 设置阻尼常数
    在这里插入图片描述
    可以设置ROI(region of interest)来对此区域进行白平衡
  • 1 打开Features菜单,使能ROI
  • 2 设置ROI为 Auto White Balance
  • 3 设置ROI的高度和宽度和偏移

使用 Spinnaker API C++ 实现自动白平衡配置

开启自动白平衡:

//开启自动白平衡
CEnumerationPtr ptrBalanceWhiteAuto = nodeMap.GetNode("BalanceWhiteAuto");
CEnumEntryPtr ptrBalanceWhiteAutoCts = ptrBalanceWhiteAuto->GetEntryByName("Continuous");
ptrBalanceWhiteAuto->SetIntValue(ptrBalanceWhiteAutoCts->GetValue());

设置white balance auto profile 为 indoor:

//设置white balance auto profile 为 indoor
CEnumerationPtr ptrBalanceWhiteAutoProfile = nodeMap.GetNode("BalanceWhiteAutoProfile");
CEnumEntryPtr ptrBalanceWhiteAutoProfileIndoor = ptrBalanceWhiteAutoProfile->GetEntryByName("Indoor");
ptrBalanceWhiteAutoProfile->SetIntValue(ptrBalanceWhiteAutoProfileIndoor->GetValue());

设置上下限和阻尼常数:

//设置上下限和阻尼常数:
CFloatPtr ptrBalanceWhiteAutoLowerLimit = nodeMap.GetNode("BalanceWhiteAutoLowerLimit");
ptrBalanceWhiteAutoLowerLimit->SetValue(0.5);
CFloatPtr ptrBalanceWhiteAutoUpperLimit = nodeMap.GetNode("BalanceWhiteAutoUpperLimit");
ptrBalanceWhiteAutoUpperLimit->SetValue(4.0);
CFloatPtrptrBalanceWhiteAutoDamping = nodeMap.GetNode("BalanceWhiteAutoDamping");
ptrBalanceWhiteAutoDamping->SetValue(0.25);

设置ROI 自动白平衡:

//设置ROI 自动白平衡  设置ROI的高度宽度平移
CBooleanPtr ptrRoiEnable = nodeMap.GetNode("RoiEnable");
ptrRoiEnable->SetValue(1);
CEnumerationPtr ptrAutoAlgorithmSelector = nodeMap.GetNode("AutoAlgorithmSelector");
CEnumEntryPtr ptrAutoAlgorithmSelectorWB= ptrAutoAlgorithmSelector->GetEntryByName("AutoWhiteBalance");
ptrAutoAlgorithmSelector->SetIntValue(ptrAutoAlgorithmSelectorWB->GetValue());
CFloatPtr ptrAasRoiOffsetX = nodeMap.GetNode("AasRoiOffsetX");
ptrAasRoiOffsetX->SetValue(0);
CFloatPtr ptrAasRoiOffsetY = nodeMap.GetNode("AasRoiOffsetY");
ptrAasRoiOffsetX->SetValue(0);
CFloatPtr ptrAasRoiWidth = nodeMap.GetNode("AasRoiWidth");
ptrAasRoiOffsetX->SetValue(2048);
CFloatPtr ptrAasRoiHeight = nodeMap.GetNode("AasRoiHeight");
ptrAasRoiOffsetX->SetValue(6);

如何手动调整白平衡的比率

同样,手动调整白平衡的比率可以通过Flir的上位机(SpinView)或者在Spinnaker API

通过SpinView

  • 1 打开设置菜单
  • 2 关闭自动白平衡
  • 3 选择适当的平衡比率选择器并更改平衡比率中的值。
    在 Balance Ratio 中选择红色会改变 a,选择蓝色会改变 b。
    
    在这里插入图片描述

    通过Spinnaker API C++

    手动调整白平衡比率:
    // 手动调整白平衡比率
    CEnumerationPtr ptrBalanceWhiteAuto = nodeMap.GetNode("BalanceWhiteAuto");
    CEnumEntryPtr ptrBalanceWhiteAutoOff = ptrBalanceWhiteAuto->GetEntryByName("Off");
    ptrBalanceWhiteAuto->SetIntValue(ptrBalanceWhiteAutoOff->GetValue());
    CEnumerationPtr ptrBalanceRatioSelector = nodeMap.GetNode("BalanceRatioSelector");
    CEnumEntryPtr ptrBalanceRatioSelectorRed = ptrBalanceRatioSelector->GetEntryByName("Red");
    ptrBalanceRatioSelector->SetIntValue(ptrBalanceRatioSelectorRed->GetValue());
    CFloatPtr ptrBalanceRatio = nodeMap.GetNode("BalanceRatio");
    ptrBalanceRatio->SetValue(1.5);