美文网首页
Linux系统配置Basler相机驱动(软件触发和硬件触发)Op

Linux系统配置Basler相机驱动(软件触发和硬件触发)Op

作者: 魁爷的黑作坊 | 来源:发表于2017-11-26 00:43 被阅读0次

由于学校实验室需要用到Basler相机,然而网上Basler相机的说明文档是全英文的,对新手不太友好,而且国内关于Basler的硬件触发代码没有。在研究了Basler相机的SDK之后总结出了触发的驱动,还有照片与OpenCV格式转换的代码,希望可以对你们有帮助。

测试环境

  • Ubuntu14.04
  • Pylon5.0.5
  • OpenCV3.4.14
  • 相机型号acA1600-60gm/acA2500-14gm

使用步骤

下载Basler相机的SDK(pylon)

Pylon下载网站下载对应的SDK,此处我下载的是Pylon5.0.5

安装pylon

下载的文件名为pylonSDK-5.0.5.9000-x86_64.tar.gz,将这个文件夹随便解压到一个地方。

进入解压的文件,打开终端,此时的目录为 解压的目录/pylon-5.0.5.9000-x86_64

输入命令,将SDK解压到opt目录下面

 sudo tar -C /opt -xzf pylonSDK*.tar.gz

至此,Basler的SDK(Pylon)安装完成

软件触发

前期准备

将摄像机的电源线插上,电源线的制作方法详见Basler相机的说明PDF

网线也插上,用/opt/pylon5/ipconfiguretion将相机的ip和主机的ip设置在同一网段内

/opt/pylon5/bin/pylon查看相机是否连接成功,是否可以拍摄照片

代码编写

softwareTrigger.cpp源文件

软件触发的源文件,用死循环一直循环取图像,包含拍照的图像转成OpenCV的Mat矩阵

//#include <opencv2/opencv.hpp>
#include <pylon/PylonIncludes.h>
using namespace Pylon;
using namespace GenApi;
//using namespace cv;
using namespace std;

int main(){
    try{
        PylonInitialize();          //初始化相机
        CInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice());

        cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;
        camera.Open();

        camera.StartGrabbing(GrabStrategy_LatestImages);

        CGrabResultPtr ptrGrabResult;   
        CPylonImage image;           //图片结构体

        while(1){
            camera.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);

            CImageFormatConverter fc;
            fc.OutputPixelFormat = PixelType_BGR8packed;
            if (ptrGrabResult->GrabSucceeded())
            {
                cout << "Please wait. Images are grabbed." << endl;
                cout << ptrGrabResult->GetWidth()<<endl;
                cout << ptrGrabResult->GetHeight()<<endl;

                /* 将相机拍的照片转换成OpenCV的Mat矩阵
                // fc.Convert(image, ptrGrabResult);//转换
                // int imRows = ptrGrabResult->GetWidth() / 3;
                // int imCols = ptrGrabResult->GetHeight() / 3;
                // Mat cv_img = Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t*)image.GetBuffer());
                // imshow("OpenCVimg",cv_img);
                // waitKey(0);
                */
            }
        }
        camera.Close();//一定要记得关闭,不然重新连接连不上相机
    }
    catch (const GenericException &e)
    {
        // Error handling.
        cerr << "An exception occurred." << endl
        << e.GetDescription() << endl;
    }
    return 0;
}

制作makefile文件,将库引入进来

# Makefile for Basler pylon sample program
.PHONY: all clean

# The program to build
NAME       := SoftwareTrigger

# Installation directories for pylon
PYLON_ROOT ?= /opt/pylon5

# Build tools and flags
LD         := $(CXX)
CPPFLAGS   := $(shell $(PYLON_ROOT)/bin/pylon-config --cflags)
CXXFLAGS   := #e.g., CXXFLAGS=-g -O0 for debugging
LDFLAGS    := $(shell $(PYLON_ROOT)/bin/pylon-config --libs-rpath)
LDLIBS     := $(shell $(PYLON_ROOT)/bin/pylon-config --libs)

# Rules for building
all: $(NAME)

$(NAME): $(NAME).o
    $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)

$(NAME).o: $(NAME).cpp
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

clean:
    $(RM) $(NAME).o $(NAME)

运行结果

robot@robot:~/桌面/ubuntu/Trigger/SoftwareTrigger$ ./SoftwareTrigger 
Using device acA1600-60gm
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200

硬件触发

前期准备

将摄像机的电源线插上,电源线的制作方法详见Basler相机的说明PDF

网线也插上,用/opt/pylon5/ipconfiguretion将相机的ip和主机的ip设置在同一网段内

/opt/pylon5/bin/pylon查看相机是否连接成功,是否可以拍摄照片

代码编写

按照官方的介绍,需要我们自己定义硬件触发配置的头文件,在头文件定义是哪个线触发,上升沿触发还是下降沿触发。

hardwaretriggerconfiguration.h

#ifndef HARDWARETRIGGERCONFIGURATION_H
#define HARDWARETRIGGERCONFIGURATION_H
#include <pylon/Platform.h>

#ifdef _MSC_VER
#   pragma pack(push, PYLON_PACKING)
#endif /* _MSC_VER */

#include <pylon/InstantCamera.h>

namespace Pylon
{
    /** \addtogroup Pylon_InstantCameraApiGeneric
     * @{
     */

    /*!
    \class  CSoftwareTriggerConfiguration
    \brief  Changes the configuration of the camera so that the acquisition of frames is triggered by software trigger.
            Use together with CInstantCamera::WaitForFrameTriggerReady() and CInstantCamera::ExecuteSoftwareTrigger().

        The %CSoftwareTriggerConfiguration is provided as header-only file.
        The code can be copied and modified for creating own configuration classes.
    */
    class CHardwareTriggerConfiguration : public CConfigurationEventHandler
    {
    public:
        /// Apply software trigger configuration.
        static void ApplyConfiguration( GENAPI_NAMESPACE::INodeMap& nodemap)
        {
            using namespace GENAPI_NAMESPACE;

            // Disable all trigger types except the trigger type used for triggering the acquisition of
            // frames.
            {
                // Get required enumerations.
                CEnumerationPtr triggerSelector( nodemap.GetNode("TriggerSelector"));
                CEnumerationPtr triggerMode( nodemap.GetNode("TriggerMode"));

                // Check the available camera trigger mode(s) to select the appropriate one: acquisition start trigger mode
                // (used by older cameras, i.e. for cameras supporting only the legacy image acquisition control mode;
                // do not confuse with acquisition start command) or frame start trigger mode
                // (used by newer cameras, i.e. for cameras using the standard image acquisition control mode;
                // equivalent to the acquisition start trigger mode in the legacy image acquisition control mode).
                String_t triggerName( "FrameStart");
                if ( !IsAvailable( triggerSelector->GetEntryByName(triggerName)))
                {
                    triggerName = "AcquisitionStart";
                    if ( !IsAvailable( triggerSelector->GetEntryByName(triggerName)))
                    {
                        throw RUNTIME_EXCEPTION( "Could not select trigger. Neither FrameStart nor AcquisitionStart is available.");
                    }
                }

                // Get all enumeration entries of trigger selector.
                GENAPI_NAMESPACE::NodeList_t triggerSelectorEntries;
                triggerSelector->GetEntries( triggerSelectorEntries );

                // Turn trigger mode off for all trigger selector entries except for the frame trigger given by triggerName.
                for ( GENAPI_NAMESPACE::NodeList_t::iterator it = triggerSelectorEntries.begin(); it != triggerSelectorEntries.end(); ++it)
                {
                    // Set trigger mode to off if the trigger is available.
                    GENAPI_NAMESPACE::CEnumEntryPtr pEntry(*it);
                    if ( IsAvailable( pEntry))
                    {
                        String_t triggerNameOfEntry( pEntry->GetSymbolic());
                        triggerSelector->FromString( triggerNameOfEntry);
                        if ( triggerName == triggerNameOfEntry)
                        {
                            // Activate trigger.
                            triggerMode->FromString( "On");

                            // The trigger source must be set to 'Software'.
//                            CEnumerationPtr(nodemap.GetNode("TriggerSource"))->FromString("Software");

                            //// Alternative hardware trigger configuration:
                            //// This configuration can be copied and modified to create a hardware trigger configuration.
                            //// Remove setting the 'TriggerSource' to 'Software' (see above) and
                            //// use the commented lines as a starting point.
                            //// The camera user's manual contains more information about available configurations.
                            //// The Basler pylon Viewer tool can be used to test the selected settings first.

                            //// The trigger source must be set to the trigger input, e.g. 'Line1'.
                            CEnumerationPtr(nodemap.GetNode("TriggerSource"))->FromString("Line1");

                            ////The trigger activation must be set to e.g. 'RisingEdge'.
                            CEnumerationPtr(nodemap.GetNode("TriggerActivation"))->FromString("RisingEdge");//上升延触发
                            CEnumerationPtr(nodemap.GetNode("TriggerActivation"))->FromString("FallingEdge");//下降延触发
                        }
                        else
                        {
                            triggerMode->FromString( "Off");
                        }
                    }
                }
                // Finally select the frame trigger type (resp. acquisition start type
                // for older cameras). Issuing a software trigger will now trigger
                // the acquisition of a frame.
                triggerSelector->FromString(triggerName);
            }


            //Set acquisition mode to "continuous"
            CEnumerationPtr(nodemap.GetNode("AcquisitionMode"))->FromString("Continuous");
        }

        //Set basic camera settings.
        virtual void OnOpened( CInstantCamera& camera)
        {
            try
            {
                ApplyConfiguration( camera.GetNodeMap());
            }
            catch (const GenericException& e)
            {
                throw RUNTIME_EXCEPTION( "Could not apply configuration. Pylon::GenericException caught in OnOpened method msg=%hs", e.what());
            }
            catch (const std::exception& e)
            {
                throw RUNTIME_EXCEPTION( "Could not apply configuration. std::exception caught in OnOpened method msg=%hs", e.what());
            }
            catch (...)
            {
                throw RUNTIME_EXCEPTION( "Could not apply configuration. Unknown exception caught in OnOpened method.");
            }
        }
    };

    /**
     * @}
     */
}

#ifdef _MSC_VER
#   pragma pack(pop)
#endif /* _MSC_VER */


#endif // HARDWARETRIGGERCONFIGURATION_H

HardwareTrigger.cpp

#include <pylon/PylonIncludes.h>
#include "hardwaretriggerconfiguration.h"
using namespace Pylon;
using namespace GenApi;
using namespace std;

int main(){
    // The exit code of the sample application.
    int exitCode = 0;

    // Before using any pylon methods, the pylon runtime must be initialized.
    PylonInitialize();

    try
    {
        // This smart pointer will receive the grab result data.
        CGrabResultPtr ptrGrabResult;

        // Create an instant camera object for the camera device found first.
        CInstantCamera camera( CTlFactory::GetInstance().CreateFirstDevice());

        // Register the standard configuration event handler for enabling software triggering.
        // The software trigger configuration handler replaces the default configuration
        // as all currently registered configuration handlers are removed by setting the registration mode to RegistrationMode_ReplaceAll.
        camera.RegisterConfiguration( new CHardwareTriggerConfiguration, RegistrationMode_ReplaceAll, Cleanup_Delete);

        // For demonstration purposes only, add sample configuration event handlers to print out information
        // about camera use and image grabbing.
//        camera.RegisterConfiguration( new CConfigurationEventPrinter, RegistrationMode_Append, Cleanup_Delete);
//        camera.RegisterImageEventHandler( new CImageEventPrinter, RegistrationMode_Append, Cleanup_Delete);

        // Print the model name of the camera.
        cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;

        // The MaxNumBuffer parameter can be used to control the count of buffers
        // allocated for grabbing. The default value of this parameter is 10.
        camera.MaxNumBuffer = 10;

        // Open the camera.
        camera.Open();

        camera.StartGrabbing(GrabStrategy_LatestImages);
        CPylonImage image;

        while(1){
            //第一个参数是两次触发间隔的时间
            camera.RetrieveResult(50000, ptrGrabResult, TimeoutHandling_ThrowException);

            CImageFormatConverter fc;
            fc.OutputPixelFormat = PixelType_BGR8packed;
            if (ptrGrabResult->GrabSucceeded())
            {
                cout << "Please wait. Images are grabbed." << endl;
                cout << ptrGrabResult->GetWidth()<<endl;
                cout << ptrGrabResult->GetHeight()<<endl;

                // fc.Convert(image, ptrGrabResult);//转换
                // int imRows = ptrGrabResult->GetWidth() / 3;
                // int imCols = ptrGrabResult->GetHeight() / 3;
                // Mat cv_img = Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t*)image.GetBuffer());
                // imshow("img",cv_img);
                // waitKey(0);
            }
        }
    }
    catch (const GenericException &e)
    {
        // Error handling.
        cerr << "An exception occurred." << endl
        << e.GetDescription() << endl;
        exitCode = 1;
    }
    // Releases all pylon resources.
    PylonTerminate();

    return 0;
}

Makefile文件

# Makefile for Basler pylon sample program
.PHONY: all clean

# The program to build
NAME       := HardwareTrigger

# Installation directories for pylon
PYLON_ROOT ?= /opt/pylon5

# Build tools and flags
LD         := $(CXX)
CPPFLAGS   := $(shell $(PYLON_ROOT)/bin/pylon-config --cflags)
CXXFLAGS   := #e.g., CXXFLAGS=-g -O0 for debugging
LDFLAGS    := $(shell $(PYLON_ROOT)/bin/pylon-config --libs-rpath)
LDLIBS     := $(shell $(PYLON_ROOT)/bin/pylon-config --libs)

# Rules for building
all: $(NAME)

$(NAME): $(NAME).o
    $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)

$(NAME).o: $(NAME).cpp
    $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

clean:
    $(RM) $(NAME).o $(NAME)

运行编译出的可执行文件之后,不断触发相机,可得出一下的结果即触发成功

Using device acA1600-60gm
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200
Please wait. Images are grabbed.
1600
1200

示例下载

以上代码的示例链接: https://pan.baidu.com/s/1QsJy4h_DZhQUEGiaT0qo9g
提取码:zrci

Qt+OpenCV版本代码链接: https://pan.baidu.com/s/1CEOOwS-Qw7GB_UDiZRyW5g
提取码:q5z1

相机图片

Basler相机
Basler相机

相关文章

  • Linux系统配置Basler相机驱动(软件触发和硬件触发)Op

    由于学校实验室需要用到Basler相机,然而网上Basler相机的说明文档是全英文的,对新手不太友好,而且国内关于...

  • Linux驱动

    【一】驱动的概念:通过软件驱动硬件,使硬件处于某种工作模式,提供控制硬件的方法。 【二】Linux架构体系(精简)...

  • Android系统架构

    Android系统架构 Linux内核层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、相机...

  • 《Linux设备驱动开发详解》读书笔记

    第 1 章 Linux 设备驱动概述及开发环境构建 1. 设备驱动的定义 设备驱动充当了硬件和应用软件之间的纽带,...

  • 异常处理

    异常的发生和捕获是在硬件层面完成的、异常的处理是软件完成的 异常分类 中断Interrupt 触发CPU内部开关值...

  • Linux

    linux IO复用 epoll与select的区别 水平触发和边沿触发的区别 讲一下同步异步(进程和IO) 讲一...

  • 触发点疗法学习笔记4:触发点的种类

    触发点疗法学习笔记4:触发点的种类 1、触发点分为主触发点和卫星触发点;活跃触发点和潜在触发点。共同特征:按压它们...

  • epoll 边沿触发和水平触发

    1. epoll 边沿触发和水平触发 对于epoll有两种触发模式:水平触发LT和边缘触发ET,其中边缘触发必须需...

  • LINUX音频驱动架构

    简介 LINUX下音频驱动开发,要遵循标准的ALSA架构,下面分别从硬件架构、软件架构、驱动程序,3个方面分析。 ...

  • Ubuntu16.04下配置Basler工业相机(使用QtCre

    Basler工业相机网上资料少,写的博客更少,当时为了把这个Basler相机用起来,不知道耗费了我多少心血。查阅了...

网友评论

      本文标题:Linux系统配置Basler相机驱动(软件触发和硬件触发)Op

      本文链接:https://www.haomeiwen.com/subject/revhbxtx.html