Baumer工业相机堡盟相机如何通过BGAPI SDK联合OpenCVSharp进行图像简单拼接并显示固定数量保存和持续保存(C#)

简介: Baumer工业相机堡盟相机如何通过BGAPI SDK联合OpenCVSharp进行图像简单拼接并显示固定数量保存和持续保存(C#)

Baumer工业相机

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


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

Baumer工业相机通过使用BGAPI SDK进行开发时,可以联合OpenCVSharp实现图像的拼接和固定数量保存以及持续保存的功能。


Baumer工业相机SDK联合OpenCVSharp的技术背景

Baumer工业相机SDK是一种软件开发工具包,用于与工业相机通信和图像采集。这些SDK通常包含驱动程序和API,可以让开发人员使用多个编程语言(例如C++、C#、Python)编写应用程序。它们也提供了许多图像参数和相机参数的控制选项,以便满足各种应用需求。


OpenCVSharp是OpenCV在C#中的封装,是一种流行且广泛使用的计算机视觉库,提供了大量的图像处理和计算机视觉算法,例如图像过滤、特征提取、目标检测等。OpenCVSharp可以与工业相机SDK集成,以便对从相机采集的图像进行处理和分析。


联合使用工业相机SDK和OpenCVSharp,开发人员可以实现更高级别的图像处理和视觉分析应用。例如,他们可以使用工业相机SDK实现图像采集和实时显示,然后使用OpenCVSharp进行图像处理和物体检测。他们还可以使用OpenCVSharp的计算机视觉算法来实现特定应用,例如质量控制、机器人视觉导航和自动识别等。

这里主要描述如何在C#的平台下实现通过BGAPI SDK和OpenCV进行图像转换的核心代码,本文的回调函数将实现拼接四张图像并进行固定数量保存和持续保存的功能。


代码分析

本文介绍使用BGAPI SDK对Baumer的JPEG工业相机进行开发时,使用通过BGAPI SDK和OpenCVSharp进行图像拼接显示图像以及进行固定数量保存和持续保存图像的功能


第一步:先引用对应的OpenCV的类文件

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;

第二步:在回调函数里进行Buffer图像转换拼接以及保存相关功能

后续进行图像转换为OpenCV库的Mat图像并进行拼接和显示以及进行固定数量保存和持续保存图像核心代码,如下所示:

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//对四张图像进行基础拼接
            OpenCvSharp.Mat Matgray1 = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);//用bitmap转换为mat  
            OpenCvSharp.Mat Matgray2 = Matgray1;
            OpenCvSharp.Mat Matgray3 = Matgray1;
            OpenCvSharp.Mat Matgray4 = Matgray1;
            Mat panorama1 = new Mat();
            Mat panorama2 = new Mat();
            Mat panoramaResult = new Mat();
            Cv2.VConcat(Matgray1, Matgray2, panorama1);
            Cv2.VConcat(Matgray3, Matgray4, panorama2);
            Cv2.HConcat(panorama1, panorama2, panoramaResult);
            Bitmap bmp = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(panoramaResult);//用mat转换为bitmap              
            panorama1.Dispose(); panorama2.Dispose(); panoramaResult.Dispose();
            #endregion
            #region//回调函数保存图像功能
            if (bSaveImg)
            {
    //正常单次保存图像
                if (!AutoSaveCheck.Checked & !ContinueSave.Checked)
                {
                    //使用bitmap自带函数保存
                    string strtime = DateTime.Now.ToString("yyyyMMddhhmmssfff");
                    string saveimagepath = pImgFileDir + "\\" + strtime + ".jpg";
                    bmp.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);
                    //}
                    bSaveImg = false;//变量控制单次保存图像
                }
    //固定数量保存图像
                if (AutoSaveCheck.Checked)
                {
                    //使用bitmap自带函数保存
                    string strtime = DateTime.Now.ToString("yyyyMMddhhmmssfff");
                    string saveimagepath = pImgFileDir + "\\" + strtime + ".jpg";
                    //bmp.Save(saveimagepath, System.Drawing.Imaging.ImageFormat.Jpeg);
                    Thread SaveImagesThread1 = new Thread((ThreadStart)delegate() { AutoSaveImageRun(bmp, saveimagepath); });
                    SaveImagesThread1.Start();
                    SaveImagesThread1.Join();
                    AutoSaveCount = AutoSaveCount + 1;
                    if (AutoSaveCount == AutoSaveNum0)
                    {
                        AutoSaveCount = 0;
                        bSaveImg = false;
                        AutoSaveCheck.Checked = false;
                    }
                }
    //持续一直保存图像
                if (ContinueSave.Checked)
                {
                    //使用bitmap自带函数保存
                    string strtime = DateTime.Now.ToString("yyyyMMddhhmmssfff");
                    string saveimagepath = pImgFileDir + "\\" + strtime + ".jpg";
                    //bmp.Save(saveimagepath, System.Drawing.Imaging.ImageFormat.Jpeg);
                    Thread SaveImagesThread1 = new Thread((ThreadStart)delegate() { AutoSaveImageRun(bmp, saveimagepath); });
                    SaveImagesThread1.Start();
                    SaveImagesThread1.Join();
                }
            }
            #endregion
            #region//bitmap的图像数据复制pBitmap
            Bitmap clonebitmap = (Bitmap)bmp.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;
}

第三步:OpenCVSharp进行图像固定数量保存和持续保存的具体应用

C#调用代码如下所示:

#region//回调函数保存图像功能
if (bSaveImg)
{
    if (!AutoSaveCheck.Checked & !ContinueSave.Checked)
    {
        //使用bitmap自带函数保存
        string strtime = DateTime.Now.ToString("yyyyMMddhhmmssfff");
        string saveimagepath = pImgFileDir + "\\" + strtime + ".jpg";
        bmp.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);
        //}
        bSaveImg = false;//变量控制单次保存图像
    }
    if (AutoSaveCheck.Checked)
    {
        //使用bitmap自带函数保存
        string strtime = DateTime.Now.ToString("yyyyMMddhhmmssfff");
        string saveimagepath = pImgFileDir + "\\" + strtime + ".jpg";
        //bmp.Save(saveimagepath, System.Drawing.Imaging.ImageFormat.Jpeg);
        Thread SaveImagesThread1 = new Thread((ThreadStart)delegate() { AutoSaveImageRun(bmp, saveimagepath); });
        SaveImagesThread1.Start();
        SaveImagesThread1.Join();
        AutoSaveCount = AutoSaveCount + 1;
        if (AutoSaveCount == AutoSaveNum0)
        {
            AutoSaveCount = 0;
            bSaveImg = false;
            AutoSaveCheck.Checked = false;
        }
    }
    if (ContinueSave.Checked)
    {
        //使用bitmap自带函数保存
        string strtime = DateTime.Now.ToString("yyyyMMddhhmmssfff");
        string saveimagepath = pImgFileDir + "\\" + strtime + ".jpg";
        //bmp.Save(saveimagepath, System.Drawing.Imaging.ImageFormat.Jpeg);
        Thread SaveImagesThread1 = new Thread((ThreadStart)delegate() { AutoSaveImageRun(bmp, saveimagepath); });
        SaveImagesThread1.Start();
        SaveImagesThread1.Join();
    }
}
#endregion

工业相机图像通过OpenCVSharp进行图像保存的优点

高效性:OpenCVSharp在处理图像时非常快速,能够处理大量的图像数据。


稳定性:OpenCVSharp提供了一个非常容易使用的API,可以让用户轻松地完成图像处理任务,并且提供了稳定的代码库和基于OpenCV的算法实现。


兼容性:OpenCVSharp是基于.NET的,可以与各种操作系统和编程语言进行兼容。它可以在Windows、Linux和Mac OS X上运行,并且可以使用C#、C++和Python等编程语言进行调用。


可扩展性:OpenCVSharp可以自定义算法,扩展现有的功能,并支持各种图像输入/输出格式的文件,如BMP、JPG、PNG、TIF等。


因此,采用OpenCVSharp进行保存工业相机图像具有高效性、稳定性、兼容性和可扩展性等优点,能够大大提高工业相机图像的处理效率和准确性。


工业相机图像通过OpenCVSharp进行图像保存的行业应用

自动化生产控制:工业相机可以用于自动化生产控制,将其拍摄的图像通过SDK转为OPENCV的MAT图像后,可以使用图像处理技术对产品进行检测、分类、计数等操作,实现自动化生产控制。


智能交通:工业相机可以用于智能交通,将其拍摄的图像通过SDK转为OPENCV的MAT图像后,可以使用图像处理技术对车辆进行识别、计数、跟踪等操作,实现智能交通管理。


医疗影像:工业相机可以用于医疗影像,将其拍摄的图像通过SDK转为OPENCV的MAT图像后,可以使用图像处理技术对医疗影像进行分析、诊断等操作,提高医疗诊断的准确性和效率。


物流仓储:工业相机可以用于物流仓储,将其拍摄的图像通过SDK转为OPENCV的MAT图像后,可以使用图像处理技术对物流仓储过程进行监控、管理、智能化等操作,提高物流仓储效率和安全性。


视频监控:工业相机可以用于视频监控,将其拍摄的图像通过SDK转为OPENCV的MAT图像后,可以使用图像处理技术对视频图像进行分析、识别、跟踪等操作,实现智能化视频监控。

目录
相关文章
|
5月前
|
数据采集 JavaScript C#
C#图像爬虫实战:从Walmart网站下载图片
C#图像爬虫实战:从Walmart网站下载图片
|
6月前
|
数据采集 开发工具 Python
海康威视工业相机SDK+Python+PyQt开发数据采集系统(支持软件触发、编码器触发)
该系统基于海康威视工业相机SDK,使用Python与PyQt开发,支持Gige与USB相机设备的搜索及双相机同时显示。系统提供软件触发与编码器触发模式,并可在数据采集过程中实时保存图像。此外,用户可以调节曝光时间和增益,并进行信息输入,这些信息将被保存至配置文件以便下次自动加载。参数调节与实时预览等功能进一步增强了系统的实用性。
418 1
|
8月前
|
并行计算 算法 C#
C# Mandelbrot和Julia分形图像生成程序更新到2010-9-14版 支持多线程计算 多核处理器
此文档是一个关于分形图像生成器的介绍,作者分享了个人开发的M-J算法集成及色彩创新,包括源代码和历史版本。作者欢迎有兴趣的读者留言交流,并提供了邮箱(delacroix_xu@sina.com)以分享资源。文中还展示了程序的发展历程,如增加了真彩色效果、圈选放大、历史记录等功能,并分享了几幅精美的分形图像。此外,还提到了程序的新特性,如导入ini文件批量输出图像和更新一批图片的功能。文档末尾附有多张程序生成的高分辨率分形图像示例。
|
8月前
|
存储 编解码 算法
C#.NET逃逸时间算法生成分形图像的毕业设计完成!晒晒功能
该文介绍了一个使用C#.NET Visual Studio 2008开发的程序,包含错误修复的Julia、Mandelbrot和优化过的Newton三种算法,生成色彩丰富的分形图像。作者改进了原始算法的效率,将内层循环的画点操作移至外部,提升性能。程序提供五种图形模式,支持放大缩小及颜色更新,并允许用户自定义画布大小以调整精度。还具备保存为高质JPG的功能。附有四张示例图片展示生成的分形效果。
|
9月前
|
存储 传感器 监控
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
336 0
|
9月前
|
监控 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
97 0
|
9月前
|
监控 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C#)
119 0
|
2月前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
116 12
|
3月前
|
设计模式 C# 图形学
Unity 游戏引擎 C# 编程:一分钟浅谈
本文介绍了在 Unity 游戏开发中使用 C# 的基础知识和常见问题。从 `MonoBehavior` 类的基础用法,到变量和属性的管理,再到空引用异常、资源管理和性能优化等常见问题的解决方法。文章还探讨了单例模式、事件系统和数据持久化等高级话题,旨在帮助开发者避免常见错误,提升游戏开发效率。
117 4
|
3月前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
61 3

热门文章

最新文章