linux下用大恒相机采图

2020-03-26  本文已影响0人  book_02

平台: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

上一篇下一篇

猜你喜欢

热点阅读