Baumer工业相机堡盟工业相机如何联合BGAPI SDK和OpenCVSharp实现Mono12和Mono16位深度的图像保存(C#)

news2024/11/15 12:10:05

Baumer工业相机堡盟工业相机如何联合BGAPI SDK和OpenCVSharp实现Mono12和Mono16位深度的图像保存(C#)

  • Baumer工业相机
  • Baumer工业相机保存位深度12/16位图像的技术背景
  • 代码案例分享
    • 1:引用合适的类文件
    • 2:BGAPI SDK在图像回调中联合OpenCV保存Mono12/16图像
    • 3:BGAPI SDK的图像联合OpenCV转换Mono12/16图像并保存
  • 工业相机使用位深度12/16位图像的优点
  • 工业相机使用位深度12/16位图像的行业应用


持之以恒挑战赛

Baumer工业相机

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

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

Baumer工业相机通过使用BGAPI SDK进行开发时,可以联合OpenCVSharp实现位深度为16的图像保存。

Baumer工业相机保存位深度12/16位图像的技术背景

工业相机通常用于需要高质量图像的分析和检查的专业环境中。这些相机被设计用来捕捉16比特的高比特深度的图像,与低比特深度的图像相比,可以捕捉到更大范围的色彩和细节。

保存位深16位图像的工业相机的技术背景涉及几个关键部分。首先,相机的图像传感器必须能够捕捉到高比特深度的图像。这是通过使用高质量的图像传感器来实现的,该传感器能够以每像素16比特的分辨率捕获数据。

其次,相机的电子设备必须能够处理和存储高比特深度的图像数据。这意味着相机需要有一个高速处理器和足够的内存来处理所产生的大量图像数据。

第三,相机的软件必须能够支持16位图像的保存。这意味着相机的固件和软件接口必须被设计成能够处理16位图像所产生的更大的文件尺寸,并且还能与工业标准文件格式如TIFF和RAW兼容。

总的来说,保存16位深度图像的工业相机的技术背景涉及高质量的图像传感器、强大的电子器件和专门的软件的组合,这些都是为了处理捕捉和存储高位深度图像的独特需求。

这里主要描述如何在C#的平台下联合BGAPI SDKOpenCVSharp实现Mono12或者Mono16图像格式的保存功能的核心代码

代码案例分享

本文介绍使用BGAPI SDK对Baumer的工业相机进行开发时,联合BGAPI SDKOpenCVSharp实现Mono12或者Mono16图像格式的保存功能

堡盟相机支持Mono8、Mono12、BGR8等多种像素格式(PixelFormat)——每种格式需对应相应的OpenCV格式。与堡盟相机像素格式对应的OpenCV矩阵类型如下表所示。
在这里插入图片描述

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

1:引用合适的类文件

C#环境下核心代码如下所示:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using BGAPI2;
using System.Runtime.InteropServices;
using System.IO;
using CSCameraDemo.Properties;
using System.Globalization;
using WindowsFormsApplication1;
using System.Threading.Tasks;
using System.Threading;
using System.Drawing.Imaging;

using OpenCvSharp;
using OpenCvSharp.Dnn;

2:BGAPI SDK在图像回调中联合OpenCV保存Mono12/16图像

下面为在在C#环境开启相机连接相机后通过转换图像格式实现Mono12或者Mono16图像格式保存的核心代码。

如下所示:

SystemList 
Open a System 
Get the InterfaceList and fill it Open an Interface 
Get the DeviceList and fill it 
Open a Device

void mDataStream_NewBufferEvent(object sender, BGAPI2.Events.NewBufferEventArgs mDSEvent)
{
    try
    {
        BGAPI2.Buffer mBufferFilled = null;              
        mBufferFilled = mDSEvent.BufferObj;
        if (mBufferFilled == null)
        {
            MessageBox.Show("Error: Buffer Timeout after 1000 ms!");
        }
        else if (mBufferFilled.IsIncomplete == true)
        {
            //MessageBox.Show("Error: Image is incomplete!");
            //queue buffer again
            mBufferFilled.QueueBuffer();
        }
        else
        {
            #region//获取当前FrameID
            FrameIDInt = (int)mBufferFilled.FrameID;
            OnNotifySetFrameID(FrameIDInt.ToString());
            #endregion

            //将相机内部图像内存数据转为bitmap数据
            System.Drawing.Bitmap bitmap  = new System.Drawing.Bitmap((int)mBufferFilled.Width, (int)mBufferFilled.Height, (int)mBufferFilled.Width,
                System.Drawing.Imaging.PixelFormat.Format8bppIndexed, (IntPtr)((ulong)mBufferFilled.MemPtr + mBufferFilled.ImageOffset));
                   

            #region//Mono图像数据转换。彩色图像数据转换于此不同
            System.Drawing.Imaging.ColorPalette palette = bitmap.Palette;
            int nColors = 256;
            for (int ix = 0; ix < nColors; ix++)
            {
                uint Alpha = 0xFF;
                uint Intensity = (uint)(ix * 0xFF / (nColors - 1));
                palette.Entries[ix] = System.Drawing.Color.FromArgb((int)Alpha, (int)Intensity, (int)Intensity, (int)Intensity);
            }
            bitmap.Palette = palette;
            #endregion

            long currenttime = (long)mBufferFilled.Timestamp;                   
            DateTime sdasd = GetTime(currenttime, true);

            #region//回调函数保存图像功能
            if (bSaveImg)
            {
                //使用bitmap自带函数保存
                string strtime = DateTime.Now.ToString("yyyyMMddhhmmssfff");
                string saveimagepath = pImgFileDir  +"\\"+ strtime + ".jpg";
                // bitmap.Save(saveimagepath, System.Drawing.Imaging.ImageFormat.Bmp);

                //使用opencv进行保存图像
                if (mBufferFilled.PixelFormat == "Mono8")
                {
                    OpenCvSharp.Mat matgray = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);//用bitmap转换为mat                           
                    matgray.SaveImage("opencv_image.png");
                    Cv2.ImWrite("opencvcv_image_Clone.png", matgray);
                    Cv2.ImWrite(saveimagepath, matgray);
                }                      


                if (mBufferFilled.PixelFormat.Contains("Mono12"))
                {

                    //OpenCvSharp.Mat imOriginal = new OpenCvSharp.Mat((int)mBufferFilled.Height, (int)mBufferFilled.Width, MatType.CV_8UC1, (IntPtr)mBufferFilled.MemPtr);

                    //OpenCvSharp.Mat imConverted = new OpenCvSharp.Mat(imOriginal.Rows, imOriginal.Cols, MatType.CV_16UC1); Cv2.ConvertScaleAbs(imOriginal, imConverted, 1, 0);

                    saveimagepath = pImgFileDir + "\\" + strtime + "-Mono16.png";

                    OpenCvSharp.Mat imOriginal = new OpenCvSharp.Mat((int)mBufferFilled.Height, (int)mBufferFilled.Width, MatType.CV_16UC1,
                        (IntPtr)mBufferFilled.MemPtr, (int)mBufferFilled.Width * 2);

                    imOriginal.ConvertTo(imOriginal, MatType.CV_16UC1, 16.0);

                    //Bitmap bmp = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(imOriginal);//用mat转换为bitmap

                    Cv2.ImWrite("cv_Mono12_as_Mono16_image.png", imOriginal);
                    Cv2.ImWrite(saveimagepath, imOriginal);
                }


                bSaveImg = false;//变量控制单次保存图像
            }
            #endregion

            #region//OPENCV对灰度图像进行直方图均衡化(不用)
            //OpenCvSharp.Mat Matgray = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);//用bitmap转换为mat                 
            //Mat Qualized = new Mat();
            //Cv2.EqualizeHist(Matgray, Qualized); // 对灰度图像进行直方图均衡化
            //Bitmap bmp = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(Qualized);//用mat转换为bitmap                 
            #endregion

            #region//bitmap的图像数据复制pBitmap
            Bitmap clonebitmap = (Bitmap)bitmap.Clone();
            BitmapData data = clonebitmap.LockBits(new Rectangle(0, 0, clonebitmap.Width, clonebitmap.Height), ImageLockMode.ReadOnly, clonebitmap.PixelFormat);
            clonebitmap.UnlockBits(data);
            pBitmap = clonebitmap;
            #endregion

            #region//将pBitmap图像数据显示在UI界面PictureBox控件上
            prcSource.X = 0;prcSource.Y = 0;
            prcSource.Width = (int)mBufferFilled.Width;prcSource.Height = (int)mBufferFilled.Height;
            System.Drawing.Graphics graph = System.Drawing.Graphics.FromHwnd(pictureBoxA.Handle);
            graph.DrawImage(pBitmap, prcPBox, prcSource, GraphicsUnit.Pixel);
            #endregion

            clonebitmap.Dispose(); //清除临时变量clonebitmap所占内存空间
            mBufferFilled.QueueBuffer();

        }
    }
    catch (BGAPI2.Exceptions.IException ex)
    {
        {
            string str2;
            str2 = string.Format("ExceptionType:{0}! ErrorDescription:{1} in function:{2}", ex.GetType(), ex.GetErrorDescription(), ex.GetFunctionName());
            MessageBox.Show(str2);
        }
    }
    return;
}

      

3:BGAPI SDK的图像联合OpenCV转换Mono12/16图像并保存

下面为在在C#环境开启相机连接相机后通过转换图像格式实现Mono12或者Mono16图像格式保存的核心代码。

如下所示:

if (mBufferFilled.PixelFormat.Contains("Mono12"))
{
   saveimagepath = pImgFileDir + "\\" + strtime + "-Mono16.png";
   OpenCvSharp.Mat imOriginal = new OpenCvSharp.Mat((int)mBufferFilled.Height, (int)mBufferFilled.Width, MatType.CV_16UC1,(IntPtr)mBufferFilled.MemPtr, (int)mBufferFilled.Width * 2);
	imOriginal.ConvertTo(imOriginal, MatType.CV_16UC1, 16.0);
    Cv2.ImWrite("cv_Mono12_as_Mono16_image.png", imOriginal);
    Cv2.ImWrite(saveimagepath, imOriginal);
}

Bitmap目前已经不支持12位的图像,Mono图像只能转为8位或者16位.

工业相机使用位深度12/16位图像的优点

更好的图像细节:12/16位图像可以捕捉到更多的细节和颜色深度,提供更高的图像质量。

更广泛的动态范围:12/16位图像允许在明暗变化很大的场景中捕捉到更多的细节和颜色,以及更好的光线控制。

更低的噪声:采用12/16位图像可以减少噪声,使得图像更加清晰。

更好的后期处理:12/16位图像可以在后期处理中更灵活地进行平滑、增加对比度和其他调整。

因此,工业相机使用12/16位图像可以提供更高质量的图像,更好的细节和颜色控制,并为后期处理提供更多的灵活性。

工业相机使用位深度12/16位图像的行业应用

  1. 医疗成像:工业相机可用于各种医疗成像应用,例如X射线成像,MRI和CT扫描。这些应用需要16位图像位深度来提供高质量的成像结果。

  2. 汽车制造:工业相机可以用于汽车制造中的各种应用,例如质量控制和检查。这些应用需要高分辨率和16位图像位深度,以检测并处理微小的缺陷或问题。

  3. 机器人视觉:工业相机的高速度和高精度对于机器人视觉应用非常重要。机器人需要能够识别和定位目标,同时能够处理16位图像位深度的高质量图像。

  4. 智能交通系统:工业相机也可以用于智能交通系统中。例如,交通监控摄像机需要高质量的图像以便能够识别和跟踪车辆,行人和其他交通标志。

总之,工业相机使用16位图像位深度的行业应用范围非常广泛,它们可以用于各种不同的应用,以提供高质量的成像结果和精确的图像处理功能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【GCU体验】基于PaddlePaddle + GCU跑通模型并测试GCU性能

一、环境 地址&#xff1a;启智社区:https://openi.pcl.ac.cn/ 二、计算卡介绍 云燧T20是基于邃思2.0芯片打造的面向数据中心的第二代人工智能训练加速卡&#xff0c;具有模型覆盖面广、性能强、软件生态开放等特点&#xff0c;可支持多种人工智能训练场景。同时具备灵活的可…

STM32理论 —— 定时器、时钟

文章目录 1. 定时器1.1 分类与简介1.1.1 分类与主要功能特点1.1.2 三种常用的定时器简介1.1.3 三种计数模式1.1.4 定时器计数原理 1.2 时钟来源1.3 通用定时器简介1.4 计数溢出时间公式1.4 定时器中断的原理1.5 输入捕获1.6 核心代码1.6.1 通用定时器初始化1.6.2 高级定时器初始…

【Python_Scrapy学习笔记(十三)】基于Scrapy框架的图片管道实现图片抓取

基于Scrapy框架的图片管道实现图片抓取 前言 本文中介绍 如何基于 Scrapy 框架的图片管道实现图片抓取&#xff0c;并以抓取 360 图片为例进行展示。 正文 1、Scrapy框架抓取图片原理 利用 Scrapy 框架提供的图片管道类 ImagesPipeline 抓取页面图片&#xff0c;在使用时需…

领域驱动设计理论实践

战略设计 战略设计是将“混沌”解构成“清晰”的过程&#xff0c;在该过程从开始到结束的历程之中&#xff0c;我们会划分出领域、界定通用语言范围、确定出系统限界上下文以及上下文之间的映射方式。 领域划分 战略设计在领域驱动设计中起着关键作用&#xff0c;因为其决定了…

使用Bazel构建前端Sass

注&#xff1a;本文假设对Bazel有一定的了解。本文基于Bazel 4.2.2 版本 在web前端领域&#xff0c;前端样式&#xff0c;web浏览器只认CSS样式语言。而CSS样式语言又过于低级。于是有人发明了更高级的语言&#xff1a;Sass[1]&#xff0c;用于生成CSS代码。 这样的方案&#x…

【C++】队列模拟问题

文章目录队列模拟问题12.7.1 ATM问题12.7.2 队列类12.7.3 Queue类的接口12.7.4 **Queue类的实现**12.7.5 是否需要其他函数&#xff1f;12.7.6 Customer类queue.hqueue.cpp12.7.7 ATM模拟main.cpp队列模拟问题 12.7.1 ATM问题 Heather银行打算在Food Heap超市开设一个自动柜员…

【C++STL精讲】vector的基本使用与常用接口

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;vector是什么&#xff1f;&#x1f337;vector的基本使用&#x1f337;vector常用函数接口&#x1f490;专栏导读 &#x1f338;作者简介&#xff1a;花想云&#xff0c;在读本科生一枚&#xff0c;致力于 C/C…

HAL库版FreeRTOS(上)

目录 FreeRTOS 简介初识FreeRTOS什么是FreeRTOS?为什么选择FreeRTOS&#xff1f;FreeRTOS 的特点商业许可 磨刀不误砍柴工查找资料FreeRTOS 官方文档Cortex-M 架构资料 FreeRTOS 源码初探FreeRTOS 源码下载FreeRTOS 文件预览 FreeRTOS 移植FreeRTOS 移植移植前准备添加FreeRTO…

浏览器断点调试说明

断点调试 断点调试面板 功能按钮介绍 描述&#xff1a;继续执行脚本 或者叫&#xff08;逐过程执行&#xff09; 快捷键 &#xff08;F8&#xff09;或者是&#xff08;Ctrl\&#xff09; 作用&#xff1a;打断点了的地方&#xff08;比如有是三个断点地方&#xff09;就会 第一…

大数据能力提升项目|学生成果展系列之四

导读 为了发挥清华大学多学科优势&#xff0c;搭建跨学科交叉融合平台&#xff0c;创新跨学科交叉培养模式&#xff0c;培养具有大数据思维和应用创新的“π”型人才&#xff0c;由清华大学研究生院、清华大学大数据研究中心及相关院系共同设计组织的“清华大学大数据能力提升项…

13.vue-cli

单页面应用程序&#xff1a;所有的功能只在index.html中完成 vue-cli是vue版的webpack 目录 1 安装vue-cli 2 创建项目 3 使用预设 4 删除预设 5 开启项目 6 项目文件内容 6.1 node_moduls 中是项目依赖的库 6.2 public 6.2.1 favicon.ico 是浏览器页签内部…

尚融宝——整合OpenFeign与Sentinel实现兜底方法——验证手机号码是否注册功能

一、整合过程 在项目添加依赖&#xff1a;添加位置 <!--服务调用--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency> 在需要的服务中添加启动注…

spring中常见的注解

DI(依赖注入中常见的注解) Autowired&#xff1a;按类型自动装配Resource&#xff1a;按名称或类型自动装配&#xff0c;Qualifier&#xff1a;按名称自动装配&#xff0c;Value &#xff1a;注入int、float、String等基本数据类型&#xff0c;只能标注在成员变量、setter方法上…

【Gradle-1】入门Gradle,前置必读

1、为什么要学习Gradle Gradle作为Android开发默认的构建工具&#xff0c;你的每一次编译都会用到它。招聘要求从以前的熟悉加分&#xff0c;到现在的必备技能&#xff0c;可见Gradle的重要性。 做开发这么久了&#xff0c;你是否对Gradle又爱又恨&#xff1f;是否对Gradle的…

第三章(1):自然语言处理概述:应用、历史和未来

第三章&#xff08;1&#xff09;&#xff1a;自然语言处理概述&#xff1a;应用、历史和未来 目录第三章&#xff08;1&#xff09;&#xff1a;自然语言处理概述&#xff1a;应用、历史和未来1. 自然语言处理概述&#xff1a;应用、历史和未来1.1 主要应用1.2 历史1.3 NLP的新…

【科普】PCB为什么常用50Ω阻抗?6大原因

在PCB设计中&#xff0c;阻抗通常是指传输线的特性阻抗&#xff0c;这是电磁波在导线中传输时的特性阻抗&#xff0c;与导线的几何形状、介质材料和导线周围环境等因素有关。 对于一般的高速数字信号传输和RF电路&#xff0c;50Ω是一个常用的阻抗值。 为什么是50Ω&#xff1f…

《程序员面试金典(第6版)》面试题 10.09. 排序矩阵查找(观察法,二分法,分治算法入门题目,C++)

题目描述 给定MN矩阵&#xff0c;每一行、每一列都按升序排列&#xff0c;请编写代码找出某元素。 示例: 现有矩阵 matrix 如下&#xff1a;[[1, 4, 7, 11, 15],[2, 5, 8, 12, 19],[3, 6, 9, 16, 22],[10, 13, 14, 17, 24],[18, 21, 23, 26, 30] ]给定 target 5&…

wma格式怎么转换mp3,4种方法超快学

其实我们在任何电子设备上所获取的音频文件都具有自己的格式&#xff0c;每种格式又对应着自己的属性特点。比如wma就是一种音质优于MP3的音频格式&#xff0c;虽然很多小伙伴比较青睐于wma所具有的音质效果&#xff0c;但也不得不去考虑因wma自身兼容性而引起很多播放器不能支…

【高危】Apache Solr 代码执行漏洞(MPS-wic0-9hjb)

漏洞描述 Apache Solr 是一款开源的搜索引擎。 在Apache Solr 受影响版本中&#xff0c;由于Solr默认配置下存在服务端请求伪造漏洞&#xff0c;且SolrResourceLoader中实现了java SPI机制。当Solr以SolrCloud模式启动时&#xff0c;攻击者可以通过构造恶意的solrconfig.xml文…

几个最基本软件的环境变量配置

在Windows中配置环境变量位置&#xff1a; 控制面板->系统和安全->系统。可以点击&#xff1a;“此电脑”->“属性”直接进入。 点击“高级系统设置”->【环境变量】。在这里可以看见用户变量和系统变量&#xff0c;如果你这台机器不是你一个人使用设置为用户变量…