当前位置: 首页 > news >正文

Baumer工业相机堡盟工业相机如何通过BGAPI SDK将相机图像数据用二进制的方式保存到本地(C++)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK将相机图像数据用二进制的方式保存到本地(C++)

  • Baumer工业相机
  • Baumer工业相机将图像保存为二进制图像的技术背景
  • 代码分析
    • 第一步:先转换Byte*图像为二进制图像
    • 第二步:在回调函数里进行Buffer图像转换为二进制图像进行保存
    • 第三步:将二进制数据保存为图像文件
  • 工业相机通过SDK将图像保存二进制图像的优点
  • 工业相机通过SDK将图像保存二进制图像的行业应用

Baumer工业相机

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

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

Baumer工业相机中原始图像可以通过BGAPI SDK和其它图像处理库进行联合保存成各种格式的图像,比如和Halcon联合、比如和OpenCV联合、比如和GDI+图像库联合等等,若在高速采图领域,任何的图像转换过程可能都会造成效率的降低,因此直接保存原始数据的图像是最为快速的。

Baumer工业相机将图像保存为二进制图像的技术背景

工业相机通常通过一个传感器实时捕捉高分辨率的图像,该传感器将光转换为电信号。这些信号然后由相机的图像处理硬件和软件转换成数字二进制图像。二进制图像由黑色和白色像素组成,每个像素由一个比特表示,要么是0,要么是1,0代表黑色像素,1代表白色像素。

工业相机经常使用二进制图像,因为它们在某些应用中更有效,更容易处理。二进制图像比彩色图像或灰度图像占用的存储空间更少。这使它们成为需要存储或传输大量图像的应用的理想选择,例如在制造业质量控制或安全监控中。二进制图像也更容易使用算法和软件进行分析和处理,这对检测缺陷、跟踪物体和识别图像数据中的模式很有帮助。

总的来说,工业相机将图像保存为二进制图像的技术背景是基于工业和制造业应用中对高速、有效处理大量图像数据的需要。

有关于Baumer万兆网工业相机堡盟相机VLXT-28M.I如何做全帧率图像存储到本地的介绍,之前已经有相关的技术博客可以参考:

Baumer万兆网工业相机堡盟相机VLXT-28M.I如何做全帧率图像存储到本地

这里主要描述如何在C++的平台下实现通过BGAPI SDK实现二进制保存图像功能的核心代码

代码分析

本文介绍使用BGAPI SDK对Baumer的工业相机进行开发时,使用通过BGAPI SDK获取相机的原始图像数据Byte*,然后直接将图像数据转为二进制图像保存到本地。
一般讲Byte图像数据转换为二进制进行保存可以分为以下几步:
1、将Byte
图像加载到内存中,即创建一个字节数组来保存数据。
2、确定图像的尺寸(宽度和高度),并计算出像素总数。
3、分配第二个相同大小的字节数组来保存二进制数据。
4、循环浏览图像中的每个像素,将其颜色值从字节转换成二进制(0或1)
5、将二进制数据阵列存储在一个文件或数据库中,用于本地存储。

如下为核心代码实现步骤:

第一步:先转换Byte*图像为二进制图像

C++环境下将Byte*图像保存为二进制图像如下所示:

unsigned char* imageData = // Byte*图像数据
int imageSize = // 图像数据的大小std::vector<unsigned char> binaryData(imageSize * 8);
for (int i = 0; i < imageSize; i++) {for (int j = 0; j < 8; j++) {binaryData[i * 8 + j] = (imageData[i] >> j) & 1;}
}

第二步:在回调函数里进行Buffer图像转换为二进制图像进行保存

下面为在在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 againpBufferFilled->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());//获取当前图像数据#pragma region //保存图像功能if(pDlg->m_bSaveImage &&!pDlg->m_strDirectory.IsEmpty()){CTime time = CTime::GetCurrentTime(); CString strtime;strtime.Format(_T("\\%4d%2d%2d%2d%2d%2d"),time.GetYear(),time.GetMonth(),time.GetDay(),time.GetHour(),time.GetMinute(),time.GetSecond());CString  strpath = pDlg->m_strDirectory+strtime+".jpg";pDlg->SaveImageMono(strpath, imagebuffer,width,height);pDlg->m_bSaveImage = false;}#pragma endregion Gdiplus::Rect rc = Gdiplus::Rect(0,0,width,height);#pragma region 黑白相机代码:像素格式为mono时转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);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 // 将Bitmap对象转换为Image对象Image* img = (Image*)m_pBitmap.GetThumbnailImage(width, height, NULL, NULL);//将Image图像进行JPEG图像压缩,压缩质量80CString OutputImagePath = _T("CompressedImage.jpg")CompressImage(img , OutputImagePath , 80);#pragma region //将图像显示在PictureControl控件上HDC hDC = ::GetDC(pDlg->m_stcPicture.m_hWnd);Gdiplus::Graphics GdiplusDC(hDC);CRect rcControl;pDlg->m_stcPicture.GetWindowRect(&rcControl);Gdiplus::Rect rtImage(0,0,rcControl.Width(),rcControl.Height());GdiplusDC.DrawImage(pDlg->m_pBitmap,rtImage,0,0,width,height, Gdiplus::UnitPixel);delete []pal;::ReleaseDC(pDlg->m_stcPicture.m_hWnd,hDC);delete pDlg->m_pBitmap ;pDlg->m_pBitmap =NULL;#pragma endregion // queue buffer againpBufferFilled->QueueBuffer();}}catch (BGAPI2::Exceptions::IException& ex){CString str;str.Format(_T("ExceptionType:%s! ErrorDescription:%s in function:%s"),ex.GetType(),ex.GetErrorDescription(),ex.GetFunctionName());		}	
}

第三步:将二进制数据保存为图像文件

下面为使用将二进制数据保存为图像文件算法的核心代码,如下所示:

int width = // 图像的宽度
int height = // 图像的高度std::ofstream outFile("binary_image.bmp", std::ios::binary);
if (outFile) {// BMP文件头char bmpFileHeader[14] = { 'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0 };// BMP信息头char bmpInfoHeader[40] = { 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };// 计算图像数据的大小int imageDataSize = ((width * height * 1 + 31) / 32) * 4;// BMP文件头中的文件大小*(int*)&bmpFileHeader[2] = 54 + imageDataSize;// BMP信息头中的图像宽度*(int*)&bmpInfoHeader[4] = width;// BMP信息头中的图像高度*(int*)&bmpInfoHeader[8] = height;// BMP信息头中的图像数据大小*(int*)&bmpInfoHeader[20] = imageDataSize;// 写入BMP文件头和BMP信息头outFile.write(bmpFileHeader, 14);outFile.write(bmpInfoHeader, 40);// 写入图像数据for (int i = height - 1; i >= 0; i--) {for (int j = 0; j < width; j++) {unsigned char pixel = 255 * binaryData[i * width + j];outFile.write((char*)&pixel, 1);}// 每行的字节数必须是4的倍数int paddingSize = ((width * 1 + 3) / 4) * 4 - width;if (paddingSize > 0) {char padding[3] = { 0, 0, 0 };outFile.write(padding, paddingSize);}}outFile.close();
}

工业相机通过SDK将图像保存二进制图像的优点

减少了存储空间: 与全色或灰度图像相比,二进制图像占用的存储空间要少得多。这意味着你可以在你的设备上存储更多的图像,这对内存有限的设备特别有用。

更快的处理: 二进制图像比全色或灰度图像更容易被计算机处理。这意味着你的图像分析软件可以更快地分析图像,允许更快的决策和更有效的数据处理。

提高准确性:由于二进制图像更简单,它们更容易准确分析。这对图像识别软件特别有用,因为二进制图像可以使它更容易区分图像中的物体或特征。

一致性: 因为二元图像仅由黑白像素组成,它们的视觉外观更加统一。这使得它们更容易与其他图像进行比较,并为图像分析建立一个标准。

兼容性: 许多图像分析软件是专门为处理二进制图像而设计的,使它们成为需要精确和一致的图像分析的工业相机的理想格式。这意味着通过SDK使用二进制图像可以提高你的相机与其他软件应用的兼容性。

工业相机通过SDK将图像保存二进制图像的行业应用

  1. 质量控制和检查: 二进制图像可用于各种工业制造过程中的缺陷检测和分类,如半导体、电子、汽车和制药行业。

  2. 监视和安全: 二进制图像被广泛用于监控系统,以检测异常情况,识别人脸,或跟踪移动的物体。

  3. 医学成像: 二元图像通常用于医学成像模式,如X射线、CT和MRI,以分割和分析感兴趣的病理区域。

  4. 机器人学和自动化: 二进制图像可用于机器人技术,用于工业环境中的物体识别、跟踪和定位,如仓库、工厂和物流中心。

  5. 农业和环境监测: 二进制图像可用于分析作物健康,识别植物疾病,检测害虫,或监测森林火灾、洪水和自然灾害。

综上所述,通过SDK使用工业相机和二进制图像处理,可以提高各种应用的准确性、速度和可靠性,从而使不同行业受益匪浅。

相关文章:

Baumer工业相机堡盟工业相机如何通过BGAPI SDK将相机图像数据用二进制的方式保存到本地(C++)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK将相机图像数据用二进制的方式保存到本地&#xff08;C&#xff09;Baumer工业相机Baumer工业相机将图像保存为二进制图像的技术背景代码分析第一步&#xff1a;先转换Byte*图像为二进制图像第二步&#xff1a;在回调函数里进行Buf…...

JavaScript模块的导出和导入之export和module.exports的区别

export和module.exports (需要前面的export没有“s”,后面的module.exports 有“s”) 使用两者根本区别是 **exports **返回的是模块函数 **module.exports **返回的是模块对象本身&#xff0c;返回的是一个类 使用上的区别是exports的方法可以直接调用module.exports需要new…...

基于朴素贝叶斯分类器的钞票真伪识别模型

基于朴素贝叶斯分类器的钞票真伪识别模型 内容 本实验通过实现钞票真伪判别案例来展开学习朴素贝叶斯分类器的原理及应用。 本实验的主要技能点&#xff1a; 1、 朴素贝叶斯分类器模型的构建 2、 模型的评估与预测 3、 分类概率的输出 源码下载 环境 操作系统&#xf…...

【Python】【进阶篇】二十二、Python爬虫的BS4解析库

目录二十二、Python爬虫的BS4解析库22.1 BS4下载安装22.2 BS4解析对象22.3 BS4常用语法1) Tag节点22.4 遍历节点22.5 find_all()与find()1) find_all()2) find()22.6 CSS选择器二十二、Python爬虫的BS4解析库 Beautiful Soup 简称 BS4&#xff08;其中 4 表示版本号&#xff0…...

UDS统一诊断服务【五】诊断仪在线0X3E服务

文章目录前言一、诊断仪在线服务介绍二、数据格式2.1&#xff0c;请求报文2.2&#xff0c;子功能2.3&#xff0c;响应报文前言 本文介绍UDS统一诊断服务的0X3E服务&#xff0c;希望能对你有所帮助 一、诊断仪在线服务介绍 诊断仪在线服务比较简单&#xff0c;其功能就是告诉服…...

我的创作纪念日:Unity CEO表示生成式AI将是Unity近期发展重点,发布神秘影片预告

PICK 未来的AI技术将会让人类迎来下一个生产力变革&#xff0c;这其中也包括生成型AI的突破性革新。各大公司也正在竞相推出AIGC工具&#xff0c;其中微软的Copilot、Adobe的Firefly、Github的chatGPT等引起了人们的关注。然而&#xff0c;游戏开发领域似乎还没有一款真正针对性…...

秩亏自由网平差的直接解法

目录 一、原理概述二、案例分析三、代码实现四、结果展示一、原理概述 N = B T P B N=B^TPB N=<...

大数据开发必备面试题Spark篇合集

1、Hadoop 和 Spark 的相同点和不同点&#xff1f; Hadoop 底层使用 MapReduce 计算架构&#xff0c;只有 map 和 reduce 两种操作&#xff0c;表达能力比较欠缺&#xff0c;而且在 MR 过程中会重复的读写 hdfs&#xff0c;造成大量的磁盘 io 读写操作&#xff0c;所以适合高时…...

C ++匿名函数:揭开C++ Lambda表达式的神秘面纱

潜意识编程&#xff1a;揭秘C Lambda表达式的神秘面纱 Subconscious Programming: Unveiling the Mystery of C Lambda Expressions 引言&#xff1a;Lambda表达式的魅力 (The Charm of C Lambda Expressions)Lambda表达式简介与基本概念 (Introduction and Basic Concepts of …...

AOP使用场景记录总结(缓慢补充更新中)

测试项目结构: 目前是测试两个日志记录和 代码的性能测试 后面如果有其他的应用场景了在添加.其实一中就包括了二,但是没事,多练一遍 1. 日志记录 比如说对service层中的所有增加,删除,修改方法添加日志, 记录内容包括操作的时间 操作的方法, 方法的参数, 方法所在的类, 方法…...

FPGA基于XDMA实现PCIE X4的HDMI视频采集 提供工程源码和QT上位机程序和技术支持

目录1、前言2、我已有的PCIE方案3、PCIE理论4、总体设计思路和方案5、vivado工程详解6、驱动安装7、QT上位机软件8、上板调试验证9、福利&#xff1a;工程代码的获取1、前言 PCIE&#xff08;PCI Express&#xff09;采用了目前业内流行的点对点串行连接&#xff0c;比起 PCI …...

ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析

查看原文>>>ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析 目录 专题一、空间数据获取与制图 专题二、ArcGIS专题地图制作 专题三、空间数据采集与处理 专题四、遥感数据处理与应用 专题五、DEM数据…...

怎么找回回收站里已经删除的文件

作为忙忙碌碌的打工人&#xff0c;电脑办公是在所难免的&#xff0c;而将使电脑存储着大量的数据文件&#xff0c;不少小伙伴都养成了定期清理电脑的习惯。而清理简单快捷的方法&#xff0c;无疑是直接把文件拖进回收站里。再一键清空&#xff0c;清理工作就完成了。但如果发现…...

Spring Boot、Cloud、Alibaba 版本说明

Spring Boot、Cloud、Alibaba 版本说明 一、毕业版本依赖关系(推荐使用) 由于 Spring Boot 3.0&#xff0c;Spring Boot 2.7~2.4 和 2.4 以下版本之间变化较大&#xff0c;目前企业级客户老项目相关 Spring Boot 版本仍停留在 Spring Boot 2.4 以下&#xff0c;为了同时满足存…...

软件测试入门第一步:编写测试报告

什么是测试报告&#xff1f; 1、说明&#xff1a;是指把测试的过程和结果写成文档&#xff0c;对发现的问题和缺陷进行分析&#xff0c;为纠正软件的存在的质量问题提供依据&#xff0c;同时为软件验收和交付打下基础。 ps. 【测试过程和测试结果的分析报告&#xff0c;以及上线…...

【Vue】vue中的路由导航守卫(路由的生命周期)

文章目录全局前置守卫可选的第三个参数 next全局解析守卫router.beforeResolve全局后置钩子路由独享的守卫组件内的守卫可用的配置 API使用组合 API完整的导航解析流程正如其名&#xff0c;vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入…...

NumPy 基础知识 :6~10

原文&#xff1a;Numpy Essentials 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 六、NumPy 中的傅立叶分析 除其他事项外&#xff0c;傅立叶分析通常用于数字信号处理。 这要归功于它在将输入信号&#xff08;时域&#xff09;分离为以离散频率&#xff08;频域&am…...

实现vue的条件渲染

我的需求是根据设备不同的状态 渲染不同的标签。设备状态用device_State表示。 在线上面是一个vue的标签&#xff0c;我有一个数据state &#xff0c;如何让这个标签根据数据的取值 &#xff0c;修改内容&#xff0c;如state1时&#xff0c;标签修改为离线 要根据数据的取值动态…...

第四章 word2vec 的高速化

目录4.1 word2vec 的改进①4.1.1 Embedding 层4.1.2 Embedding 层的实现4.2 word2vec 的改进②4.2.1 中间层之后的计算问题4.2.2 从多分类到二分类4.2.3 sigmoid 函数和交叉熵误差4.2.4 多分类到二分类的实现4.2.5 负采样4.2.6 负采样的采样方法4.2.7 负采样的实现4.3 改进版 w…...

【四】3D Object Model之创建Creation——clear_object_model_3d()/copy_object_model_3d()算子

&#x1f60a;&#x1f60a;&#x1f60a;欢迎来到本博客&#x1f60a;&#x1f60a;&#x1f60a; &#x1f31f;&#x1f31f;&#x1f31f; Halcon算子太多&#xff0c;学习查找都没有系统的学习查找路径&#xff0c;本专栏主要分享Halcon各类算子含义及用法&#xff0c;有…...

第三十一章 配置镜像 - 删除镜像成员时删除镜像数据库属性

文章目录第三十一章 配置镜像 - 删除镜像成员时删除镜像数据库属性删除镜像成员时删除镜像数据库属性编辑或删除异步成员第三十一章 配置镜像 - 删除镜像成员时删除镜像数据库属性 删除镜像成员时删除镜像数据库属性 当从镜像中删除成员时&#xff0c;始终可以选择从属于该镜…...

自动写作ai-自动写作神器

自动生成文章 自动生成文章是指使用自然语言处理和人工智能技术&#xff0c;通过算法来自动生成文章的过程。一些自动生成文章的工具可以使用大量数据&#xff0c;学习数据背后的语言规范和知识结构&#xff0c;从而生成高质量和有用的文章。这种技术能够减少写作时间和人力成…...

P1368 【模板】最小表示法(SAM 求最小循环移位)

【模板】最小表示法 题目描述 小敏和小燕是一对好朋友。 他们正在玩一种神奇的游戏&#xff0c;叫 Minecraft。 他们现在要做一个由方块构成的长条工艺品。但是方块现在是乱的&#xff0c;而且由于机器的要求&#xff0c;他们只能做到把这个工艺品最左边的方块放到最右边。…...

投票感知器参数学习算法

投票感知器参数学习算法 以下为投票感知器参数学习算法的伪代码&#xff1a; 输入&#xff1a;训练集 (x1,y1),(x2,y2),...,(xn,yn)(x_1, y_1), (x_2, y_2), ..., (x_n, y_n)(x1​,y1​),(x2​,y2​),...,(xn​,yn​)&#xff0c;学习率 η\etaη&#xff0c;最大迭代次数 TTT…...

Hyper-v下安装CentOS-Stream-9

1、我不想要动态扩展的硬盘&#xff0c;固定大小硬盘性能更高&#xff0c;所以这里我先创建一个固定硬盘&#xff08;如果你想用动态扩展的硬盘&#xff0c;那么可以省略前面几步&#xff0c;直接从第7步开始&#xff0c;并在第12步选择创建可动态扩展的虚拟硬盘&#xff09;&a…...

数据结构之顺序表,实现顺序表的增删改查

目录 一、顺序表的概念 二、顺序表的分类 1.静态顺序表 2.动态顺序表 3.顺序表的增删改查 总结 一、顺序表的概念 顺序表是一段物理地址连续的村塾单元依次存储数据元素的线性结构&#xff0c;一般情况下使用数组存储&#xff0c;在数组上完成数据的增删改查。 二、顺…...

HTB-Jeeves

HTB-Jeeves信息收集80端口50000端口![在这里插入图片描述](https://img-blog.csdnimg.cn/5824bf345bc040ee9e449bebeade9495.png)开机kohsuke -> Administrator信息收集 80端口 ask jeeves是一款以回答用户问题提问的自然语言引擎&#xff0c;面对问题首先查看数据库里是否…...

大力出奇迹——GPT系列论文学习(GPT,GPT2,GPT3,InstructGPT)

目录说在前面1.GPT1.1 引言1.2 训练范式1.2.1 无监督预训练1.2.2 有监督微调1.3 实验2. GPT22.1 引言2.2 模型结构2.3 训练范式2.4 实验3.GPT33.1引言3.2 模型结构3.3 训练范式3.4 实验3.4.1数据集3.5 局限性4. InstructGPT4.1 引言4.2 方法4.2.1 数据收集4.2.2 各部分模型4.3 …...

Linux ubuntu更新meson版本

问题描述 在对项目源码用meson进行编译时&#xff0c;可能出现以下错误 meson.build:1:0: ERROR: Meson version is 0.45.1 but project requires > 0.58.0. 或者 meson_options.txt:1:0: ERROR: Unknown type feature. 等等&#xff0c;原因是meson版本跟设置的不适配。 …...

匹配yyyy-MM-dd日期格式的正则表达式

^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ 解释&#xff1a; ^&#xff1a;匹配行的开头 \d{4}&#xff1a;匹配四个数字&#xff0c;表示年份 -&#xff1a;匹配一个横杠 (0[1-9]|1[0-2])&#xff1a;匹配01到12的月份&#xff0c;0开头的要匹配两位数字&#xff0c;1开…...