Baumer工业相机堡盟相机彩色相机如何实现白平衡

项目场景

Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。

Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩展性等特点。

Baumer工业相机中彩色相机具有色彩还原度真实的特性,适用于颜色分析的工业应用。


技术背景

Baumer工业彩色相机由于传感器芯片每个像素仅能对一种颜色感光,后期再经过Bayer变换,转成 彩色的 RGB数据,受环境以及芯片成像原理的影响经常得到图都会有些许色彩差异,因此要在实际的环境中通过白平衡处理来矫正颜色;

白平衡就是通过调整图像中R、G、B分量的比例关系,可以使在各种光线条件下拍摄出的图像色彩还原真实。由于图像传感器(CMOS/CCD)本身没有这种功能,因此就必要对它输出的信号进行一定的修正。

一般的彩色工业相机需要做白平衡,以调整其拍摄的图像的色温和色差。白平衡可以确保图像中的颜色是准确和一致的,无论在何种照明条件下拍摄的图像。这对于需要精确色彩的行业来说非常重要,如制造业、医疗保健和科学研究。

白平衡过程包括设置相机,以考虑到正在使用的光源类型,并相应地调整图像的色彩平衡。

彩色工业相机为什么需要做白平衡?

工业相机需要做白平衡,因为它有助于确保在不同的照明条件下准确和一致的色彩再现。白平衡涉及到测量场景中光线的色温,并调整相机的设置以消除任何色差,从而使拍摄的图像看起来尽可能真实。这在工业应用中尤其重要,因为色彩的准确性对质量控制和生产过程至关重要。

问题描述

白平衡是工业相机的重要参数,它直接影响重现图像的彩色效果,工业相机的白平衡参数设置不合时,重现图像就会出现偏色现象,特别是会使原本不带色彩的图像也有了颜色。我们可能通过手动调节白平衡的参数也可以使用软件图像处理算法来自动调节这些参数。

工业相机做白平衡需要注意的几个问题:

  1. 曝光不要调得太大,导致相机成像有过曝的状态,一般需要成像的主体像素在人眼感觉不亮,但能又能看清楚所成像的物体;
  2. 光照条件最好是日光下,如果在实验室或者车间内,选择白色灯光下做白平衡就可以,不要再带颜色光源下做白平衡;
  3. 增益不要调节,因为做了白平衡之后增益值也会再次变化,而且原来调节的增益值过高的话也会影响矫正的效果;
  4. 像素格式不要选择Bayer格式下做白平衡,因为Bayer数据是彩色的原始数据,本身每个像素仅代表一种颜色,因此Bayer数据没法做整体颜色回归;

实现步骤:硬件准备

Baumer相机白平衡的实现过程:

一、硬件准备:前期准备便是将相机的曝光值调到合适的状态,并配合光圈的大小,达到亮度均匀,但又不至于过亮的状态;

二、软件实现步骤:

1、选择非Bayer模式的像素格式,比如BGR8,RGB8,YUV等像素格式,由于每个相机所支持的像素格式并不一致,上面选择非Bayer像素格式就是选择的原则,具体请根据所选用的相机来做选择;如下图所示:

上图选用了YUV422Packed格式来做白平衡;

2、做白平衡,找到Whitebalance,直接点击后面的Execute按钮,即可完成白平衡的实现,如下图所示:

3、为保证相机的采集速度,在做完白平衡之后可以将像素格式改为Bayer格式,如下图所示:

4、保存效果,将白平衡的效果保存,乃至断电之后,仍然可以使用该次白平衡的效果,

如下图所示,使用UserSet来保存效果,这样就可以在相机后续每次彩图都可以达到比较好的色彩效果,如下,首先选择UserSetSelector中的Userset1--UserSet3,任意选择;

然后点击UserSetSave后面的Comamnd按钮,将数据保存到选择UserSet下;

5、选择UserSetDefaultSelector与上面保存的UserSet一致即可,这样相机每次上电自动加载UserSet下的参数,包括白平衡的效果;


Baumer工业相机白平衡代码如下所示:

private BGAPI_FeatureState WhiteBalanceState = new BGAPI_FeatureState();
private BGAPIX_TypeRangeFLOAT WhiteBalanceWbred = new BGAPIX_TypeRangeFLOAT();
private BGAPIX_TypeRangeFLOAT WhiteBalanceWbgreen = new BGAPIX_TypeRangeFLOAT();
private BGAPIX_TypeRangeFLOAT WhiteBalanceWbblue = new BGAPIX_TypeRangeFLOAT();
private BGAPIX_TypeROI WhiteBalanceRoi = new BGAPIX_TypeROI();

public bool RefreshWhiteBalanceControls()
{
    BGAPI_FeatureState roiState = new BGAPI_FeatureState();
    BGAPI_FeatureState colorgainState = new BGAPI_FeatureState();

    if (mCamera.getWhitebalanceRoi(ref roiState, ref WhiteBalanceRoi) != BGAPI.Result.OK)
        return false;
    if (mCamera.getColorGains(ref colorgainState, ref WhiteBalanceWbred, ref WhiteBalanceWbgreen, ref WhiteBalanceWbblue) != BGAPI.Result.OK)
        return false;

    WhiteBalanceState.bIsImpl = (roiState.bIsImpl == true || colorgainState.bIsImpl == true) ? true : false;
    WhiteBalanceState.bIsAvail = (roiState.bIsAvail == true || colorgainState.bIsAvail == true) ? true : false;
    WhiteBalanceState.bIsLock = (roiState.bIsLock == true && colorgainState.bIsLock == true) ? true : false;
    WhiteBalanceState.bIsEnabled = (roiState.bIsEnabled == true || colorgainState.bIsEnabled == true) ? true : false;

    if (roiState.bIsAvail && roiState.bIsImpl)
    {
        //roi
        numericUpDownL.BeginInit();
        numericUpDownT.BeginInit();
        numericUpDownR.BeginInit();
        numericUpDownB.BeginInit();

        numericUpDownL.Minimum = WhiteBalanceRoi.minleft;
        numericUpDownT.Minimum = WhiteBalanceRoi.mintop;
        numericUpDownR.Minimum = WhiteBalanceRoi.minright;
        numericUpDownB.Minimum = WhiteBalanceRoi.minbottom;

        numericUpDownL.Maximum = WhiteBalanceRoi.maxleft;
        numericUpDownT.Maximum = WhiteBalanceRoi.maxtop;
        numericUpDownR.Maximum = WhiteBalanceRoi.maxright;
        numericUpDownB.Maximum = WhiteBalanceRoi.maxbottom;

        numericUpDownL.Value = WhiteBalanceRoi.curleft;
        numericUpDownT.Value = WhiteBalanceRoi.curtop;
        numericUpDownR.Value = WhiteBalanceRoi.curright;
        numericUpDownB.Value = WhiteBalanceRoi.curbottom;

        numericUpDownL.EndInit();
        numericUpDownT.EndInit();
        numericUpDownR.EndInit();
        numericUpDownB.EndInit();

        left_min.Text = WhiteBalanceRoi.minleft.ToString();
        top_min.Text = WhiteBalanceRoi.mintop.ToString();
        right_min.Text = WhiteBalanceRoi.minright.ToString();
        bottom_min.Text = WhiteBalanceRoi.minbottom.ToString();

        left_max.Text = WhiteBalanceRoi.maxleft.ToString();
        top_max.Text = WhiteBalanceRoi.maxtop.ToString();
        right_max.Text = WhiteBalanceRoi.maxright.ToString();
        bottom_max.Text = WhiteBalanceRoi.maxbottom.ToString();

        trackBarL.BeginInit();
        trackBarT.BeginInit();
        trackBarR.BeginInit();
        trackBarB.BeginInit();

        trackBarL.Minimum = WhiteBalanceRoi.minleft;
        trackBarT.Minimum = WhiteBalanceRoi.mintop;
        trackBarR.Minimum = WhiteBalanceRoi.minright;
        trackBarB.Minimum = WhiteBalanceRoi.minbottom;

        trackBarL.Maximum = WhiteBalanceRoi.maxleft;
        trackBarT.Maximum = WhiteBalanceRoi.maxtop;
        trackBarR.Maximum = WhiteBalanceRoi.maxright;
        trackBarB.Maximum = WhiteBalanceRoi.maxbottom;

        trackBarL.Value = WhiteBalanceRoi.curleft;
        trackBarT.Value = WhiteBalanceRoi.curtop;
        trackBarR.Value = WhiteBalanceRoi.curright;
        trackBarB.Value = WhiteBalanceRoi.curbottom;

        button1.Enabled = true;
        trackBarL.Enabled = true;
        trackBarT.Enabled = true;
        trackBarR.Enabled = true;
        trackBarB.Enabled = true;
        numericUpDownL.Enabled = true;
        numericUpDownT.Enabled = true;
        numericUpDownR.Enabled = true;
        numericUpDownB.Enabled = true;

        trackBarL.EndInit();
        trackBarT.EndInit();
        trackBarR.EndInit();
        trackBarB.EndInit();
    }
    else
    {
        button1.Enabled = false;
        trackBarL.Enabled = false;
        trackBarT.Enabled = false;
        trackBarR.Enabled = false;
        trackBarB.Enabled = false;
        numericUpDownL.Enabled = false;
        numericUpDownT.Enabled = false;
        numericUpDownR.Enabled = false;
        numericUpDownB.Enabled = false;
    }

	//white balance factors
	textBoxR.Text = WhiteBalanceWbred.current.ToString();
	textBoxG.Text = WhiteBalanceWbgreen.current.ToString();
	textBoxB.Text = WhiteBalanceWbblue.current.ToString();
			
	red_min.Text = WhiteBalanceWbred.minimum.ToString();
	green_min.Text = WhiteBalanceWbgreen.minimum.ToString();
	blue_min.Text = WhiteBalanceWbblue.minimum.ToString();

	red_max.Text = WhiteBalanceWbred.maximum.ToString();
	green_max.Text = WhiteBalanceWbgreen.maximum.ToString();
	blue_max.Text = WhiteBalanceWbblue.maximum.ToString();

	trackBarRed.BeginInit();
	trackBarGreen.BeginInit();
	trackBarBlue.BeginInit();

	trackBarRed.Minimum = (int)(WhiteBalanceWbred.minimum * 100);
	trackBarGreen.Minimum = (int)(WhiteBalanceWbgreen.minimum * 100);
	trackBarBlue.Minimum = (int)(WhiteBalanceWbblue.minimum * 100);

	trackBarRed.Maximum = (int)(WhiteBalanceWbred.maximum * 100);
	trackBarGreen.Maximum = (int)(WhiteBalanceWbgreen.maximum * 100);
	trackBarBlue.Maximum = (int)(WhiteBalanceWbblue.maximum * 100);

	trackBarRed.Value = (int)( WhiteBalanceWbred.current * 100 );
	trackBarGreen.Value = (int)( WhiteBalanceWbgreen.current * 100 );
	trackBarBlue.Value = (int)( WhiteBalanceWbblue.current * 100 );

	trackBarRed.EndInit();
	trackBarGreen.EndInit();
	trackBarBlue.EndInit();
	return true;
}

注意要点

工业相机的白平衡条件需要注意光线的色温和环境的色彩,以确保适当的白平衡。

此外,重要的是要平衡相机设置与理想的效果,并确保白平衡设置匹配的照明环境

工业相机的白平衡条件取决于照明条件和相机的使用环境。

一般来说,工业相机被设计为具有可定制的白平衡设置,以确保在不同的照明条件下准确的色彩再现。

白平衡模式可以根据相机的规格手动或自动调整。

重要的是,要查阅相机的用户手册或制造商的指导方针,以了解如何为特定应用优化白平衡设置的具体说明。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
相机数据流bitmap是指从相机中获取的图像数据以Bitmap格式表示的流。在Baumer的万兆网工业相机中,可以使用Baumer的BGAPI SDK来实现相机数据流转换为Bitmap格式的功能。具体实现方法是,在C++的环境下,先将Buffer图像数据转换为Gdiplus::Bitmap对象,然后将该Bitmap对象保存在图像数组中,并写入电脑内存,最后释放保存到本地。这样就可以实现高速采集相机数据流并以Bitmap格式存储到本地的功能。\[1\] 如果在项目中需要使用第三方人脸识别SDK,该SDK可能提供的是Raw格式的图像数据。在这种情况下,需要将Raw格式的图像数据转换为Bitmap格式,以便进行人脸注册和识别。\[2\] 在Baumer万兆网工业相机VLXT-28M.I中,可以使用C++平台下的核心代码来实现相机数据流以Bitmap格式存储到本地的功能。这个过程涉及将相机数据流转换为Gdiplus::Bitmap对象,并将其存入Gdiplus::Bitmap数组,最后进行释放。\[3\] #### 引用[.reference_title] - *1* *3* [Baumer工业相机堡盟相机如何通过BGAPI SDK将相机图像数据转换为Gdiplus::Bitmap并写入电脑内存最后释放保存...](https://blog.csdn.net/xianzuzhicai/article/details/129889798)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [相机原始数据转Bitmap](https://blog.csdn.net/weixin_33544435/article/details/114215063)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

格林威

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值