C++编程/数字图像处理

Pylon5 编程指南(C++)

2019-08-29  本文已影响0人  极简纯粹_

开始使用

  pylon编程向导是关于如何使用Basler pylon c++ API进行编程的快速指南。它可以与pylon示例代码一起使用。此外,API参考提供了有关Basler pylon c++接口的文档。接口文档也可以在pylon的头文件中找到。当使用Microsoft Visual Studio时,右键所需的方法或类,并从上下文菜单中选择“Go To Declaration”以转到相关文档。

使用pylon编译应用程序的通用设置

  本节展示了用于使用pylon构建32位应用程序的最常见的Microsoft Visual Studio构建设置。有关更多信息,请参阅高级主题部分,例如,当需要不同的配置时

$(PYLON_DEV_DIR)\include;
$(PYLON_DEV_DIR)\lib\Win32;
yes
yes

使用Gige相机调试pylon应用程序

  在使用GigE相机调试pylon应用程序时,可能会遇到心跳超时。应用程序必须在规定的时间间隔内向相机发送专门的网络数据包。如果相机没有接收到这些心跳,它会认为连接已经断开,不会接受应用程序的任何指令。这需要在调试时将相机的心跳超时设置为较高的值。

对pylon的运行库进行初始化和反初始化

  pylon运行库系统必须在使用前被初始化。基于pylon的应用程序必须在使用pylon运行库系统的任何其他函数之前调用PylonInitialize()方法。在应用程序退出之前,它必须调用PylonTerminate()方法来释放被pylon运行库系统分配的资源。
  Pylon::PylonAutoInitTerm类可以有助于实现上述功能。PylonAutoInitTerm的构造函数调用PylonInitialize(),析构函数调用PylonTerminate()。这确保在PylonAutoInitTerm类型的对象的生存期内被初始化pylon运行库系统。

#include <pylon/PylonIncludes.h>

using namespace Pylon;

int main(int argc, char* argv[])
{
Pylon::PylonAutoInitTerm;// PylonInitialize() will be called now
// Use pylon
// ..
} // autoInitTerm's destructor calls PylonTerminate() now

错误处理

  在出现错误的情况下,pylon类的可能会抛出c++异常。pylon c++ API抛出GenericException类型的异常或GenericException的子类异常。您应该使用捕获GenericException的异常处理程序来保护pylon调用,例如:

try
{
  camera.Width.SetValue( 640 );
}
catch (const GenericException & e)
{
  cerr << "Failed to set the AOI width. Reason: "
  << e.GetDescription() << endl;
}

创建一个pylon设备

  在pylon中,物理相机设备由pylon Devices表示。下面的例子展示了如何创建一个pylon设备:

IPylonDevice* pDevice = CTlFactory::GetInstance().CreateFirstDevice();

  第一个发现的相机设备被创建,例如,一个视觉系统只使用一个相机。
*注:第一次创建相机时,相机的GenICam参数描述文件被处理。处理的结果存储在磁盘上的缓存中。这就是为什么第一次创建要比随后的创建花费更长的时间。如果创建是由使用调试器启动的程序完成的,那么设备创建将花费相当长的时间。这是因为当调试器启动程序时,Windows提供了一个特殊的debug堆,并且当使用debug堆时,处理参数描述文件会导致大量的堆分配,而这些分配将花费更长的时间。你可以在不附加调试器的情况下启动应用程序,以确定创建设备的实际处理时间。但是不管怎样,这应该只在多相机设置时需要。

即时相机类

  一个Instant Camera类在内部使用一个pylon device。pylon device需要被创建并将其附加到即时相机对象上以便操作。

//首先使用找到的相机创建一个即时相机类
CInstantCamera camera( CTlFactory::GetInstance().CreateFirstDevice());
// 打印相机型号名称
cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;
// 开始抓取c_countOfImagesToGrab 图像.
//使用自有连续采集方式进行相机设备的默认参数初始化.
camera.StartGrabbing( c_countOfImagesToGrab);
// 这个智能指针用于抓取结果数据.
CGrabResultPtr ptrGrabResult;
//当c_countOfImagesToGrab图像被重新取回时RetrieveResult()方法会自动调用Camera.StopGrabbing() 
while ( camera.IsGrabbing())
{
    // Wait for an image and then retrieve it. A timeout of 5000 ms is used.
    camera.RetrieveResult( 5000,     ptrGrabResult,TimeoutHandling_ThrowException);
    // 图像是否抓取成功?
    if (ptrGrabResult->GrabSucceeded()){
      // Access the image data.
      cout << "SizeX: " << ptrGrabResult->GetWidth() << endl;
      cout << "SizeY: " << ptrGrabResult->GetHeight() << endl;
      const uint8_t *pImageBuffer = (uint8_t *) ptrGrabResult->GetBuffer();
      cout << "Gray value of first pixel: " << (uint32_t) pImageBuffer[0] << endl <<endl;
      }
      else
      {
          cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
      }
 }

即时相机类的主要特性

  即时相机类建立了对相机设备的方便访问,同时高度可定制。下面的列表显示了即时类的主要特性:

  1. 作为相机功能的单一访问点
  2. 它可以在不设置任何参数的情况下“开箱即用”。相机使用设备的默认配置。可以重写默认配置。
  3. 处理pylon设备的生命周期
  4. 自动打开和关闭pylon设备
  5. 提供缓冲区的创建、重用和销毁处理功能
  6. 如果需要可以提供循环抓取线程
  7. 可以检测相机设备的移除
  8. 支持先进的相机功能,如块模式和事件报告
  9. 可派生扩展
  10. 通过注册额外的事件处理程序对象进行扩展
即时相机类型
图片.png

  通用的CInstantCamera相机类允许操作所有类型的相机设备。当为多种设备类型(如GigE和IIDC 1394设备)编程时,如果在编译时不知道使用的设备类型,则应该使用该类。
  设备特定的即时相机类是CInstantCamera的专门化,通过一个参数类扩展它。parameter类为每个相机参数提供一个成员。当只为一种设备类型(例如GigE设备)编程时,应该使用这些特定于设备的即时相机类之一。

即时相机类事件处理

  Instant Camera类允许注册事件处理程序对象,用于定制相机对象的行为、处理抓取结果和处理相机事件。下面的列表显示了可用的事件处理程序类型。

配置

 emsp;配置事件处理程序类也称为“配置”,因为它们封装了特定的相机配置。pylon c++ API附带了以下配置类:

// 注册用于启用软件触发的标准配置事件处理程序
// 软件触发器配置处理程序替换默认配置
// 因为通过将注册模式设置为RegistrationMode_ReplaceAll,可以删除所有当前注册的配置处理程序。
camera.RegisterConfiguration( new CSoftwareTriggerConfiguration, RegistrationMode_ReplaceAll, Cleanup_Delete);
使用即时相机阵列处理多个相机

即时相机阵列类帮助管理系统中的多个相机。一个即时相机数组表示一个即时相机对象数组。它提供了几乎相同的界面,作为一个即时相机抓拍。CInstantCameraArray的主要目的是简化在一个线程中等待多个相机的图像和相机事件。这是通过为数组中的所有相机提供一个RetrieveResult方法来实现的。以下类可供选择:

参数访问

  对于相机配置和访问其他参数,pylon API使用GenICam标准定义的技术。GenICam规范(http://www.GenICam.org)为相机参数描述文件定义了一种格式。这些文件描述了GenICam兼容相机的配置接口。描述文件用XML(可扩展标记语言)编写,描述相机寄存器、它们之间的相互依赖关系,以及通过低级寄存器读写操作访问高级特性(如增益、曝光时间或图像格式)所需的所有其他信息。
  相机描述文件的元素表示为称为节点的软件对象。例如,一个节点可以表示单个相机寄存器、相机参数(如增益)、一组可用参数值等。每个节点实现GenApi::INode接口。
  节点有不同的类型。例如,有表示整数值的节点和表示字符串的其他节点。对于每种类型的参数,GenApi中都有一个接口。这些接口在参数类型一节中进行了描述。参数访问模式部分介绍了参数访问模式的概念。访问模式属性用于确定参数是否可用、可读或可写。

本地参数访问

  pylon提供编程接口类,这些类使用GenICam的GenApi模块提供的代码生成器从参数描述文件创建。这些编程接口类由设备特定的即时相机类导出。因此,为每个可用参数提供一个成员。这是访问参数的最简单方法。

// Maximize the image area of interest (Image AOI).
if (IsWritable(camera.OffsetX)){
  camera.OffsetX.SetValue(camera.OffsetX.GetMin());
}
if (IsWritable(camera.OffsetY)){
  camera.OffsetY.SetValue(camera.OffsetY.GetMin());
}
camera.Width.SetValue(camera.Width.GetMax());
camera.Height.SetValue(camera.Height.GetMax());
// Set the pixel data format.
camera.PixelFormat.SetValue(PixelFormat_Mono8);
泛型参数访问

  完整的节点集存储在名为节点映射的数据结构中。在运行时,节点映射从XML描述实例化。当在编译时使用的设备类型未知时,必须使用节点映射对象访问参数或节点。这适用于,例如,当机器视觉应用程序可能使用多种类型的摄像机设备时,例如GigE和IIDC 1394设备。

 // Allow all the names in the namespace GenApi to be used without qualification.
    using namespace GenApi;
    // Get the camera control object.
    INodeMap &control = camera.GetNodeMap();
    // Get the parameters for setting the image area of interest (Image AOI).
    const CIntegerPtr width = control.GetNode("Width");
    const CIntegerPtr height = control.GetNode("Height");
    const CIntegerPtr offsetX = control.GetNode("OffsetX");
    const CIntegerPtr offsetY = control.GetNode("OffsetY");
    // Maximize the Image AOI.
    if (IsWritable(offsetX) {
       offsetX->SetValue(offsetX->GetMin());
    }
    if (IsWritable(offsetY)) {
        offsetY->SetValue(offsetY->GetMin());
    }
    width->SetValue(width->GetMax());
    height->SetValue(height->GetMax());
    // Set the pixel data format.
    CEnumerationPtr(control.GetNode("PixelFormat"))->FromString("Mono8");
数据类型
参数访问模式

  每个参数都有一个访问模式,该模式描述特性是否实现、可用、可读和可写。对于给定的相机,可能根本不实现功能。例如,单色相机将不包括白平衡功能。根据相机的状态,功能可能暂时不可用。例如,当相机处于自由运行模式时,与外部触发相关的参数可能不可用。可用的特性可以是只读的、只写的,也可以是可读可写的。
  通过调用参数的GetAccessMode()方法可以查询参数的当前状态,该方法返回一个GenApi::EAccessMode枚举值,该枚举值描述如下表:


图片.png

  参数的访问模式可以在运行时更改。例如,当相机获取图像时,AOI宽度和AOI高度将是只读的。因此,建议在使用参数之前检查参数的访问模式。因此,GenApi名称空间包含以下帮助函数,它们要么接受EAccessMode值、指针,要么接受对参数的引用:

#include <pylon/gige/BaslerGigEInstantCamera.h>
using namespace Basler_GigECameraParams;

// ...
// If the AOI width is writable, set the AOI width
if ( GenApi::IsWritable ( camera.Width ) )
camera.Width = 640;
// If the pixel format is supported, set the camera to Mono16 pixel format
if ( GenApi::IsAvailable( camera.PixelFormat.GetEntry(PixelFormat_Mono16)) )
camera.PixelFormat.SetValue( PixelFormat_Mono16 );
// ...

图像抓取

  本节展示如何使用Instant Camera类抓取图像。在抓取图像之前,必须使用以下一种或多种方法设置相机参数:

采集、传输和图像抓取

  在本文档中,我们区分了图像采集、图像数据传输和图像抓取。
  我们把相机内部的过程称为图像采集。当相机开始图像采集时,传感器就会暴露出来。曝光完成后,从传感器读出图像数据。
  所获得的图像数据通过IEEE 1394或千兆以太网等接口从相机内存传输到PC机。
  将图像数据写入PC主存储器的过程称为“抓取”图像。

结果获取

  抓取图像的数据由抓取结果数据对象持有。抓取结果数据对象无法直接被访问。它总是由一个抓取结果智能指针持有(例如:基本的抓取结果智能指针CGrabResultPtr)。智能指针与抓取结果数据对象的结合也称为抓取结果。智能指针控制抓取结果数据对象和相关图像缓冲区的重用和生存期。当所有引用抓取结果数据对象的智能指针超出范围时,抓取结果的图像缓冲区将被用于抓取。由于智能指针的概念,一个抓取结果数据对象和相关的图像缓冲区可以比用于抓取图像数据的相机对象活得更长。每个设备特定的Instant Camera类都有一个设备特定的抓取结果数据对象和一个设备特定的抓取结果智能指针。通过复制或赋值,可以将设备特定的抓取结果智能指针转换为或从基本的抓取结果智能指针CGrabResultPtr。
  抓取结果智能指针类提供了一个转换操作符,允许将抓取结果智能指针直接传递给函数或方法,这些函数或方法使用const Pylon:: iimage作为参数,例如图像保存函数。

缓冲区处理

  从StartGrabbing()开始,为每个grab会话自动分配新的缓冲区。抓取图像的缓冲区由抓取结果数据对象持有。在抓取过程中,当抓取结果智能指针释放抓取结果数据对象时,缓冲区将被重用。如果在抓取停止时释放抓取结果数据对象,则释放缓冲区。
  可以使用MaxNumBuffer参数设置使用的图像数据缓冲区的数量。用于抓取的默认缓冲区数量为10。
  抓取所需的缓冲区大小会被自动确定。
当抓取一个定义的图像数量小于MaxNumBuffer的值时,分配的缓冲区的数量会自动减少,例如5。
注:可以将缓冲工厂附加到即时相机对象上,以便使用用户提供的缓冲。缓冲工厂的使用是可选的,并且只适用于高级用例。

抓取引擎

  即时相机抓取引擎由一个空的缓冲区队列、一个输出队列和一个抓取线程组成。抓取引擎使用低级API流抓取器抓取图像。空缓冲区队列和输出队列可以保存MaxNumBuffer参数定义的缓冲区数量。MaxNumQueuedBuffer缓冲区在任何时候都被传递给低级API流抓取器。所有队列都以FIFO模式(先进先出)工作。grab引擎线程确保流抓取器不会耗尽缓冲区,只要缓冲区在空缓冲区队列中可用。

默认one by one抓取策略

  即时相机支持不同的抓取策略。默认策略是一个接一个。当采用逐帧抓取策略时,图像按采集顺序进行处理。


图片.png
  1. 即时相机抓取引擎从空缓冲区队列中取出缓冲区,并在低级API流抓取器(1)中对空缓冲区进行排队。
  2. 相机设备被触发(2)。相机设备获取图像,将图像传输到PC机,然后抓取到一个空的缓冲区中。
  3. 即时相机抓取引擎线程被通知有一个已填充的缓冲区可用。已填充的缓冲区由grab engine线程(3)检索并放入输出队列。
  4. 在RetrieveResult()方法中等待的应用程序线程将得到通知,它停止等待抓取结果,并作为抓取结果数据对象的一部分检索已填充的缓冲区(4)。
  5. 抓取结果数据对象由抓取结果智能指针持有。应用程序处理完图像数据后,将填满的缓冲区返回到空缓冲区队列(5)。这是由grab result智能指针析构函数或当grab result数据对象显式释放时完成的。返回的缓冲区再次用于抓取。
在一个循环中抓取图像
//使用第一个发现的相机设备创建一个即时相机对象
CInstantCamera camera( CTlFactory::GetInstance().CreateFirstDevice());
// 打印相机模式名称
cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;
// 开始抓取 c_countOfImagesToGrab 图像.
// 相机设备是参数化的默认配置,设置自由运行的连续采集。
camera.StartGrabbing( c_countOfImagesToGrab);
// 用于接收抓取结果数据的智能指针
CGrabResultPtr ptrGrabResult;

//当c_countOfImagesToGrab被重新取回时,
// Camera.StopGrabbing() 被RetrieveResult()方法自动调用
while ( camera.IsGrabbing())
{
    // 等待一帧图像并取回. 设置超时500ms
    camera.RetrieveResult( 5000, ptrGrabResult, TimeoutHandling_ThrowException);

    // 图像是否被专区?
    if (ptrGrabResult->GrabSucceeded())
    {
        //访问图像数据信息.
        cout << "SizeX: " << ptrGrabResult->GetWidth() << endl;
        cout << "SizeY: " << ptrGrabResult->GetHeight() << endl;
        const uint8_t *pImageBuffer = (uint8_t *) ptrGrabResult->GetBuffer();
        cout << "Gray value of first pixel: " << (uint32_t) pImageBuffer[0] << endl << endl;

    }
    else
    {
        cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
    }
}

  创建相机对象。通过调用startgrab()开始抓取。由于相机还没有打开,它将通过startgrab()方法自动打开。调用默认配置事件处理程序并应用默认配置。图像被即时相机对象连续抓取,抓取结果按相机要求的顺序放入即时相机的输出队列中(抓取策略一个接一个)。RetrieveResult()方法用于等待抓取结果并从输出队列中检索它。一些抓取结果数据在检索后被打印到屏幕上。在检索c_countOfImagesToGrab图像时,RetrieveResult()方法自动调用stopgrab()。while语句条件用于检查抓取是否已停止。
  通过在startgrab()调用中省略要抓取的最大图像数量,并从grab循环内部调用stopgrab()来完成抓取,可以开始抓取无限数量的图像。

使用即时相机提供的抓取循环线程抓取图像

  Instant Camera类可以选择性地提供一个抓取循环线程。该线程运行一个抓取循环,反复调用RetrieveResult()。当使用提供的抓取循环线程时,需要一个图像事件处理程序来处理抓取结果。
使用以下图像事件处理程序:

class CImageEventPrinter : public CImageEventHandler
{
public:

    virtual void OnImageGrabbed( CInstantCamera& camera, const CGrabResultPtr& ptrGrabResult)
    {
        std::cout << "OnImageGrabbed event for device " << camera.GetDeviceInfo().GetModelName() << std::endl;

        // Image grabbed successfully?
        if (ptrGrabResult->GrabSucceeded())
        {
            std::cout << "SizeX: " << ptrGrabResult->GetWidth() << std::endl;
            std::cout << "SizeY: " << ptrGrabResult->GetHeight() << std::endl;
            const uint8_t *pImageBuffer = (uint8_t *) ptrGrabResult->GetBuffer();
            std::cout << "Gray value of first pixel: " << (uint32_t) pImageBuffer[0] << std::endl;
            std::cout << std::endl;
        }
        else
        {
            std::cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << std::endl;
        }
    }
};

下面的示例展示如何使用Instant Camera对象提供的grab循环线程进行抓取:

// 图像事件打印机用作示例图像处理.
// 当使用由Instant Camera对象提供的抓取循环线程时,必须创建并注册一个处理抓取结果的图像事件处理程序
camera.RegisterImageEventHandler( new CImageEventPrinter, RegistrationMode_Append, Cleanup_Delete);

// 通过设置GrabLoop_ProvidedByInstantCamera的grabLoopType参数,使用grab loop线程启动抓取
//  抓取结果被交付给图像事件处理程序,使用GrabStrategy_OneByOne默认抓取策略
camera.StartGrabbing( GrabStrategy_OneByOne, GrabLoop_ProvidedByInstantCamera);

cerr << endl << "Enter \"t\" to trigger the camera or \"e\" to exit and press enter? (t/e)" << endl << endl;

// 等待用户输入触发相机或退出程序.
// 停止抓取,关闭设备,当相机对象超出范围时自动销毁.
char key;
do
{
cin.get(key);
if ( (key == 't' || key == 'T'))
{
    //执行软件触发器。等待到达500毫秒的相机准备触发.
    if ( camera.WaitForFrameTriggerReady( 500, TimeoutHandling_ThrowException))
    {
        camera.ExecuteSoftwareTrigger();
    }
}
}
while ( (key != 'e') && (key != 'E'));

  首先,注册映像事件处理程序。每抓取一张图片,它都会在屏幕上打印一条信息。在本例中,它用作图像处理。对于无限数量的图像,使用startgrab()启动抓取,并通过将第二个参数设置为GrabLoop_ProvidedByInstantCamera,使用InstantCamera对象提供的抓取循环线程。现在可以使用主线程查询用户的输入,以触发图像或退出输入循环。在本例中,抓取没有显式停止,可以通过调用stopgrab()来停止。

抓取一帧图像

  为了方便起见,可以使用GrabOne()方法来抓取单个图像。下面的代码显示了所做工作的简化版本

//grab one image
StartGrabbing( 1, GrabStrategy_OneByOne, GrabLoop_ProvidedByUser);

//grab is stopped automatically due to maxImages = 1
return RetrieveResult( timeoutMs, grabResult, timeoutHandling) && grabResult->GrabSucceeded();

  如果pylon设备已经打开,则使用GrabOne()更有效,否则每次调用都会自动打开和关闭pylon设备。
  如果您想最大化帧率,建议使用SoftwareTrigger (CSoftwareTriggerConfiguration)抓取单个图像。这是因为与单帧采集相比,每次抓取图像的开销减少了。可以使用StartGrabbing()启动抓取。使用WaitForFrameTriggerReady()、ExecuteSoftwareTrigger()和RetrieveResult()方法捕捉图像,而不是使用GrabOne()。抓取完成后,可以使用StopGrabbing()停止抓取。

使用先进的相机功能

相机事件处理

  Basler GigE Vision、USB3 Vision和IIDC 1394摄像机可以发送事件消息。例如,当传感器曝光完成时,相机可以向PC发送曝光结束事件。可以通过在一个Instant Camera类中注册一个图像事件处理程序来接收事件。

访问块功能

  Basler摄像机能够发送附加到图像数据的所谓数据块的附加信息,比如帧计数器、时间戳或CRC校验和。如果被激活,数据块将由Instant Camera类自动解析

获取关于相机设备移除的信息

  要获得关于摄像机设备移除的信息,可以查询IsCameraDeviceRemoved()方法,或者注册配置事件处理程序。如果移除摄像机设备,则调用OnCameraDeviceRemoved()虚拟方法
注:OnCameraDeviceRemoved调用是从一个单独的线程发出的。

GigE多播/广播:在多台pc上抓取一台相机的图像

  Basler GigE摄像机可以配置为将图像数据流发送到多个目的地。可以使用IP组播或IP广播。

图像处理和图像显示

  除了用于抓取图像的即时相机类外,pylon还提供了额外的图像处理支持,支持处理抓取的图像。图像类,Windows位图图像支持,一个图像格式转换器,一个图像窗口,以及图像的加载和保存。

pylon图像类

  在处理图像数据时,缓冲区大小和生存期的处理通常涉及大量编码。Pylon::CPylonImage类简化了这一点。它还允许附加抓取结果的缓冲区,以防止在需要时重用它。此外,还可以连接用户缓冲区或由第三方软件包提供的缓冲区。此外,当使用图像平面或AOIs时,pylon像类也会有所帮助。utility y_image代码示例显示了pylon映像类的使用。

pylon位图图像类

  pylon::CPylonBitmapImage类简化了用于显示图像数据的Windows位图图像的创建。

图像格式转换

  Pylon::CImageFormatConverter通过将源图像转换为另一种格式来创建新图像。一旦配置了格式转换器,它就可以转换几乎所有Basler摄像机设备支持的图像格式。

AVI writter

  Pylon::CAviWroter可用于创建音频视频交错(AVI)格式的视频文件。

加载和保存图形

  Pylon::CImagePersistence支持加载和保存图形至硬盘。pylon映像类在内部使用这个接口,并提供加载和保存方法。

pylon 图像显示

  pylon图像窗口允许您使用DisplayImage或CPylonImageWindow类轻松地在屏幕上显示图像。您可以使用CPylonImageWindow类来检查从摄像机检索到的图像或CPixelFormatConverter的结果。
  每个pylon图像窗口都由一个惟一的图像窗口索引来寻址。有效的图像窗口索引范围从0到31.
  全局函数DisplayImage()提供了在屏幕上显示图像的最简单方法。您需要指定用于图像显示的图像窗口的图像窗口索引,并传递图像或获取结果。这将在必要时创建窗口,设置内容,并在屏幕上显示窗口。图像窗口将在内存中创建图像的副本,以便在函数返回后释放图像或安全地获取结果。
  要清除窗口并释放图像所需的内存,可以显示一个空图像。
  当用户使用鼠标或按Alt+F4关闭图像窗口时,图像窗口只会被隐藏。您可以调用CPylonImageWindow::Show()使其再次可见。
  要实际销毁窗口,必须调用CPylonImageWindow::Close()。如果您不关闭窗口,pylon将在调用PylonTerminate时关闭所有现有的映像窗口。
注:所有CPylonImageWindow函数都是完全线程安全的。
  如果需要对图像窗口进行更多控制,可以显式地调用CPylonImageWindow::Create()并传递图像窗口的位置和大小。调用CPylonImageWindow::Create()后,图像窗口在屏幕上不可见。要使其可见,必须调用CPylonImageWindow::Show()。
  当CPylonImageWindow::Create()成功返回时,对象将存储在CPylonImageWindow::Create()中传递的图像窗口索引,并将其用于所有其他成员函数。当CPylonImageWindow对象被销毁时,析构函数将关闭图像窗口。如果希望保留图像窗口,必须在销毁对象之前调用CPylonImageWindow::Detach()。
要使用Pylon图像窗口,需要包含pylon/PylonGUIIncludes.h头文件。

上一篇下一篇

猜你喜欢

热点阅读