美文网首页
linux下用大恒相机采图

linux下用大恒相机采图

作者: book_02 | 来源:发表于2020-03-26 11:15 被阅读0次

    平台:Ubuntu 16.04
    相机: MER-301-125U3M

    1. 安装大恒的SDK

    从大恒官网下载linux的安装包,名称如Galaxy_Linux-x86_Gige-U3_32bits-64bits_1.2.1911.9122.tar.gz
    解压后进入Galaxy_Linux-x86_Gige-U3_32bits-64bits_1.2.1911.9122目录,
    在终端中运行./Galaxy_camera.run,便会生成安装目录Galaxy_camera

    大恒的头文件和库文件:
    头文件: 在./Galaxy_camera/inc目录,有DxImageProc.hGxIAPI.h两个文件
    库文件: 在系统库目录下,/usr/lib/libgxiapi.so,所以cmake的时候可以直接去链接

    2. 采图例程

    下面的例子是用大恒相机连续采集1500张图像,并用opencv的窗口实时显示出来。

    2.1 目录结构

    例子的总体目录结构如下:

    .
    ├── CMakeLists.txt
    ├── DxImageProc.h
    ├── generate_demo.sh
    ├── main.cpp
    └── GxIAPI.h

    1. GxIAPI.hDxImageProc.h 为大恒的头文件,从大恒安装目录的inc目录里复制过来
    2. CMakeLists.txt cmake的配置文件
    3. main.cpp 采图的源码文件
    4. generate_demo.sh一个便捷的生成脚本,里面调用了cmakemake,也可以自己在终端输入这些命令来完成。新建文件的时候要给执行权限:chmod +x generate_demo.sh

    2.2 CMakeLists.txt

    cmake_minimum_required(VERSION 2.8)
    
    project(daheng_grab_demo)
    
    FIND_PACKAGE(OpenCV REQUIRED)
    
    include_directories(./)                     # daheng include files
    
    add_executable (${PROJECT_NAME} main.cpp)
    
    target_link_libraries (${PROJECT_NAME} ${OpenCV_LIBS} gxiapi)   # libgxiapi.so is daheng lib file
    

    2.3 generate_demo.sh

    #!/bin/bash
    
    rm -rf build
    mkdir build
    
    cd build
    
    cmake .. 
    make
    
    

    2.4 main.cpp

    下面的例子是用大恒相机连续采集1500张图像,并用opencv的窗口实时显示出来。

    代码比较大,是因为加了很多错误判断和信息打印的代码,防止异常出现。

    核心的获取图像代码是
    status = GXDQBuf(hDevice, &pFrameBuffer, 1000);
    status = GXQBuf(hDevice, pFrameBuffer); 之间的代码。

    调用GXDQBuf()获取一帧图像,
    调用GXQBuf()将图像buffer放回库中继续采图

    
    #include "GxIAPI.h"
    #include "DxImageProc.h"
    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    //Show error message
    #define GX_VERIFY(emStatus)                \
        if (emStatus != GX_STATUS_SUCCESS)     \
        {                                      \
            GetErrorString(emStatus);          \
            return emStatus;                   \
        }
    
    //Show error message, close device and lib
    #define GX_VERIFY_EXIT(emStatus)           \
        if (emStatus != GX_STATUS_SUCCESS)     \
        {                                      \
            GetErrorString(emStatus);          \
            GXCloseDevice(hDevice);            \
            hDevice = NULL;                    \
            GXCloseLib();                      \
            printf("<App Exit!>\n");           \
            return emStatus;                   \
        }
    
    //Get description of error
    void GetErrorString(GX_STATUS);
    
    int main(int argc, char* argv[])
    {
        GX_STATUS status = GX_STATUS_SUCCESS;
        GX_DEV_HANDLE hDevice = NULL;
        uint32_t nDeviceNum = 0;
    
        //Initialize libary
        status = GXInitLib();
        if (status != GX_STATUS_SUCCESS) {
            GetErrorString(status);
            GXCloseLib();
            return 0;
        }
    
        //Get device enumerated number
        status = GXUpdateDeviceList(&nDeviceNum, 1000);
        if (status != GX_STATUS_SUCCESS) {
            GetErrorString(status);
            GXCloseLib();
            return 0;
        }
    
        //If no device found, app exit
        if(nDeviceNum <= 0) {
            printf("<No device found>\n");
            GXCloseLib();
            return 0;
        }
    
        //Open first device enumerated
        status = GXOpenDeviceByIndex(1, &hDevice);
        if (status != GX_STATUS_SUCCESS) {
            GetErrorString(status);
            GXCloseLib();
            return 0;
        }
    
        //Set acquisition mode
        status = GXSetEnum(hDevice, GX_ENUM_ACQUISITION_MODE, GX_ACQ_MODE_CONTINUOUS);
        GX_VERIFY_EXIT(status);
    
        //Set trigger mode
        status = GXSetEnum(hDevice, GX_ENUM_TRIGGER_MODE, GX_TRIGGER_MODE_OFF);
        GX_VERIFY_EXIT(status);
    
        //Device start acquisition
        status = GXStreamOn(hDevice);
        if(status != GX_STATUS_SUCCESS) {
            GX_VERIFY_EXIT(status);
        }
    
        PGX_FRAME_BUFFER pFrameBuffer = NULL;
        // Grab images
        int image_count = 1500;
        while(image_count--) {       
            // Get a frame from Queue
            status = GXDQBuf(hDevice, &pFrameBuffer, 1000);
            if(status != GX_STATUS_SUCCESS) {
                if (status == GX_STATUS_TIMEOUT) {
                    continue;
                }
                else {
                    GetErrorString(status);
                    break;
                }
            }
    
            if(pFrameBuffer->nStatus != GX_FRAME_STATUS_SUCCESS) {
                printf("<Abnormal Acquisition: Exception code: %d>\n", pFrameBuffer->nStatus);
            }
    
            
            // image process
            int width = pFrameBuffer->nWidth;
            int height = pFrameBuffer->nHeight;
            cout <<"pFrameBuffer size: "<< width <<"x"<<height<<endl;
            cv::Mat image(cv::Size(width, height), CV_8UC1, (void*)pFrameBuffer->pImgBuf);
            
            cv::resize(image, image, cv::Size(width, height) / 2); 
            cv::imshow("image", image);
            cv::waitKey(20);
            // break;
            
    
            // GXQBuf to continue grab image
            status = GXQBuf(hDevice, pFrameBuffer);
            if(status != GX_STATUS_SUCCESS) {
                GetErrorString(status);
                break;
            }  
        } 
    
        //Device stop acquisition
        status = GXStreamOff(hDevice); 
        if(status != GX_STATUS_SUCCESS) {
            GX_VERIFY_EXIT(status);
        }
        
        //Close device
        status = GXCloseDevice(hDevice); 
        if(status != GX_STATUS_SUCCESS) {
            GetErrorString(status);
            hDevice = NULL;
            GXCloseLib();
            return status;
        }
    
        //Release libary
        status = GXCloseLib(); 
        if(status != GX_STATUS_SUCCESS) {
            GetErrorString(status);
            return status;
        }
    
        return 0;
    }
    
    
    
    //----------------------------------------------------------------------------------
    /**
    \brief  Get description of input error code
    \param  emErrorStatus  error code
    
    \return void
    */
    //----------------------------------------------------------------------------------
    void GetErrorString(GX_STATUS emErrorStatus)
    {
        char *error_info = NULL;
        size_t size = 0;
        GX_STATUS emStatus = GX_STATUS_SUCCESS;
        
        // Get length of error description
        emStatus = GXGetLastError(&emErrorStatus, NULL, &size);
        if(emStatus != GX_STATUS_SUCCESS)
        {
            printf("<Error when calling GXGetLastError>\n");
            return;
        }
        
        // Alloc error resources
        error_info = new char[size];
        if (error_info == NULL)
        {
            printf("<Failed to allocate memory>\n");
            return ;
        }
        
        // Get error description
        emStatus = GXGetLastError(&emErrorStatus, error_info, &size);
        if (emStatus != GX_STATUS_SUCCESS)
        {
            printf("<Error when calling GXGetLastError>\n");
        }
        else
        {
            printf("%s\n", (char*)error_info);
        }
    
        // Realease error resources
        if (error_info != NULL)
        {
            delete []error_info;
            error_info = NULL;
        }
    }
    
    

    2.5 编译运行

    在终端执行./generate_demo.sh便会生成build目录并开始cmake和make。
    make 成功之后会在build目录下生成可执行程序 daheng_grab_demo
    进入build目录,运行./daheng_grab_demo,便会实时抓取和显示图像

    3. 参考

    本文是根据下面的博客和大恒使用手册整理而得:

    大恒相机MER-302-56U3M在Linux环境下采集图像
    https://blog.csdn.net/qq_42143583/article/details/102523100

    相关文章

      网友评论

          本文标题:linux下用大恒相机采图

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