Baumer工业相机堡盟工业相机如何通过BGAPISDK里工具函数来计算工业相机的实时帧率(C++)

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据同步 1个月
简介: Baumer工业相机堡盟工业相机如何通过BGAPISDK里工具函数来计算工业相机的实时帧率(C++)

Baumer工业相机

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


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

Baumer工业相机的实时帧率是工业相机的一个重要参数,因为它影响相机准确捕捉快速移动物体或事件的能力。分辨率、图像质量和可用存储空间等因素也会影响工业相机的帧率。


Baumer工业相机的帧率的技术背景

工业相机的帧率是指相机每秒捕获的单个帧或图像的数量。


帧率越高,意味着摄像机每秒能够捕获更多的图像,从而使视频更流畅、更细腻。


工业相机的帧率取决于各种技术因素,如图像传感器技术、相机的处理速度,以及用于传输数据的连接方法。


图像传感器技术: 摄像机的帧率是由图像传感器读出图像像素数据的速度决定的。与CCD传感器相比,CMOS传感器提供更快的帧率,因为它们可以无损地读出像素。


处理速度:工业相机的帧率会受到相机处理能力的影响。较高的处理速度能使数据读出和传输更快,从而获得更高的帧率。


连接方法: 工业相机的帧率还取决于用于传输数据的连接方法。USB 3.0和千兆以太网提供更快的数据传输率,通常用于工业相机以实现更高的帧率。


总之,工业相机帧率的技术背景由图像传感器技术、处理速度和用于传输数据的连接方法决定。


Baumer工业相机的帧率计算方式

Baumer工业相机帧率的计算方式如下所示:


确定相机的输出格式和分辨率,例如 1920*1080。


然后查找相机的技术规格表,了解它的最大帧速率。最大帧速率是指相机能够捕获的每秒图像帧数的最大值。例如,相机的最大帧速率为 60 帧每秒。


接下来,通过检查相机检测到考虑的接口,从相机中获取图像帧并计算每秒钟传输的帧数。


以通过USB3.0接口连接的标准分辨率相机为例,可以使用以下公式计算帧率:


实时帧数 = 最大帧速率 * 传输带宽利用率


传输带宽利用率 = (像素位深度 * 帧高 * 帧宽 * 实际传输速率) / 8


例如,如果选择了 8 位的像素位深度,相机输出的图像帧大小为 1920x1080 像素,并且实际传输速率为 300 MB/s,则传输带宽利用率为:


(8 * 1080 * 1920 * 300) / 8 = 150.7 MB/s


如果相机的最大帧速率为 60 帧每秒,则实时帧率为:


实时帧数 = 60 * 150.7 / 300 = 30 帧每秒


因此,这个相机在这种配置下的实时帧率为 30 帧每秒。


在BufferEvent声明显示FrameID

在回调函数里声明当前FrameID给予全局变量,C++调用代码如下所示:


.h文件声明:

public:
  static UINT ShowFrame_hThread1(LPVOID pParam);//该线程的调用函数 
  void SetShowFrame();//在这个函数中编写该线程需要完成的任务 
  double FrameID;
  CString m_CurframeID;
  CString m_Cursetframe;
  CString m_CurStreamBitrate;
  afx_msg void OnClose();

回调函数中给予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显示帧率
    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());//获取当前图像数据
  // 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());  
  } 
}

新建线程去计算FrameID来计算帧率,C++调用代码如下所示:

void CGigeDemoDlg::OnBnClickedBtnplay()
{
  // TODO: 在此添加控件通知处理程序代码
  USES_CONVERSION;
  if(m_pDevice != NULL)
  {
  try
  {
    m_pDevice->GetRemoteNode("TriggerMode")->SetString("Off"); //关闭触发模式,进入自由采集图片流模式
    m_pDevice->GetRemoteNode("AcquisitionStart")->Execute();
    #pragma region 线程显示帧率和网口数据通量(做参考)
    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);
  }
  }


设计显示帧率的函数

通过计算FrameID的变化计算帧率,每1s重新计算一次


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

UINT CGigeDemoDlg::ShowFrame_hThread1(LPVOID pParam)
{
  CGigeDemoDlg *dlg = (CGigeDemoDlg *)pParam;
  dlg->SetShowFrame();
  return 0;
}
void CGigeDemoDlg::SetShowFrame()
{
  try
  {
  bool m_bRun0 = true;
  while (m_bRun0)
  {
    if(FrameID>0)
    {
    double CurFrameID1 = FrameID;
    Sleep(1000);
    double CurFrameID2 = FrameID;
    double CalFrameID =(CurFrameID2-CurFrameID1)*1 ;
    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"));
    }
    CString CurFameratestr;
    CurFameratestr.Format(_T("%.1f"),CalFrameID);
    m_Cursetframe = CurFameratestr;
    GetDlgItem(IDC_STCURFRAME)->SetWindowText(CurFameratestr);
    CString CurFamerateID;
    CurFamerateID.Format(_T("%.1f"),CurFrameID1);
    GetDlgItem(IDC_STCURFRAMEID)->SetWindowText(CurFamerateID);
    }
  }
  }
  catch (int e)
  {
  MessageBox(_T("Camera SetShowimage Error"));
  }
}

测试输出结果如下所示:

5.png

4.png

Baumer工业相机通过BGAPI SDK计算帧率的优势

使用带有软件开发工具包(SDK)的工业相机来计算实时帧率有几个优点:


一致、准确的结果: 通过使用SDK,实时帧率可以在不同的系统或应用中准确和一致地计算。


可定制的设置: SDK通常提供广泛的可定制设置,以调整相机设置、图像采集参数和其他影响帧率计算的变量。


高速数据传输: 为高速成像而设计的工业相机通常提供快速的数据传输率,减少延迟并提高计算精度。


多参数监控: 许多SDK使用户能够同时监测多个参数,包括帧率、温度和系统功率使用,确保相机的最佳性能和寿命。


低延时控制: 一个SDK可以实现从远程系统对所有相机功能的低延迟控制,是闭环控制应用的理想选择,如实时检测或运动控制。

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
目录
打赏
0
0
0
0
10
分享
相关文章
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用Force IP强制修改网口IP功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用Force IP强制修改网口IP功能(C++)
91 0
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
680 0
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
120 0
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
46 12
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
53 16
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
1月前
|
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
128 6

热门文章

最新文章