Baumer工业相机堡盟工业相机如何通过BGAPI SDK转换和显示偏振相机的图像(C++)

简介: Baumer工业相机堡盟工业相机如何通过BGAPI SDK转换和显示偏振相机的图像(C++)

Baumer工业相机

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


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

Baumer工业相机的BGAPI SDK给新型偏振相机提供了测量所获图像的强度和偏振的能力。因此,它能够在应用程序中利用偏振信息。本应用说明描述了如何获得偏振相机的图像数据并进行转换和显示的功能。


Baumer工业相机的偏振相机的技术背景

Baumer工业相机的BGAPI SDK可以提供相机的图像原始数据,Halcon具有极为巨大的图像处理库,在图像处理领域非常强大,功能丰富,使用于工业视觉检测。


工业相机的SDK(Software Development Kit)是为了方便开发人员对工业相机进行控制和图像采集而提供的一套软件工具。而Halcon是一款强大的机器视觉软件,能够进行图像处理、分析、识别等多种任务。


Baumer工业相机中的偏振相机是基于索尼IMC250MZR传感器的。该传感器涂有一层金属网,可以过滤4个相邻像素的偏振信息。偏振角度被过滤以0°、45°、90°、135°的方式排列。

有了这些信息,就可以计算出以下数据:

偏振角(AOP)。

直线极化度(DOLP)

角度和直角极化度(ADOLP)

图像的强度。


Baumer工业相机通过BGAPI SDK在回调函数里显示偏振相机的图像

Baumer工业相机集成偏振功能,下面介绍在C++里Baumer工业相机显示偏振相机的图像的方式


1.引用合适的类文件

代码如下(示例):


#include <stdio.h>
#include <iostream>
#include <iomanip>
#include <set>
#include <vector>
#include <algorithm>
#include <string>
#include "bgapi2_genicam/bgapi2_genicam.hpp"

2.Baumer工业相机在BufferEvent转换并显示偏振相机图像

Baumer工业相机BGAPI SDK的图像处理库中提供了可以将偏振图像格式转换为合适适用格式的图像算法。


在回调函数里转换并显示偏振格式图像,C#调用代码如下所示:

//图像回调函数
//==================
void BGAPI2CALL BufferHandler( void * callBackOwner, Buffer * pBufferFilled )
{
  CGigeDemoDlg* pDlg = (CGigeDemoDlg*)callBackOwner;
  unsigned char* imagebuffer = NULL;
  USES_CONVERSION;
  try
  {
  if(pBufferFilled == NULL)
  {
  }
  else if(pBufferFilled->GetIsIncomplete() == true)
  {
    // queue buffer again
    pBufferFilled->QueueBuffer();
  }
  else
  {
    pDlg->FrameID= pBufferFilled->GetFrameID();                                                 //获取当前图像FrameID显示帧率
    int frameid1 = pBufferFilled->GetFrameID();    
    int width = 0, height = 0;
    width = (int)pBufferFilled->GetWidth();height = (int)pBufferFilled->GetHeight();    //获取当前图像像素长宽
    CString PixelFormat1 = (CString)pBufferFilled->GetPixelFormat();        //获取当前图像像素格式
    imagebuffer = (BYTE*)((bo_int64)pBufferFilled->GetMemPtr()+pBufferFilled->GetImageOffset());//获取当前图像数据
    // A Baumer Polarization Camera can be recognized by checking that the feature
// ComponentSelector has the value "PolarizedRaw"
  if (pDevice->GetRemoteNodeList()->GetNodePresent("ComponentSelector"))
  {
    if (pDevice->GetRemoteNode("ComponentSelector")->GetValue() == "PolarizedRaw")
    {
    // I'm a Polarization Camera
    }
  }
  // Acquire an image to a buffer
  BGAPI2::Buffer* pBufferFilled = pDataStream->GetFilledBuffer(1000);
  bo_uint width = static_cast<bo_uint>(pBufferFilled->GetWidth());
  bo_uint height = static_cast<bo_uint>(pBufferFilled->GetHeight());
  void* pBufferData = pBufferFilled->GetMemPtr();
  bo_uint64 bufferDataSize = pBufferFilled->GetMemSize();
  bo_uint64 imageOffset = pBufferFilled->GetImageOffset();
  // Enable all polarized formats (AOP, DOLP, ADOLP, Intensity)
  BGAPI2::Node* pCompSelector = pImage->GetNode("ComponentSelector");
  BGAPI2::NodeMap*pComponents = pCompSelector->GetEnumNodeList();
  for (bo_uint64 i = 0; i < pComponents->GetNodeCount(); i++)
  {
      pCompSelector->SetInt(i);
      pImage->GetNode("ComponentEnable")->SetBool( true );
  }
  // Calculate all the polarization formats from the raw image to a multi-part Image object.
  BGAPI2::Image* pMultiPartImage = pImageProcessor->CreateTransformedImage(pImage, "Mono8");
  int width = (int)pTranImage->GetWidth();
  int height = (int)pTranImage->GetHeight();
  imagebuffer = (BYTE*)((bo_int64)pTranImage->GetBuffer()+pBufferFilled->GetImageOffset());
  #pragma region 生成//制作一个相关大小的空白黑白Bitmap图像
  if (pDlg->m_pBitmap == NULL)
  {
  pDlg->m_pBitmap = new Gdiplus::Bitmap(width, height, PixelFormat8bppIndexed);
  }
  Gdiplus::BitmapData lockedbits;
  Gdiplus::ColorPalette * pal = (Gdiplus::ColorPalette*)new BYTE[sizeof(Gdiplus::ColorPalette) + 255 *  sizeof(Gdiplus::ARGB)];
  pal->Count = 256;
  for (UINT i = 0;i<256;i++)
  {
  UINT color = i * 65536 + i * 256 + i;
  color = color | 0xFF000000;
  pal->Entries[i] = color;
  }
  pDlg->m_pBitmap->SetPalette(pal);
  #pragma endregion 
  #pragma region //将图像数据写入前面生成的空白Bitmap图像
  Gdiplus::Rect rc = Gdiplus::Rect(0,0,width,height);
  Gdiplus::Status ret = pDlg->m_pBitmap->LockBits(&rc, Gdiplus::ImageLockModeWrite, PixelFormat8bppIndexed, &lockedbits);
  BYTE* pixels = (BYTE*)lockedbits.Scan0;
  BYTE* src = (BYTE*)imagebuffer;
  for (int row = 0; row < height; ++row)
  {
  CopyMemory(pixels, src, lockedbits.Stride);
  pixels += width;
  src += width;
  }
  pDlg->m_pBitmap->UnlockBits(&lockedbits);
  #pragma endregion 
    // queue buffer again
    pBufferFilled->QueueBuffer();
  }
  }
  catch (BGAPI2::Exceptions::IException& ex)
  {
  CString str;
  str.Format(_T("ExceptionType:%s! ErrorDescription:%s in function:%s"),ex.GetType(),ex.GetErrorDescription(),ex.GetFunctionName());  
  } 
}

3.Baumer工业相机BGAPI SDK转换偏振图像的具体步骤

C++调用核心代码如下所示:

int width = (int)pTranImage->GetWidth();
int height = (int)pTranImage->GetHeight();
imagebuffer = (BYTE*)((bo_int64)pTranImage->GetBuffer()+pBufferFilled->GetImageOffset());
#pragma region 生成//制作一个相关大小的空白黑白Bitmap图像
if (pDlg->m_pBitmap == NULL)
{
  pDlg->m_pBitmap = new Gdiplus::Bitmap(width, height, PixelFormat8bppIndexed);
}
Gdiplus::BitmapData lockedbits;
Gdiplus::ColorPalette * pal = (Gdiplus::ColorPalette*)new BYTE[sizeof(Gdiplus::ColorPalette) + 255 * sizeof(Gdiplus::ARGB)];
pal->Count = 256;
for (UINT i = 0;i<256;i++)
{
  UINT color = i * 65536 + i * 256 + i;
  color = color | 0xFF000000;
  pal->Entries[i] = color;
}
pDlg->m_pBitmap->SetPalette(pal);
#pragma endregion 
#pragma region //将图像数据写入前面生成的空白Bitmap图像
Gdiplus::Rect rc = Gdiplus::Rect(0,0,width,height);
Gdiplus::Status ret = pDlg->m_pBitmap->LockBits(&rc, Gdiplus::ImageLockModeWrite, PixelFormat8bppIndexed, &lockedbits);
BYTE* pixels = (BYTE*)lockedbits.Scan0;
BYTE* src = (BYTE*)imagebuffer;
for (int row = 0; row < height; ++row)
{
  CopyMemory(pixels, src, lockedbits.Stride);
  pixels += width;
  src += width;
}
pDlg->m_pBitmap->UnlockBits(&lockedbits);
#pragma endregion

Baumer工业相机使用偏振相机数据的原因

偏振相机使用偏振滤波器来分离光线的偏振状态,这样可以提高图像的对比度,使得细微的表面形态、反射和透射率等信息被准确地记录下来。这些信息对于工业品质控制、表面形貌评价、材料研究等方面都非常重要。


相比较传统的工业相机,偏振相机还可以减少光线干扰,提高图像细节,增强测量精度,更好地适应复杂的工业环境。


因此,工业相机使用偏振相机的数据可以更加准确地确定产品质量,提高生产效率和效益。


Baumer工业相机使用偏振相机的优势

抑制光逆反射:工业现场中通常会出现光源反射的问题,会干扰图像的质量。偏振相机能够让只有某些角度的光被捕获,而反射产生的光线则被过滤掉。


改善材料的表面检测:很多工业生产中需要对材料、产品的表面缺陷进行检测,例如玻璃、塑料等。偏振相机可以识别和区分这些材料表面的缺陷,并提高检测精度和检测速度。


改善物体外形检测:产品在生产过程中可能会出现形变,或者形状不规则,这些因素都会影响使用普通相机拍摄的效果。而偏振相机采用偏振光线,可以减少这些干扰,提高检测结果的准确度。


增强图像的对比度:偏振相机检测的图像能够显示出物体表面的细节和特征,而不仅仅是颜色和亮度等基本属性,从而提高图像的对比度和分辨率,使得检测结果更准确、更可靠。


Baumer工业相机使用偏振相机的行业应用

工业相机,特别是在机器视觉应用中,偏振相机被用来分析解决许多问题,包括表面缺陷检测、玻璃或透明塑料裂纹检测等。由于偏振相机可以区分材料表面的不同反射率,因此可以减少表面反射和减少模糊图像的存在。


在制造和工业应用中,偏振相机可以用于检测不同方向上的应力,这使得它们可以识别和追踪具有特定工艺标记的物体,从而改善制造和组装的精度。


此外,偏振相机还可用于食品和制药行业中的质量控制,以检测不同材料中的异物和杂质。


工业相机使用偏振相机的行业应用有很多。其中一些包括:


汽车制造:偏振相机可以用于检测汽车表面的缺陷和异物,如油脂和污垢。

塑料行业:偏振相机可以检测塑料制品的裂痕、气孔和异物。

食品行业:偏振相机可以用于检测食品中的异物,如骨头、塑料碎片等。

电子工业:偏振相机可以用于检测电子元件的质量,如半导体器件和电子电路板的质量。

纺织工业:偏振相机可以用于检测纺织品的质量,如纤维的方向、密度和强度。

总的来说,偏振相机在工业中的应用十分广泛,能够帮助生产厂家提高产品品质、提高生产效率和降低生产成本。

目录
相关文章
|
6月前
|
存储 数据采集 数据可视化
【C++】医院PACS医学图像存储和传输系统源码
图像后处理与重建 •MPR\CPR(三维多平面重建) •VRT(三维容积重建) •SSD(三维表面重建) •VE(虚拟内窥镜) •MIP(最大密度投影)、MinIP(最小密度投影) •CalSCore(心脏图像冠脉钙化积分)
93 3
|
3月前
|
数据采集 开发工具 Python
海康威视工业相机SDK+Python+PyQt开发数据采集系统(支持软件触发、编码器触发)
该系统基于海康威视工业相机SDK,使用Python与PyQt开发,支持Gige与USB相机设备的搜索及双相机同时显示。系统提供软件触发与编码器触发模式,并可在数据采集过程中实时保存图像。此外,用户可以调节曝光时间和增益,并进行信息输入,这些信息将被保存至配置文件以便下次自动加载。参数调节与实时预览等功能进一步增强了系统的实用性。
196 1
|
3月前
|
传感器 定位技术 C++
基于C++的GDAL用空白栅格填充长时间序列遥感影像中的缺失图像
然后,定义需要处理的遥感影像路径列表,和识别数据缺失的逻辑。这里我们简化处理,假设已经知道哪一幅图像是缺失的,因此直接跳过识别步骤。
57 1
|
6月前
|
监控 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
73 0
|
5月前
|
算法 Java API
在VC++中使用CxImage库读写图像实现像素操作
在VC++中使用CxImage库读写图像实现像素操作
37 0
|
6月前
|
存储 算法 数据可视化
|
6月前
|
C++ 计算机视觉 Python
【Py调用C++】使用使用python调用C++生成dll处理图像(OPENCV)
【Py调用C++】使用使用python调用C++生成dll处理图像(OPENCV)
178 0
【Py调用C++】使用使用python调用C++生成dll处理图像(OPENCV)
|
7天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
33 4
|
8天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
28 4
|
1月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
27 4