Baumer工业相机堡盟相机如何使用PixelTransformation像素转换功能(像素转换功能的使用和优点以及行业应用)(C++)

news/2024/4/29 11:11:10/文章来源:https://blog.csdn.net/xianzuzhicai/article/details/129681816

项目场景

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

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

Baumer工业相机堡盟相机中PixelTransformation功能由BGAPI SDK提供的ImageProcesser函数进行转换的,以方便各种场合所需要的不同格式图像。


技术背景

工业相机SDK开发工具包中的像素转换功能通常用于将来自相机传感器的数据转换成可由计算机处理的格式。该功能将原始像素数据(通常表示为一系列数字)转换为可在计算机屏幕上显示或用于进一步分析和处理的图像。

这个功能的具体细节取决于具体的SDK和正在使用的相机,可能有所不同。不过,一般来说,像素转换功能会考虑到相机传感器的颜色深度、用于传输数据的任何压缩或编码,以及可能影响原始像素数据表示方式的任何其他因素。

总的来说,像素转换功能是任何工业相机SDK开发工具包的一个重要组成部分,因为它允许用户以对广泛的应用有用和实用的方式处理相机产生的数据。

工业相机从环境中捕捉图像并将其转换为数字数据。像素转换功能是在模拟信号转换为数字信号的过程中发生的,其中每个像素的特征被修改,以优化所产生的图像的质量。

在mono8和mono12像素格式的情况下,该数字表示每个像素的比特深度。单8相机捕获的灰度图像有256级亮度,而单12相机捕获的灰度图像有4096级亮度。

在转换过程中,像素值根据各种算法进行转换,包括伽玛校正、色彩校正和数字增益,以确保图像准确地表现所拍摄的场景。例如,伽马校正,调整每个像素的亮度值,以补偿相机响应的非线性。


CameraExplorer使用像素转换功能


 

Baumer BGAPI SDK使用像素转换功能

Baumer工业相机堡盟相机SDK示例中005_PixelTransformation.cpp详细介绍了如何配置像素转换功能。

软件SDK示例地址如下所示:Baumer_GAPI_SDK_2.12.0_win_x86_64_cpp\examples\src\0_Common\005_PixelTransformation\005_PixelTransformation.cpp

 

下面代码Demo演示如何通过相机SDK中的Buffer转换Mono8和彩色像素转换为BGR8。

如下所示为C++的部分核心代码:

SystemList 
Open a System 
Get the InterfaceList and fill it Open an Interface 
Get the DeviceList and fill it 
Open a Device // CAPTURE 8 IMAGES
std::cout << " " << std::endl;
std::cout << "CAPTURE & TRANSFORM 4 IMAGES" << std::endl;
std::cout << "############################" << std::endl << std::endl;BGAPI2::Buffer * pBufferFilled = NULL;
try {BGAPI2::Image* pImage = imgProcessor->CreateImage();BGAPI2::Node* pPixelFormatInfoSelector = imgProcessor->GetNode("PixelFormatInfoSelector");BGAPI2::Node* pBytesPerPixel = imgProcessor->GetNode("BytesPerPixel");for (int i = 0; i < 4; i++) {pBufferFilled = pDataStream->GetFilledBuffer(1000);  // timeout 1000 msecif (pBufferFilled == NULL) {std::cout << "Error: Buffer Timeout after 1000 msec" << std::endl << std::endl;} else if (pBufferFilled->GetIsIncomplete() == true) {std::cout << "Error: Image is incomplete" << std::endl << std::endl;// queue buffer againpBufferFilled->QueueBuffer();} else {std::cout << " Image " << std::setw(5) << pBufferFilled->GetFrameID()<< " received in memory address " << std::hex << pBufferFilled->GetMemPtr()<< std::dec << std::endl;// create an image object from the filled buffer and convert itBGAPI2::Image * pTransformImage = NULL;pImage->Init(pBufferFilled);BGAPI2::String sPixelFormat = pImage->GetPixelformat();std::cout << "  pImage.Pixelformat:             "<< pImage->GetPixelformat() << std::endl;std::cout << "  pImage.Width:                   "<< pImage->GetWidth() << std::endl;std::cout << "  pImage.Height:                  "<< pImage->GetHeight() << std::endl;std::cout << "  pImage.Buffer:                  "<< std::hex << pImage->GetBuffer() << std::dec << std::endl;pPixelFormatInfoSelector->SetValue(sPixelFormat);double fBytesPerPixel = pBytesPerPixel->GetAvailable() ? pBytesPerPixel->GetDouble() : 0.0;std::cout << "  Bytes per image:                "<< static_cast<unsigned int>((pImage->GetWidth())*(pImage->GetHeight())*fBytesPerPixel)<< std::endl;std::cout << "  Bytes per pixel:                "<< fBytesPerPixel << std::endl;// display first 6 pixel values of first 6 lines of the image// ========================================================================unsigned char* imageBuffer = (unsigned char *)pImage->GetBuffer();std::cout << "  Address" << std::endl;// set display for uppercase hex numbers filled with '0'std::cout << std::uppercase << std::setfill('0') << std::hex;for (int j = 0; j < 6; j++) {  // first 6 linesvoid* imageBufferAddress = &imageBuffer[static_cast<int>(pImage->GetWidth()*j*fBytesPerPixel)];std::cout << "  " << std::setw(8) << imageBufferAddress << " ";for (int k = 0; k < static_cast<int>(6 * fBytesPerPixel); k++) {  // bytes of first 6 pixelsstd::cout << " " << std::setw(2)<< static_cast<int>(imageBuffer[static_cast<int>(pImage->GetWidth()*j*fBytesPerPixel)+k]);}std::cout << "  ..." << std::endl;}// set display for lowercase dec numbers filled with ' 'std::cout << std::nouppercase << std::setfill(' ') << std::dec;// if pixel format starts with "Mono"if (std::string(pImage->GetPixelformat()).substr(0, 4) == "Mono") {// transform to Mono8pTransformImage = imgProcessor->CreateTransformedImage(pImage, "Mono8");std::cout << " Image "<< std::setw(5) << pBufferFilled->GetFrameID() << " transformed to Mono8" << std::endl;std::cout << "  pTransformImage.Pixelformat:    "<< pTransformImage->GetPixelformat() << std::endl;std::cout << "  pTransformImage.Width:          "<< pTransformImage->GetWidth() << std::endl;std::cout << "  pTransformImage.Height:         "<< pTransformImage->GetHeight() << std::endl;std::cout << "  pTransformImage.Buffer:         "<< std::hex << pTransformImage->GetBuffer() << std::dec << std::endl;std::cout << "  Bytes per image:                "<< pTransformImage->GetWidth() * pTransformImage->GetHeight() * 1 << std::endl;std::cout << "  Bytes per pixel:                "<< 1.0 << std::endl;unsigned char* transformBuffer = (unsigned char *)pTransformImage->GetBuffer();// display first 6 pixel values of first 6 lines of the transformed image// ========================================================================std::cout << "  Address    Y  Y  Y  Y  Y  Y " << std::endl;// set display for uppercase hex numbers filled with '0'std::cout << std::uppercase << std::setfill('0') << std::hex;for (int j = 0; j < 6; j++) {  // first 6 linesvoid* transformBufferAddress = &transformBuffer[pTransformImage->GetWidth() * 1 * j];std::cout << "  " << std::setw(8) << std::setfill('0')<< std::hex << transformBufferAddress << " ";for (int k = 0; k < 6; k++) {  // first 6 Pixel with Mono8 (1 Byte per Pixel)// value of pixelstd::cout << " " << std::setw(2)<< static_cast<int>(transformBuffer[pTransformImage->GetWidth()*j + k]);}std::cout << " ..." << std::endl;}// set display for lowercase dec numbers filled with ' 'std::cout << std::nouppercase << std::setfill(' ') << std::dec;std::cout << " " << std::endl;} else {  // if color format// transform to BGR8pTransformImage = imgProcessor->CreateTransformedImage(pImage, "BGR8");std::cout << " Image "<< std::setw(5) << pBufferFilled->GetFrameID() << " transformed to BGR8" << std::endl;std::cout << "  pTransformImage.Pixelformat:    "<< pTransformImage->GetPixelformat() << std::endl;std::cout << "  pTransformImage.Width:          "<< pTransformImage->GetWidth() << std::endl;std::cout << "  pTransformImage.Height:         "<< pTransformImage->GetHeight() << std::endl;std::cout << "  pTransformImage.Buffer:         "<< std::hex << pTransformImage->GetBuffer() << std::dec << std::endl;std::cout << "  Bytes per image:                "<< pTransformImage->GetWidth() * pTransformImage->GetHeight() * 3 << std::endl;std::cout << "  Bytes per pixel:                "<< 3.0 << std::endl;unsigned char* transformBuffer = (unsigned char *)pTransformImage->GetBuffer();// display first 6 pixel values of first 6 lines of the transformed image// ========================================================================std::cout << "  Address    B  G  R  B  G  R  B  G  R  B  G  R  B  G  R  B  G  R" << std::endl;// set display for uppercase hex numbers filled with '0'std::cout << std::uppercase << std::setfill('0') << std::hex;for (int j = 0; j < 6; j++) {  // 6 linesvoid* transformBufferAddress = &transformBuffer[pTransformImage->GetWidth() * 3 * j];std::cout << "  " << std::setw(8) << std::setfill('0')<< std::hex << transformBufferAddress << " ";for (int k = 0; k < 6; k++) {  // first 6 Pixel with BGR8 (3 Bytes per Pixel)// Value of Blue pixelstd::cout << " " << std::setw(2)<< static_cast<int>(transformBuffer[pTransformImage->GetWidth() * 3 * j + k * 3 + 0]);// Value of Green pixelstd::cout << " " << std::setw(2)<< static_cast<int>(transformBuffer[pTransformImage->GetWidth() * 3 * j + k * 3 + 1]);// Value of Red pixelstd::cout << " " << std::setw(2)<< static_cast<int>(transformBuffer[pTransformImage->GetWidth() * 3 * j + k * 3 + 2]);}std::cout << " ..." << std::endl;}// set display for lowercase dec numbers filled with ' 'std::cout << std::nouppercase << std::setfill(' ') << std::dec;std::cout << " " << std::endl;}pTransformImage->Release();// delete [] transformBuffer;// QUEUE BUFFER AFTER USEpBufferFilled->QueueBuffer();}}if (pImage != NULL) {pImage->Release();pImage = NULL;}
}
catch (BGAPI2::Exceptions::IException& ex) {returncode = (returncode == 0) ? 1 : returncode;std::cout << "ExceptionType:    " << ex.GetType() << std::endl;std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
}
std::cout << " " << std::endl;std::cout << "CAMERA STOP" << std::endl;
std::cout << "###########" << std::endl << std::endl;


图像转换的优势

工业相机的像素变换功能有几个优点,例如。

1. 提高图像质量。像素变换有助于纠正图像的失真和非线性,从而使图像更清晰、明确。

2. 提高准确性和精确性。通过纠正图像的失真和非线性,像素变换有助于提高测量和分析的准确性和精确度。

3. 不同相机之间的一致性。像素变换可用于校准不同的相机,以产生一致和准确的结果。

4.  提高效率。通过校正失真和非线性,像素转换消除了对额外的后处理步骤的需要,节省了时间和精力。

5. 更大的灵活性。像素转换可以定制,以适应特定的应用,使图像采集和分析更加灵活。


图像转换的行业应用

工业相机的像素转换功能可用于各种场景,如。

1. 图像校正。像素变换功能可用于纠正图像失真和其他由相机镜头引起的缺陷,如色差、晕影和透视变形。

2. 色彩校正。该功能可用于调整图像的色彩平衡、饱和度和其他与色彩有关的参数。

3. 图像增强。该功能可用于增强图像的对比度、锐度和其他视觉特征,以提高图像的质量。

4. 图像处理。该功能可用于转换图像格式或数据类型,调整图像大小,裁剪图像,或应用其他图像处理技术。

5. 机器视觉。该函数可用于预处理图像数据,然后再将其输入计算机视觉算法,用于物体检测、识别、跟踪或其他机器视觉任务。

总的来说,像素变换函数在图像处理和分析中起着至关重要的作用,它在制造业、机器人、汽车、医疗和其他行业的应用非常广泛。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_273972.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

银河麒麟v10系统硬盘挂载并配置yum软件源

一、查看磁盘 近期由于centos系统停止更新用户服务器要更换银河麒麟v10&#xff0c;拿到服务器后使用lsblk -f或fdisk -l命令查看磁盘名称 可以看到sdb200G就是要挂载的硬盘&#xff0c;还没有uuid需要初始化才可以挂载。 二、分区 分区命令&#xff1a; fdisk /dev/【你的…

QML- QML视觉元素类型

QML视觉元素类型一、概述一、图像类型三、共享视觉属性1. 不透明度和可见性2. 转换&#xff08;转置&#xff09;一、概述 对于最基本的视觉效果&#xff0c;Qt Quick提供了一个 Rectangle 类型来绘制矩形。这些矩形可以用颜色或垂直渐变来着色。 Rectangle 还可以在矩形上绘制…

QuestDb 基础使用

一、安装 Download QuestDB | QuestDB 可去官网直接下载对应版本&#xff0c;我这里是Windows版本 二、运行 找到Bin目录运行 管理员Cmd&#xff0c;输入 questDb.exe,即可运行&#xff0c;默认webConsole端口 9000&#xff0c;可在bin下 server.config去修改。 效果如下 …

Mac安装Nacos

参考链接&#xff1a; https://nacos.io/zh-cn/docs/quick-start.html 文章目录Nacos安装下载和解压启动和关闭Nacos什么是nacos?Nacos架构基本架构及概念逻辑架构及其组件介绍领域模型数据模型服务领域模型配置领域模型类视图Nacos安装 下载和解压 从链接中下载最新的版本 …

Vue基础25之路由第四节

Vue基础25路由编程式路由导航Home.vue(去掉两个router-line的replace)HomeMessage.vueBanner.vue总结缓存路由组件Home.vueHomeNews.vueHomeMessage.vue总结两个新的生命周期钩子HomeNews.vueHomeMessage.vueHome.vue总结全局路由守卫路由前置守卫src/router/index.js路由后置守…

Qt QShortCut快捷键原理、实现和应用

应用 QShortCut方式的快捷键有好几种使用方式&#xff1a; 1.通过绑定QAction或QMenu的方式。QAction和QMenu都提供了setShortcut()接口&#xff1b; 2.实例化一个对象&#xff1a;然后绑定信号槽activated()信号&#xff1a; auto shortcut new QShortcut(QKeySequence(tr(…

Postgresql源码(102)子事务控制语句分析

1 子事务控制语句分析 1.1 执行savepoint 执行函数&#xff1a; 【立即执行】→DefineSavepoint→PushTransaction&#xff08;从utility框架进入&#xff09;【延迟执行】→StartSubTransaction&#xff08;从顶层事务框架CommitTransactionCommand进入&#xff09; 准入条…

差分毫伏输出传感器信号隔离转换模块放大器0-10mV/0-20mV/0-±10mV/0-±20mV

概述&#xff1a;DIN11 IPO 压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号导轨安装变送模块。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。此系列模块内部嵌入了一个高效微功率的电源&#xff0c;向输入…

代码随想录-57-106. 从中序与后序遍历序列构造二叉树

目录前言题目1.递归&#xff08;区间&#xff0c;左闭右开&#xff09;变量2. 本题思路分析&#xff1a;3. 算法实现4. 算法复杂度5. 算法坑点前言 在本科毕设结束后&#xff0c;我开始刷卡哥的“代码随想录”&#xff0c;每天一节。自己的总结笔记均会放在“算法刷题-代码随想…

Java注解怎么用

什么是注解 Java的注解&#xff08;Annotation&#xff09;是一种元数据&#xff0c;它可以提供程序的额外信息&#xff0c;帮助程序员更好地管理程序。注解通常被用作代码的标记或者指定某些行为的方式。在Java中&#xff0c;注解以符号开头&#xff0c;放在代码的各个位置&a…

【数据结构】千字深入浅出讲解队列(附原码 | 超详解)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;C语言实现数据结构 &#x1f4ac;总结&#xff1a;希望你看完…

linux驱动学习加强版-2(文件驱动的书写)

文章目录一、驱动的外设二、驱动操作文件原理三、编写一个驱动程序3.1 编写驱动程序的步骤3.1.2 确定主设备号以及注册驱动3.1.3 实现对应的函数四、一些错误现象一、驱动的外设 我们的设备硬件都需要驱动才能工作&#xff0c;没有驱动的硬件可以称之为废铁&#xff0c;没有硬…

spacesniffer文件大小查看工具安装和使用

软件描述 spacesniffer是一块可以快速查看电脑中所有文件大小的工具&#xff0c;当电脑空间不够时&#xff0c;可以迅速找出不需要的大提及文件。 一、软件下载 1、从网盘下载 spacesniffer文件大小查看工具 2、从官网下载 http://www.uderzo.it/main_products/space_sni…

供水管网微观水力模型

国外在管网建模方面起步于20世纪60年代。20世纪80年代&#xff0c;随着计算机及相应技术的发展&#xff0c;遥测远传设备的应用进入了实用化阶段&#xff0c;国内已有很多供水企业实现了供水管网建模。给水管网系统建模&#xff0c;就是为仿真模拟管网系统动态实时运行情况建立…

【论文阅读总结】用于目标检测的特征金字塔网络(FPN)

Feature Pyramid Networks for Object Detection1.摘要2.引言2.1 低级特征对于检测小物体很重要2.2 算法目标3. 文献综述3.1 Hand-engineered features and early neural networks3.2 Deep ConvNet object detectors3.3 Methods using multiple layers4.Feature Pyramid Networ…

LangChain:Prompt Templates介绍及应用

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️&#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

WPF+WebView2+react/vue/angular

创建WPF项目 安装WbeView2 Nuget包 在窗体中添加命名空间 xmlns:wv2"clr-namespace:Microsoft.Web.WebView2.Wpf;assemblyMicrosoft.Web.WebView2.Wpf"使用控件 <wv2:WebView2 x:Name"webview"/>在MainWindow中初始化 public MainWindow(){Initia…

什么是语法糖?Java中有哪些语法糖?

本文从 Java 编译原理角度&#xff0c;深入字节码及 class 文件&#xff0c;抽丝剥茧&#xff0c;了解 Java 中的语法糖原理及用法&#xff0c;帮助大家在学会如何使用 Java 语法糖的同时&#xff0c;了解这些语法糖背后的原理1 语法糖语法糖&#xff08;Syntactic Sugar&#…

Linux syslog 日志服务

文章目录Syslog 概述syslog 协议标准syslog APIsyslog 日志文件日志文件介绍日志配置产生本地日志参考文章Syslog 概述 syslog 常被称为系统日志或系统记录&#xff0c;系统日志通过 syslog 进程记录系统的有关事件&#xff0c;也可以记录应用程序运作事件。通过适当配置&…

Python批量删除或移动指定图像

Python批量删除或移动指定图像前言一、批量删除指定名称的图像二、批量移动指定名称的图像前言 笔者的研究方向为计算机视觉&#xff0c;因此经常和大量图像打交道&#xff0c;有时需要批量删除一些图像&#xff0c;有时需要批量移动一些图像&#xff0c;因此编写了下述代码。下…