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各类算子含义及用法,有…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
接口 RESTful 中的超媒体:REST 架构的灵魂驱动
在 RESTful 架构中,** 超媒体(Hypermedia)** 是一个核心概念,它体现了 REST 的 “表述性状态转移(Representational State Transfer)” 的本质,也是区分 “真 RESTful API” 与 “伪 RESTful AP…...
VASP软件在第一性原理计算中的应用-测试GO
VASP软件在第一性原理计算中的应用 VASP是由维也纳大学Hafner小组开发的一款功能强大的第一性原理计算软件,广泛应用于材料科学、凝聚态物理、化学和纳米技术等领域。 VASP的核心功能与应用 1. 电子结构计算 VASP最突出的功能是进行高精度的电子结构计算ÿ…...
