Baumer工业相机堡盟相机BGAPI SDK如何实现显示相机帧率和网口数据通量(C++)

简介: Baumer工业相机堡盟相机BGAPI SDK如何实现显示相机帧率和网口数据通量(C++)

项目场景:

Baumer工业相机堡盟相机传统开发包BGAPI SDK进行工业视觉软件整合时,常常需要将SDK中一些功能整合到图像处理软件中,方便项目的推进使用;


注意:本文是基于Baumer的BGAPI SDK的基础上使用C++语言来实现相机帧率和网口数据通量的实时显示。


问题描述

在项目的图像处理任务中,有时需要将相机的帧率实时显示在图像处理软件的界面上。


但是Baumer BGAPI SDK上没有直接显示帧率的方法函数,这就需要小伙伴们结合SDK自己去写一个了


实现方法步骤1:确认帧率信息

基本上所有的相机图像数据都有一个FrameID,从开启采集后不断增加,一般情况下都是根据FrameID来计算当前相机的实时帧率。


首先,FrameID一般出现在相机图像的回调函数里,先定义全局变量FrameID去获取相机的FrameID。


FrameID在回调函数的代码如下所示

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显示帧率                                             
        }
    }
  catch (BGAPI2::Exceptions::IException& ex)
  {
  CString str;
  str.Format(_T("ExceptionType:%s! ErrorDescription:%s in function:%s"),ex.GetType(),ex.GetErrorDescription(),ex.GetFunctionName());  
  }

实现方法步骤2:定义显示线程

2、在头文件里定义一个线程去显示对应帧率的变化。

static UINT ShowFrame_hThread1(LPVOID pParam);//该线程的调用函数 
void SetShowFrame();//在这个函数中编写该线程需要完成的任务


实现方法步骤3:实现线程方法

3、实现定义的线程方法,通过每秒的计算方式实时计算出相机的图像采集速度帧率


代码如下所示:

UINT CGigeDemoDlg::ShowFrame_hThread1(LPVOID pParam)
{
  CGigeDemoDlg *dlg = (CGigeDemoDlg *)pParam;
  dlg->SetShowFrame();
  return 0;
}
void CGigeDemoDlg::SetShowFrame()
{
  try
  {
  while (m_bRun0)
  {
    if(FrameID>0)
    {
    double CurFrameID1 = FrameID;
    Sleep(1000);
    double CurFrameID2 = FrameID;
    double CalFrameID =(CurFrameID2-CurFrameID1)*1 ;
    //ShowFrame_hThread1->g_criticalsection.Lock(); //边界锁锁定
     同步锁中间可添加需要保护的操作代码,如操作txt文档读、看、写时等。
    //ShowFrame_hThread1->g_criticalsection.Unlock();//边界锁解除
    if(m_pDataStream!=NULL)
    {
      try
      {
      BGAPI2::NodeMap* pDataStreamNodeList = m_pDataStream->GetNodeList();
      if (m_pDataStream->GetTLType() == "GEV") 
      {
        float m_CurStreamBitrateDouble = pDataStreamNodeList->GetNode("Bitrate")->GetDouble();
        m_CurStreamBitrate.Format(_T("%.2f"),m_CurStreamBitrateDouble);
        GetDlgItem(IDC_STCURBITRATE)->SetWindowText(m_CurStreamBitrate+_T(" MBit/s")); //获取网口数据量并显示出来
      }
      }
      catch (CMemoryException* e)
      {}
    }
    CString CurFameratestr;
    CurFameratestr.Format(_T("%.1f"),CalFrameID);                  //获取帧率并显示出来
    m_Cursetframe = CurFameratestr;
    GetDlgItem(IDC_STCURFRAME)->SetWindowText(CurFameratestr);
    }
  }
  }
  catch (int e)
  {
  MessageBox(_T("Camera SetShowimage Error"));
  }
}

实现方法步骤4:启动线程

4、在相机的启动时同时启动该线程


代码如下所示:


void CGigeDemoDlg::OnBnClickedBtnplay()
{
  // TODO: 在此添加控件通知处理程序代码
  USES_CONVERSION;
  if(m_pDevice != NULL)
  {
  try
  {
    m_pDevice->GetRemoteNode("TriggerMode")->SetString("Off"); //关闭触发模式,进入自由采集图片流模式
    m_pDevice->GetRemoteNode("AcquisitionStart")->Execute();
    #pragma region 线程显示帧率和网口数据通量(做参考)
    m_bRun0 = true;
    AfxBeginThread(ShowFrame_hThread1, (void*)this);    
    #pragma endregion 
  }
  catch (BGAPI2::Exceptions::IException& ex)
  {
    CString str1;
    str1.Format(_T("ExceptionType:%s! ErrorDescription:%s in function:%s"),ex.GetType(),ex.GetErrorDescription(),ex.GetFunctionName());
    MessageBox(str1);
  }
  }
}


实现方法步骤5:停止显示线程

5、如何关闭该线程,在相机关闭时需要正常关闭。


代码如下所示:

void CGigeDemoDlg::StopShowFrame_hThread1()
{
  m_bRun0  = FALSE;          //停止帧率和网口数据通量线程执行
  WaitForSingleObject(ShowFrame_hThread1,200);   //一直等待对应线程退出
  Sleep(2000);                                      //线程停止缓冲时间
  /*DWORD exitcode2;
  GetExitCodeThread(ShowFrame_hThread1,&exitcode2);
  ExitThread(exitcode2);   */
}

实现方法步骤6:帧率和网口数据通量显示

6、完成上面的操作后,在相机初始化并开启采图后就可以开启相机当前帧率和网口数据通量的显示

3f26b172e1c949159cb386a745edaec1.png

目录
相关文章
|
监控 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C#)
366 0
|
监控 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
248 0
|
数据采集 开发工具 Python
海康威视工业相机SDK+Python+PyQt开发数据采集系统(支持软件触发、编码器触发)
该系统基于海康威视工业相机SDK,使用Python与PyQt开发,支持Gige与USB相机设备的搜索及双相机同时显示。系统提供软件触发与编码器触发模式,并可在数据采集过程中实时保存图像。此外,用户可以调节曝光时间和增益,并进行信息输入,这些信息将被保存至配置文件以便下次自动加载。参数调节与实时预览等功能进一步增强了系统的实用性。
1847 1
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
11月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
438 12
|
9月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
233 0
|
9月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
372 0
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
220 16
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
12月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。