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将图像保存二进制图像的行业应用
-
质量控制和检查: 二进制图像可用于各种工业制造过程中的缺陷检测和分类,如半导体、电子、汽车和制药行业。
-
监视和安全: 二进制图像被广泛用于监控系统,以检测异常情况,识别人脸,或跟踪移动的物体。
-
医学成像: 二元图像通常用于医学成像模式,如X射线、CT和MRI,以分割和分析感兴趣的病理区域。
-
机器人学和自动化: 二进制图像可用于机器人技术,用于工业环境中的物体识别、跟踪和定位,如仓库、工厂和物流中心。
-
农业和环境监测: 二进制图像可用于分析作物健康,识别植物疾病,检测害虫,或监测森林火灾、洪水和自然灾害。
综上所述,通过SDK使用工业相机和二进制图像处理,可以提高各种应用的准确性、速度和可靠性,从而使不同行业受益匪浅。
相关文章:
Baumer工业相机堡盟工业相机如何通过BGAPI SDK将相机图像数据用二进制的方式保存到本地(C++)
Baumer工业相机堡盟工业相机如何通过BGAPI SDK将相机图像数据用二进制的方式保存到本地(C)Baumer工业相机Baumer工业相机将图像保存为二进制图像的技术背景代码分析第一步:先转换Byte*图像为二进制图像第二步:在回调函数里进行Buf…...
JavaScript模块的导出和导入之export和module.exports的区别
export和module.exports (需要前面的export没有“s”,后面的module.exports 有“s”) 使用两者根本区别是 **exports **返回的是模块函数 **module.exports **返回的是模块对象本身,返回的是一个类 使用上的区别是exports的方法可以直接调用module.exports需要new…...

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

【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(其中 4 表示版本号࿰…...

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

我的创作纪念日:Unity CEO表示生成式AI将是Unity近期发展重点,发布神秘影片预告
PICK 未来的AI技术将会让人类迎来下一个生产力变革,这其中也包括生成型AI的突破性革新。各大公司也正在竞相推出AIGC工具,其中微软的Copilot、Adobe的Firefly、Github的chatGPT等引起了人们的关注。然而,游戏开发领域似乎还没有一款真正针对性…...
秩亏自由网平差的直接解法
目录 一、原理概述二、案例分析三、代码实现四、结果展示一、原理概述 N = B T P B N=B^TPB N=<...
大数据开发必备面试题Spark篇合集
1、Hadoop 和 Spark 的相同点和不同点? Hadoop 底层使用 MapReduce 计算架构,只有 map 和 reduce 两种操作,表达能力比较欠缺,而且在 MR 过程中会重复的读写 hdfs,造成大量的磁盘 io 读写操作,所以适合高时…...

C ++匿名函数:揭开C++ Lambda表达式的神秘面纱
潜意识编程:揭秘C Lambda表达式的神秘面纱 Subconscious Programming: Unveiling the Mystery of C Lambda Expressions 引言: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、福利:工程代码的获取1、前言 PCIE(PCI Express)采用了目前业内流行的点对点串行连接,比起 PCI …...

ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析
查看原文>>>ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升环境、生态、水文、土地、土壤、农业、大气等领域的数据分析 目录 专题一、空间数据获取与制图 专题二、ArcGIS专题地图制作 专题三、空间数据采集与处理 专题四、遥感数据处理与应用 专题五、DEM数据…...
怎么找回回收站里已经删除的文件
作为忙忙碌碌的打工人,电脑办公是在所难免的,而将使电脑存储着大量的数据文件,不少小伙伴都养成了定期清理电脑的习惯。而清理简单快捷的方法,无疑是直接把文件拖进回收站里。再一键清空,清理工作就完成了。但如果发现…...
Spring Boot、Cloud、Alibaba 版本说明
Spring Boot、Cloud、Alibaba 版本说明 一、毕业版本依赖关系(推荐使用) 由于 Spring Boot 3.0,Spring Boot 2.7~2.4 和 2.4 以下版本之间变化较大,目前企业级客户老项目相关 Spring Boot 版本仍停留在 Spring Boot 2.4 以下,为了同时满足存…...

软件测试入门第一步:编写测试报告
什么是测试报告? 1、说明:是指把测试的过程和结果写成文档,对发现的问题和缺陷进行分析,为纠正软件的存在的质量问题提供依据,同时为软件验收和交付打下基础。 ps. 【测试过程和测试结果的分析报告,以及上线…...
【Vue】vue中的路由导航守卫(路由的生命周期)
文章目录全局前置守卫可选的第三个参数 next全局解析守卫router.beforeResolve全局后置钩子路由独享的守卫组件内的守卫可用的配置 API使用组合 API完整的导航解析流程正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入…...

NumPy 基础知识 :6~10
原文:Numpy Essentials 协议:CC BY-NC-SA 4.0 译者:飞龙 六、NumPy 中的傅立叶分析 除其他事项外,傅立叶分析通常用于数字信号处理。 这要归功于它在将输入信号(时域)分离为以离散频率(频域&am…...

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

第四章 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()算子
😊😊😊欢迎来到本博客😊😊😊 🌟🌟🌟 Halcon算子太多,学习查找都没有系统的学习查找路径,本专栏主要分享Halcon各类算子含义及用法,有…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...