Baumer(堡盟)工业相机C#开发


前言

  • 堡盟neoAPI是一款功能强大、用户友好的全新应用程序编程接口(API),它支持C++、C#和Python等编程语言,只需几行代码即可将堡盟相机轻松快速地集成到具体应用中——例如,只需6行代码就可以实现图像采集和储存。这样,即使那些在图像处理方面经验有限的软件开发人员也能轻松胜任。
  • 凭借集成的自动化机制,堡盟neoAPI可大幅减少所需的代码行数,从而使相机的评估和集成变得更加高效,后续的软件更新也更简单。让您有更多时间处理其他项目。
  • 同时,堡盟neoAPI还可以将相机集成到现有编程环境中。各种集成开发环境(IDE)自带“自动完成”(auto-complete)功能,不仅可以针对代码段和相机GenICam功能提供建议,还可以完善它们并显示相关帮助。这样,软件开发人员就可以高效完成编程,而且无需在多个帮助文档中进行搜索。此外,堡盟还提供支持Python和C#语言的软件包,用户借助相应的软件包管理器就可以轻松实现软件包集成。

SDK下载链接:https://pan.baidu.com/s/1FcYqh41L1B-7cLyIW_ft5w
提取码:s087

一、设置和入门

准备工作

  • 欢迎使用堡盟 Microsoft C 的 neoAPI

  • 该软件包为您提供了使用堡盟neoAPI对堡盟相机进行编程所需的一切。如果您正在寻找C++或Python软件包,请从堡盟网站单独下载

  • 堡盟neoAPI for C#不需要任何特定版本的.Net Framework。它与 2.0 及更高版本的 .Net Framework 以及新的 .Net Core Framework 兼容。

  • 此处下载适用于您的操作系统和体系结构的软件包
    链接:https://pan.baidu.com/s/1FcYqh41L1B-7cLyIW_ft5w 提取码:s087

  • 拥有合适的主机系统(64 位 Windows 或 Linux)或 ARM 板 (AArch64 Linux),并准备好至少一个千兆以太网或USB3 端口 准备一台堡盟GigE或USB相机,包括必要的电缆和合适的电源

  • 拥有所选的合适 C#(.Net 框架或核心)开发环境(例如 Visual Studio 2013 或更高版本或 Visual Studio Code) 或者,您可以下载并安装堡盟Camera Explore,这是一款图形工具,可帮助您了解和使用相机 (可选)安装 CMake(至少版本3.9.3)以生成示例

  • 提供的一些示例需要 OpenCV(至少版本 3),如果要生成它们,它们将自动安装所需的 NuGet 包

安装相机驱动

  • 如果使用 USB 摄像头,则需要安装包装随附的 USB 驱动程序(请参阅/drivers/)
  • 对于GigE相机,与Windows自带网口驱动程序相比,堡盟驱动驱动程序可降低系统负载。我们建议安装和使用软件包随附的 filter-driver(请参阅/drivers/)

有关如何在 Windows 系统上充分利用 GigE 连接性能的更多信息,请参阅应用笔记 AN201622 和 AN201802。

驱动目录

安装NuGet包

C# 包包含可使用 Visual Studio 安装的 neoAPI NuGet 包。安装本地包需要 2 个步骤,创建本地包源并将包添加到项目中。

步骤 1 — 创建本地包源

打开 Visual C# 项目或在 Visual Studio 中创建一个新项目
转到“工具”/“NuGet 包管理器”并打开“数据包管理器设置”
在这里插入图片描述

步骤2 — 将包添加到项目中

转到“工具”/“NuGet 包管理器”并打开“数据包管理器控制台”
单击进入“数据包管理器控制台”窗口
运行命令:“Install-Package neoAPI”
在这里插入图片描述
在这里插入图片描述

二、连接相机

1.如何连接到相机

在开发使用相机时,第一步就是连接相机,使用NeoAPI::Cam::Connect()方法进行连接,代码如下(示例):

NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();                   // 连接到任意的1部相机
//or
camera.Connect("GigE");             // 连接到网口相机
//or
camera.Connect("VCXU-23M");         // 连接到相机名称“VCXU-23M”的相机
//or
camera.Connect("700004105902");     // 连接到指定序列号的相机
//or
camera.Connect("P10-2");            // 连接到指定USB端口名称的相机

2.判断相机是否连接以及相机参数获取

相机连接后,相机可能会因为断电或者其他因素出现断连情况,导致无法进行下一步操作,所以我们在做一些相机设置的同时,需要判定相机是否断连,使用NeoAPI::Cam::IsConnected;
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();                              // 连接相机
if (camera.IsConnected)             //判断相机是否连接
{                   
    co.WriteLine(camera.f.ExposureTime.Value); // 获取相机曝光时间
} 

3.在连接多台相机时如何遍历相机,连接指定相机

在一个系统中搭配多态相机使用时,要使用 NeoAPI::CamInfoList 和 NeoAPI::CamInfo来遍历筛选相机
代码如下(示例):

using co = System.Console;
NeoAPI.CamInfoList infolist = NeoAPI.CamInfoList.Get();  // 获取列表信息
infolist.Refresh();                                      // 刷新当前状态
String model = "";
foreach (NeoAPI.CamInfo info in infolist)
{
    model = info.ModelName;
    co.WriteLine(info.ModelName +" :: " + info.IsConnectable); // 打印所有连接相机的名称
}
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect(model);                               // 连接最后一台搜索到的相机
co.WriteLine("相机连接状态为:" + camera.IsConnected);

三.使用相机功能

1.确认相机是否具备指定功能

在不确定相机型号的情况下,个别相机可能某些功能不具备或者接口名称存在差异,在使用前需使用NeoAPI::Cam::HasFeature()方法确认
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    if (camera.HasFeature(ExposureTime)) {        // 确认是否具备该功能接口  
      co.WriteLine("The ExposureTime feature is implemented" );
    }
}

2.检查功能是否可用

某些功能可能会根据相机上设置的其他功能而变化。因此,例如,功能 ExposureTime 的可用性取决于功能 ExposureAuto 的值。仅当 ExposureAuto 关闭时,ExposureTime 才可用。您可以使用该方法NeoAPI::Feature::IsAvailable获取当前状态。
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    if (camera.f.ExposureTime.IsAvailable) {       // check if this feature is available
        co.WriteLine("The ExposureTime feature is available" );
    }
}

3.检查功能是否可读取、写入

要检查功能是否可读或可写,请使用NeoAPI::Feature::IsReadable 和 NeoAPI::Feature::IsWritable方法并实现。某些功能将永远无法写入,例如设备序列号或型号名称。其他功能可能会根据其他功能的值更改其访问状态。例如,如果“ExposureAuto”功能被打开,则“ExposureTime”功能将设置为只读,从而确保没有外界干扰自动曝光算法。
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    if (camera.f.DeviceSerialNumber.IsAvailable && camera.f.DeviceSerialNumber.IsReadable) {  //确认当前参数是否可读
        co.WriteLine(camera.f.DeviceSerialNumber.Value );
    }
    else {
        co.WriteLine("DeviceSerialNumber is not readable" );
    }
    if (camera.f.DeviceSerialNumber.IsAvailable && camera.f.DeviceSerialNumber.IsWritable) {  //确认当前参数是否可以写入
        camera.f.DeviceSerialNumber.Value = "111111";
    }
    else {
        co.WriteLine("DeviceSerialNumber is read-only" );
    }
}

4.读取和写入相机参数

一旦检查了该功能的可用性和读/写能力,读取和写入值就变得很简单了。
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    co.WriteLine(camera.f.ExposureTime.Value );  // 打印当前曝光时间
    camera.f.ExposureTime.Value = 20000;         // 设置曝光时间为20000
}

5.自动调整参数功能

对于相机参数设置的允许值,参数可以具有最小值、最大值或增量值。这意味着不可能设置全部数字范围,而只能设置一个子集。
一个很好的例子是设置感兴趣区域或区域 (ROI/AOI) 的功能。“Width”、“Height”、“OffsetX”和“OffsetY”功能通常只能取 2、4、8 或 16 的倍数,其最大值取决于相机的传感器。如果为某个特征设置了增量,neoAPI 将自动选择最接近的可能值,以防给定值无法写入特征。如果您希望在输入有误的情况下获得异常,则可以使用NeoAPI::Cam::AdjustFeatureValueMode 属性禁用此行为。
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    camera.f.Width.Value = 201;               // 相机宽度无法设置到201,会自动匹配一个最接近的值进行设置    co.WriteLine(camera.f.Width.Value );      // 打印设置好的宽度值
    camera.f.Width.Value = 100000;            // 宽度无法到达100000,会自动设置到最大宽度    
   co.WriteLine(camera.f.Width.Value );      // 打印设置的宽度值(相机的最大宽度)
    camera.SetAdjustFeatureValueMode = false;  // 关闭参数自动调整功能
    try {
        camera.f.Width.Value = 201;              // 现在设置的错误宽度会报错
        camera.f.Width.Value = 100000;        // 超出宽度最大值,同样报错
    }
    catch (NeoAPI.NeoException exc) {       //捕获异常
        co.WriteLine("NeoException: " + exc.ToString() );
    }
}

6.参数设置后生效模式

相机更改参数时,使用NeoAPI::Cam::SynchronFeatureMode属性来调整生效方式。若设置为true,则会等到参数写入完成再执行下一步动作;若设置为false,则参数不会立马生效,需要缓存图片释放后才能生效。
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    camera.f.ExposureTime.Value = 50;             //设置一个较小的曝光值
    camera.f.Gain.Value = 1;                         // 设置增益为1
    camera.SynchronFeatureMode = false;  // 将同步模式关闭,则设置的参数不会立马生效
    camera.f.Gain.Value = 4  ;             // 设置一个不同的增益
    NeoAPI.Image img = camera.GetImage();  // 这个时候获取的图片很可能不是增益为4的图片
    img.Save("test1");
    img = camera.GetImage();               // 这个时候获取的图片是增益为4的图片
    img.Save("test2");

7.触发模式设置

设置触发模式的开关,以及触发方式(IO触发,软触发等)
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    camera.f.TriggerMode.Value = NeoAPI.TriggerMode.On; // 打开触发模式
    var f = camera.f.TriggerSoftware;
    f.Execute();                                        // 执行软触发
}

8.通过遍历方式获取相机信息

通过枚举的方式,来获取相机的信息。下面是介绍了通过NeoAPI::Feature::GetEnumValueList()方法获取相机“PixelFormat”的例程
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    var f = camera.f.PixelFormat;
    // 遍历所有元素并打印可能的枚举的名称
 foreach (var a in f.GetEnumValueList())
    {
        System.Console.WriteLine(a.Key);
 if(a.Value.IsReadable && a.Value.ValueString == "RGB8")  // 检查相机是否支持该格式
        {
            f.ValueString = a.Value.ValueString;                 // 将像素格式设置为 RGB8
        }
        else if (a.Value.IsReadable && a.Value.ValueString == "Mono8") {
            f.ValueString = a.Value.ValueString;
    }
    co.WriteLine(f.Value + "; " + f.ValueString());              // 打印当前像素格式
}

9.选择器功能介绍

下一个示例演示如何使用选择器功能来访问一组相似的功能。一个相机可以有多个GPIO线,每条线都有一组属性。为了访问其中一条 GPIO 行的它们,我们将 LineSelector 设置为此行,并且可以读取或写入此行的属性。
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected()) {
    var f = camera.f.LineSelector;
    co.WriteLine(f.IsSelector);           // 判断该接口是否为可选择的选择器
     f.Value = NeoAPI.LineSelector.Line0;
    // 遍历 GetEnumValueList() 以获取选择器功能的所有可能值
  foreach (var a in f.GetEnumValueList()) {
        co.WriteLine(a.Name);
    }
    co.WriteLine("-----------" );
    // 遍历 GetSelectedFeatureList() 以获取当前所选 (Line0) 的所有选定要素及其值
  foreach (var a in f.GetSelectedFeatureList()) {
        co.WriteLine(a.DisplayName + ": " + a.ValueString );
    }
}

四.图像和缓冲区概念

1.如何将图像传输到应用程序?

GenICam相机有两种不同的操作模式。相机可以处于“自由运行”模式,相机将持续提供图像。其次,在触发模式下,您需要通过软件命令功能“TriggerSoftware”或通过硬件触发脉冲(通过功能“TriggerSource”设置源)使相机拍摄图像。
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
if (camera.IsConnected) {
    camera.f.ExposureTime.Value = 20000;                      //设置曝光时间为20000us
    camera.f.TriggerMode.Value = NeoAPI.TriggerMode.On;   // 设置触发模式为On        
    camera.f.TriggerSoftware.Execute();                     // 执行一次软触发
    NeoAPI.Image img = camera.GetImage();                 // 获取图片
    camera.f.TriggerMode.Value = NeoAPI.TriggerMode.Off;  // 关闭触发模式  
    camera.f.AcquisitionFrameRateEnable.Value = true;     // 开启固定帧率功能
    camera.f.AcquisitionFrameRate.Value = 24;             // 将固定帧率设置为24
    img = camera.GetImage();                              // 在自由采集状态下,获取图片
}

2.排队缓冲区模式

  • 排队缓冲模式不会循环任何图像,因此永远不会覆盖来自相机的任何图像。在NeoAPI::Cam::GetImage()此模式下,该方法将始终返回队列中最早的图像。这是机器视觉应用的典型要求,其中每个图像都会被触发,例如,通过光栅对应于传送带上的一个产品,该产品应由自动检测系统进行检测。NeoAPI::Cam::GetImage()
  • 需要注意的是在这个模式,如果缓冲区不够,会出现图片丢失的问题(缓存溢出)。所以要保证有足够的缓冲区(一般在相机采集速度较快的时候需要注意该问题)。否则,neoAPI 将停止记录新图像。此模式非常适合图像识别任务可以并行运行以同时处理多个图像的应用程序。
    要切换到排队缓冲区模式,需要NeoAPI::Cam::ImageBufferCount的数值等于NeoAPI::Cam::ImageBufferCycleCount的数值。
    代码如下(示例):
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
camera.ImageBufferCount = 50;          // 设置缓冲区队列为50
camera.ImageBufferCycleCount = 50;     // 设置循环队列的数值同样为50,便可以进入队列缓冲区模式

3.如何从图片中获取信息

图片的Frame ID,时间戳等信息可以直接从图片中获取
代码如下(示例):

using co = System.Console;
using NeoAPI;
Cam camera = new Cam();
camera.Connect();
Image i = camera.GetImage();  // 获取图片
if (!i.IsEmpty)                            //判断图片不为空
{
    co.WriteLine(i.ImageID);         // 获取图片的ID
    co.WriteLine(i.Timestamp);    // 获取图片的时间戳
    co.WriteLine(i.Size);                //获取图片大小
    co.WriteLine(i.PixelFormat);    //获取像素格式
}

五.事件介绍以及使用

1.neoApi事件介绍

事件可以支持您发现相机系统中的当前状态或更改。这是一种对自动发生或基于程序之外的事情发生的变化发出警报的方法。
在neoApi中有 3 组事件:

  • 设备事件(Device Events):这些事件由摄像机生成,用于提醒您在操作过程中的某些变化。GenICam标准称其为远程设备事件。哪些设备事件可用取决于连接的摄像机及其功能。可用的设备事件可以与 一起列出。NeoAPI::Cam::AvailableEvents
  • 即插即用事件(Plug-and-Play Events):这些事件由接口(USB或GigE)生成,用于提醒您相机的一般可用性,例如相机是可连接的、拔出的或处于neoAPI无法访问的状态。neoAPI 提供了 和 事件来帮助您观察系统的运行情况。DeviceAdded;DeviceInAccessible;DeviceRemoved
  • 图像事件(Image Events):这些事件会通知您来自相机的新图像的可用性,例如,当相机在外部触发时,这些事件可能很有用。

在 neoAPI 中获取事件信息有两种方法:

  • 可以使用或NeoAPI::Cam::GetEvent(),NeoAPI::Cam::GetImage()
    通过回调方法支持异步工作,可以注册为为到达事件调用。
  • Device 和 PnP 事件是使用其方法检索事件的标识符 (ID)、名称和时间戳的实例。图像事件不包含此信息,而是提供对实际图像及其属性的引用。NeoAPI::NeoEvent

2.图像事件(Image Events)的使用方法

图像事件一般是在相机获取图像的同时,来添加一些自定义的处理,包括图片信息获取,图片显示存储等。
代码如下(示例):

using System;
using System.IO;
using System.Threading;
using NeoAPI;
using co = System.Console;
// 编写图像回调函数,获取图片的信息
protected void test_image_handler(object obj, ImageEventArgs args) {
    co.WriteLine("received image: " + args.Image.ImageID +
                 " size: " + args.Image.Size + " height: " + args.Image.Height +
                 " width: " + args.Image.Width + " pixelformat: " + args.Image.PixelFormat);
}
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();                                       // 连接相机
camera.f.ExposureTime.Value = 40;
camera.f.TriggerMode.Value = NeoAPI.TriggerMode.On;     // 打开相机触发模式
camera.f.TriggerSource.Value = NeoAPI.TriggerSource.Software;    //开启软触发
camera.ImageCallback.Handler += test_image_handler;     // 注册回调函数
camera.EnableImageCallback();                           // 打开回调
for (int i = 0; i < 5; i++) {                           // 循环触发相机5次
    camera.f.TriggerSoftware.Execute();
    System.Threading.Thread.Sleep(100);
}
camera.DisableImageCallback();                          // 关闭回调
camera.Dispose();

六.日志跟踪

1.生成跟踪日志的方法

通过启用日志,可以检测到相机的报警信息,便于问题排查
代码如下(示例):

using co = System.Console;
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
string logfile = "test.log";
NeoAPI.NeoTrace trace = new NeoAPI.NeoTrace();
trace.SetSeverity(NeoAPI.NeoTraceSeverity.All);         // 设置追踪等级
trace.EnableLogfile(logfile);                           // 启用跟踪到日志文件
trace.Info("The Info", "Module Name", "Function name", trace);  // 设置要跟踪的内容
trace.Warning("The Warning", "Module Name", "Function name", camera);
trace.Error("The Error");
// 调用此方法(或者其他方法)后,将从API生成一个跟踪消息
co.WriteLine("prog: " + Cam.LibraryVersion);
trace.DisableLogfile();
camera.Dispose();

2.通过回调方式进行日志跟踪

图片的Frame ID,时间戳等信息可以直接从图片中获取
代码如下(示例):

using co = System.Console;
//编写回调函数
protected void test_trace_handler(object obj, TraceEventArgs args) {
    co.WriteLine("trace: " + args.Message);
}
NeoAPI.Cam camera = new NeoAPI.Cam();
camera.Connect();
NeoAPI.NeoTrace trace = new NeoAPI.NeoTrace();          // 创建跟踪对象
trace.Callback.Handler += test_trace_handler;           // 注册回调函数
trace.EnableLogCallback();                              // 开启回调
trace.SetSeverity(NeoAPI.NeoTraceSeverity.All);         // 设置跟踪等级
trace.Info("The Info", "my app", "main", camera);       // 设置要跟踪的内容
trace.Warning("The Warning");
trace.Error("The Error");
co.WriteLine("prog: " + Cam.LibraryVersion);  // 调用此方法(或者其他方法)后,将从API生成一个跟踪消息
trace.DisableLogCallback();                             // 关闭回调
camera.Dispose();

总结

下面给大家展示一段简单的采图例程,包含了相机的连接,曝光时间设置以及图片获取,代码如下:


using System;
using NeoAPI;
namespace ConsoleApp
{
    class Program
    {
        static int Main(string[] args)
        {
            int result = 0;
            try
            {
                Cam camera = new Cam();
                camera.Connect();
                camera.f.ExposureTime.Value = 10000;
                Image image = camera.GetImage();
                image.Save("getting_started.bmp");
            }
            catch (System.Exception exc)
            {
                System.Console.WriteLine("error: {0}", exc.Message);
                result = 1;
            }
            return result;
        }
    }
}
  • 19
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值