Ubuntu16.04下配置Basler工业相机(使用QtCreator)

Basler工业相机网上资料少,写的博客更少,当时为了把这个Basler相机用起来,不知道耗费了我多少心血。
查阅了Basler的官方文档,还有各种语焉不详的博客,终于能够在Linux下调用Basler相机了。
所以我决定写一篇非常详细的博客,好让后来者少踩些坑。


我的第一个工业相机,据说这玩意要近万块钱

其实Linux下配置Basler摄像头时和配置OpenCV时相差不大。
先去 官网下载对应的安装包
https://www.baslerweb.com/cn/sales-support/downloads/software-downloads/#type=pylonsoftware;version=all;os=windows
根据自己的系统选择x86或者x86_64(即x64)版本。

我的相机型号为acA1920-40gc。

下载好后,对压缩包进行解压操作,可以选择解压文件到自己选择的目录,此处我们选择默认当前目录:

$ tar -xzvf  pylon-5.0.***.tar.gz

解压文件后,打开文件,里边还有一个压缩包,此压缩包即为安装文件,解压此文件到/opt目录下:

$ sudo tar -C /opt -xzvf pylon***armhf.tar.gz

安装完毕后就开始在qtcreator中进行配置,以便在Qtcreator中调用该相机。
1、首先打开Qtcreator,如下图所示,创建控制台项目或者空项目


————————————————————————————
2、然后打开.pro文件,在其中配置Basler相机:

先找到INCLUDEPATH的路径:
(1)点开“计算机”,点开文件夹“opt”



(2)接着打开pylon5文件夹



那么INCLUDEPATH 的内容为:
INCLUDEPATH += /opt/pylon5/include \
/opt/pylon5/include/pylon

例子:(下图中我是把OpenCV和Basler一起配置)


——————————————————————————————————

3、写好了INCLUDEPATH,再来写LIBS。
LIBS(我目前知道的)有2种写法:
第一种是直接写出路径来:

例子:
LIBS += /usr/local/lib/libopencv_calib3d.so \
/usr/local/lib/libopencv_calib3d.so.3.2 \
/usr/local/lib/libopencv_calib3d.so.3.2.0 \
/usr/local/lib/libopencv_core.so \

第二种方法是先写一个总的,再写分的:

例子:
LIBS +=-L/opt/pylon5/lib64 \
-lbxapi-5.0.11 \
-lbxapi \
-lFirmwareUpdate_gcc_v3_0_Basler_pylon_v5_0 \
-lGCBase_gcc_v3_0_Basler_pylon_v5_0 \
-lGenApi_gcc_v3_0_Basler_pylon_v5_0 \
-lgxapi-5.0.11 \

这2种写法都是一样的,是通用的。

先找到LIB所在的路径为 opt / pylon5 / lib64



可以看到里面有很多后缀为.so的文件,把这些文件的路径写到.pro文件中就行了。



这里我把我总的.pro文件内容贴出来,可供参考:
(我这里面同时配置了OpenCV和Basler,注意我的Basler的版本为5.0.11)
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp

INCLUDEPATH += /usr/local/include \
/usr/local/include/opencv \
/usr/local/include/opencv2 \
/opt/pylon5/include \
/opt/pylon5/include/pylon

LIBS += /usr/local/lib/libopencv_calib3d.so \
/usr/local/lib/libopencv_calib3d.so.3.2 \
/usr/local/lib/libopencv_calib3d.so.3.2.0 \
/usr/local/lib/libopencv_core.so \
/usr/local/lib/libopencv_core.so.3.2 \
/usr/local/lib/libopencv_core.so.3.2.0 \
/usr/local/lib/libopencv_features2d.so \
/usr/local/lib/libopencv_features2d.so.3.2 \
/usr/local/lib/libopencv_features2d.so.3.2.0 \
/usr/local/lib/libopencv_flann.so \
/usr/local/lib/libopencv_flann.so.3.2 \
/usr/local/lib/libopencv_flann.so.3.2.0 \
/usr/local/lib/libopencv_highgui.so \
/usr/local/lib/libopencv_highgui.so.3.2 \
/usr/local/lib/libopencv_highgui.so.3.2.0 \
/usr/local/lib/libopencv_imgcodecs.so \
/usr/local/lib/libopencv_imgcodecs.so.3.2 \
/usr/local/lib/libopencv_imgcodecs.so.3.2.0 \
/usr/local/lib/libopencv_imgproc.so \
/usr/local/lib/libopencv_imgproc.so.3.2 \
/usr/local/lib/libopencv_imgproc.so.3.2.0 \
/usr/local/lib/libopencv_ml.so \
/usr/local/lib/libopencv_ml.so.3.2 \
/usr/local/lib/libopencv_ml.so.3.2.0 \
/usr/local/lib/libopencv_objdetect.so \
/usr/local/lib/libopencv_objdetect.so.3.2 \
/usr/local/lib/libopencv_objdetect.so.3.2.0 \
/usr/local/lib/libopencv_photo.so \
/usr/local/lib/libopencv_photo.so.3.2 \
/usr/local/lib/libopencv_photo.so.3.2.0 \
/usr/local/lib/libopencv_shape.so \
/usr/local/lib/libopencv_shape.so.3.2 \
/usr/local/lib/libopencv_shape.so.3.2.0 \
/usr/local/lib/libopencv_stitching.so \
/usr/local/lib/libopencv_stitching.so.3.2 \
/usr/local/lib/libopencv_stitching.so.3.2.0 \
/usr/local/lib/libopencv_superres.so \
/usr/local/lib/libopencv_superres.so.3.2 \
/usr/local/lib/libopencv_superres.so.3.2.0 \
/usr/local/lib/libopencv_video.so \
/usr/local/lib/libopencv_video.so.3.2 \
/usr/local/lib/libopencv_video.so.3.2.0 \
/usr/local/lib/libopencv_videoio.so \
/usr/local/lib/libopencv_videoio.so.3.2 \
/usr/local/lib/libopencv_videoio.so.3.2.0 \
/usr/local/lib/libopencv_videostab.so \
/usr/local/lib/libopencv_videostab.so.3.2 \
/usr/local/lib/libopencv_videostab.so.3.2.0 \
/usr/local/lib/libopencv_viz.so \
/usr/local/lib/libopencv_viz.so.3.2 \
/usr/local/lib/libopencv_viz.so.3.2.0 \
-L/opt/pylon5/lib64 \
-lbxapi-5.0.11 \
-lbxapi \
-lFirmwareUpdate_gcc_v3_0_Basler_pylon_v5_0 \
-lGCBase_gcc_v3_0_Basler_pylon_v5_0 \
-lGenApi_gcc_v3_0_Basler_pylon_v5_0 \
-lgxapi-5.0.11 \
-lgxapi \
-llog4cpp_gcc_v3_0_Basler_pylon_v5_0 \
-lLog_gcc_v3_0_Basler_pylon_v5_0 \
-lMathParser_gcc_v3_0_Basler_pylon_v5_0 \
-lNodeMapData_gcc_v3_0_Basler_pylon_v5_0 \
-lpylonbase-5.0.11 \
-lpylonbase \
-lpylonc-5.0.11 \
-lpylonc \
-lpylon_TL_bcon-5.0.11 \
-lpylon_TL_bcon \
-lpylon_TL_camemu-5.0.11 \
-lpylon_TL_camemu \
-lpylon_TL_gige-5.0.11 \
-lpylon_TL_gige \
-lpylon_TL_usb-5.0.11 \
-lpylon_TL_usb \
-lpylonutility-5.0.11 \
-lpylonutility \
-luxapi-5.0.11 \
-luxapi \
-lXmlParser_gcc_v3_0_Basler_pylon_v5_0 \

4、这样配置好了.pro文件,就能开始写程序了。
在Linux中调用Basler摄像头,需要一段比较长的代码,代码如下:

//定义是否保存图片
#define saveImages 0
//定义是否记录视频
#define recordVideo 0

// 加载OpenCV API
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/video.hpp>
#include<opencv2/opencv.hpp>

//加载PYLON API.
#include <pylon/PylonIncludes.h>

#include <pylon/gige/BaslerGigEInstantCamera.h> //自动调节

//加载C++ 头文件
#include<iostream>


//命名空间.
using namespace Pylon;
using namespace cv;
using namespace std;

using namespace Basler_GigECameraParams; //自动调节

typedef Pylon::CBaslerGigEInstantCamera Camera_t; //自动调节
typedef Camera_t::GrabResultPtr_t GrabResultPtr_t; //自动调节


static const uint32_t c_countOfImagesToGrab = 2000;

int saveImage_flag=0; //保存一张图片

int main()
{
                 cout<<"000"<<endl;
    //Pylon自动初始化和终止
    Pylon::PylonAutoInitTerm autoInitTerm;

    try
    {
               cout<<"0"<<endl;

        // 原程序对camera的定义
        //CInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice());

       CDeviceInfo info;
       info.SetDeviceClass( Camera_t::DeviceClass());

       // Create an instant camera object with the first found camera device that matches the specified device class.
       Camera_t camera( CTlFactory::GetInstance().CreateFirstDevice( info));


              cout<<"1"<<endl;

        // 打印相机的名称
        std::cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl;
                cout<<"2"<<endl;

        //获取相机节点映射以获得相机参数
        GenApi::INodeMap& nodemap = camera.GetNodeMap();
                            cout<<"3"<<endl;

        //打开相机
        camera.Open();
                cout<<"4"<<endl;


        //获取相机成像宽度和高度
        GenApi::CIntegerPtr width = nodemap.GetNode("Width");
        GenApi::CIntegerPtr height = nodemap.GetNode("Height");
                            cout<<"5"<<endl;

        //设置相机最大缓冲区,默认为10
        camera.MaxNumBuffer = 5;
        // 新建pylon ImageFormatConverter对象.
        CImageFormatConverter formatConverter;
                        cout<<"6"<<endl;

        //确定输出像素格式
        formatConverter.OutputPixelFormat = PixelType_BGR8packed;
        // 创建一个Pylonlmage后续将用来创建OpenCV images
        CPylonImage pylonImage;
                    cout<<"7"<<endl;

        //声明一个整形变量用来计数抓取的图像,以及创建文件名索引
        int grabbedlmages = 0;

        // 新建一个OpenCV video creator对象.
        VideoWriter cvVideoCreator;
        //新建一个OpenCV image对象.

        Mat openCvImage;
        // 视频文件名
                    cout<<"8"<<endl;

        std::string videoFileName = "openCvVideo.avi";
        // 定义视频帧大小
        cv::Size frameSize = Size((int)width->GetValue(), (int)height->GetValue());
                        cout<<"9"<<endl;
        cout<<"Width: "<<frameSize.width<<endl;
        cout<<"Height: "<<frameSize.height<<endl;


        //设置视频编码类型和帧率,有三种选择
        // 帧率必须小于等于相机成像帧率!!!!
        cvVideoCreator.open(videoFileName, CV_FOURCC('D', 'I', 'V','X'), 10, frameSize, true);
        //cvVideoCreator.open(videoFileName, CV_F0URCC('M','P',,4','2’), 20, frameSize, true);
        //cvVideoCreator.open(videoFileName, CV_FOURCC('M', '3', 'P', 'G'), 20, frameSize, true);
            cout<<"10"<<endl;

        // 开始抓取c_countOfImagesToGrab images.
        //相机默认设置连续抓取模式
        camera.StartGrabbing(-1, GrabStrategy_LatestImageOnly); //c_countOfImagesToGrab

        //抓取结果数据指针
        CGrabResultPtr ptrGrabResult;

        // 当c_countOfImagesToGrab images获取恢复成功时,Camera.StopGrabbing()
        //被RetrieveResult()方法自动调用停止抓取


        cout << "Initial Gain = " << camera.GainRaw.GetValue() << endl;


        cout << "Initial exposure time = ";
        cout << camera.ExposureTimeAbs.GetValue() << " us" << endl;


        cout << "Initial balance ratio: ";
        camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Red);
            cout << "R = " << camera.BalanceRatioAbs.GetValue() << "   ";
        camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Green);
            cout << "G = " << camera.BalanceRatioAbs.GetValue() << "   ";
        camera.BalanceRatioSelector.SetValue(BalanceRatioSelector_Blue);
            cout << "B = " << camera.BalanceRatioAbs.GetValue() << endl;


        while (camera.IsGrabbing())
        {
            // 等待接收和恢复图像,超时时间设置为5000 ms.
            camera.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);

            //如果图像抓取成功
            if (ptrGrabResult->GrabSucceeded())
            {
                // 获取图像数据
             //   cout <<"SizeX: "<<ptrGrabResult->GetWidth()<<endl;
             //   cout <<"SizeY: "<<ptrGrabResult->GetHeight()<<endl;


                //将抓取的缓冲数据转化成pylon image.
                formatConverter.Convert(pylonImage, ptrGrabResult);


                // 将 pylon image转成OpenCV image.
                openCvImage = cv::Mat(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(), CV_8UC3, (uint8_t *) pylonImage.GetBuffer());



                //如果需要保存图片
                if (saveImages)
                {
                   std::ostringstream s;
                    // 按索引定义文件名存储图片
                   s << "image_" << grabbedlmages << ".jpg";
                   std::string imageName(s.str());
                    //保存OpenCV image.
                   imwrite(imageName, openCvImage);
                   grabbedlmages++;
                }

                //如果需要记录视频
                if (recordVideo)
                {
                    cvVideoCreator.write(openCvImage);
                }


                //新建OpenCV display window.
                namedWindow("OpenCV Display Window", CV_WINDOW_NORMAL); // other options: CV_AUTOSIZE, CV_FREERATIO
                //显示及时影像.
                  if(!openCvImage.data)
                  {
                      cout<<"opencvImage fail"<<endl;
                      continue;
                  }

                imshow("OpenCV Display Window", openCvImage);

                if(saveImage_flag==0) //只保存一张图片
                {
                    imwrite("/home/fsac/2.jpg",openCvImage);
                    saveImage_flag=1;
                }


                // Define a timeout for customer's input in
                // '0' means indefinite, i.e. the next image will be displayed after closing the window.
                // '1' means live stream

                waitKey(10);

            }
            else
            {
                cout<<"图像读取失败,即ptrGrabResult->GrabSucceeded()未成功"<<endl;
                continue;
            }
        }

        if(!camera.IsGrabbing())
            cout<<"camera.IsGrabbing() is failed"<<endl;


    }
    catch (GenICam::GenericException &e)
    {
        // Error handling.
        cerr << "An exception occurred." << endl
            << e.GetDescription() << endl;
    }
    return 0;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,012评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,628评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,653评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,485评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,574评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,590评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,596评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,340评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,794评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,102评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,276评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,940评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,583评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,201评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,441评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,173评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,136评论 2 352

推荐阅读更多精彩内容