Newer
Older
CasicIrisIdentify / device / IrisCameraController.cpp
#include "IrisCameraController.h"

IrisCameraController::IrisCameraController(QObject *parent) : QObject(parent)
{
    initIrisCameraController();
}
IrisCameraController::~IrisCameraController()
{
    this->closeIrisCamera();
}


void IrisCameraController::initIrisCameraController()
{
    // Init GxiApi libary
    GX_STATUS emStatus = GX_STATUS_SUCCESS;
    emStatus = GXInitLib();
    if (emStatus != GX_STATUS_SUCCESS)
    {
        emit irisCameraInitError();
        LOG_ERROR("[CameraController]初始化虹膜相机失败");
        return ;
    }
    LOG_INFO("[CameraController]初始化虹膜相机成功");

    //枚举设备
    UpdateDeviceList();
}

void IrisCameraController::openIrisCamera()
{
    GX_STATUS emStatus = GX_STATUS_SUCCESS;

    if (m_ui32DeviceNum > 0) {
        emStatus = GXOpenDeviceByIndex(1, &m_hDevice);

        if (emStatus == GX_STATUS_SUCCESS) {
            LOG_INFO("[CameraController]开启虹膜相机成功");

            // isOpen flag set true
            m_bOpen = true;

            // 使能采集帧率调节模式
            emStatus = GXSetEnum(m_hDevice, GX_ENUM_ACQUISITION_FRAME_RATE_MODE, GX_ACQUISITION_FRAME_RATE_MODE_ON);

            // 设置采集帧率,假设设置为 10.0,用户按照实际需求设置此值 1000 / 100 = 10
            emStatus = GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, 10.0);

            SetUpAcquisitionThread();
        }
    }

    return;
}

void IrisCameraController::closeIrisCamera()
{
    // Release GxiApi libary
    GX_STATUS emStatus = GX_STATUS_SUCCESS;
    emStatus = GXCloseLib();
    if (emStatus != GX_STATUS_SUCCESS)
    {
        emit irisCameraTermError();
    }
}

void IrisCameraController::startCapture()
{
    // 获取定时器, 绑定定时函数
//    LOG_DEBUG(QString("[IrisCameraController][startCapture]虹膜相机拍图").toStdString());

    bool bSetDone = false;
    // Set acquisition buffer number
    bSetDone = SetAcquisitionBufferNum();
    if (!bSetDone)
    {
        return;
    }

    bool bPrepareDone = false;
    // Alloc resource for image acquisition
    bPrepareDone = m_pobjAcqThread->PrepareForShowImg();
    if (!bPrepareDone)
    {
        return;
    }

    // Device start acquisition and start acquisition thread
    StartAcquisition();

    LOG_DEBUG(QString("[CameraController][startCapture]虹膜相机拍图").toStdString());

    // Do not start timer when acquisition start failed
    if (!m_bAcquisitionStart)
    {
        return;
    }
}
void IrisCameraController::stopCapture()
{
//    LOG_DEBUG(QString("[IrisCameraController][stopCapture]虹膜相机停止拍图").toStdString());
    this->StopAcquisition();
}

void IrisCameraController::SetUpAcquisitionThread()
{
    // if Acquisition thread is on Stop acquisition thread
    if (m_pobjAcqThread != NULL)
    {
        m_pobjAcqThread->m_bAcquisitionThreadFlag = false;
        m_pobjAcqThread->quit();
        m_pobjAcqThread->wait();

        // Release acquisition thread object
        RELEASE_ALLOC_MEM(m_pobjAcqThread);
    }

    // Instantiation acquisition thread
    try
    {
        m_pobjAcqThread = new CAcquisitionThread();
        m_pobjAcqThread->m_hDevice = m_hDevice;
    }
    catch (std::bad_alloc &e)
    {
        QMessageBox::about(NULL, "Allocate memory error", "Cannot allocate memory, please exit this app!");
        RELEASE_ALLOC_MEM(m_pobjAcqThread);
        return;
    }

    return;
}

void IrisCameraController::UpdateDeviceList()
{
    GX_STATUS emStatus = GX_STATUS_SUCCESS;

    // Enumerate Devcie List
    emStatus = GXUpdateDeviceList(&m_ui32DeviceNum, ENUMRATE_TIME_OUT);

    LOG_INFO(QString("[CameraController]枚举虹膜相机成功[%1]").arg(m_ui32DeviceNum).toStdString());

    return;
}

void IrisCameraController::StartAcquisition()
{
    GX_STATUS emStatus = GX_STATUS_SUCCESS;

    emStatus = GXStreamOn(m_hDevice);

    // Set acquisition thread run flag
    m_pobjAcqThread->m_bAcquisitionThreadFlag = true;

    // Acquisition thread start
    m_pobjAcqThread->start();

    // isStart flag set true
    m_bAcquisitionStart = true;

    return;
}

void IrisCameraController::StopAcquisition()
{
    GX_STATUS emStatus = GX_STATUS_SUCCESS;

    m_pobjAcqThread->m_bAcquisitionThreadFlag = false;
    m_pobjAcqThread->quit();
    m_pobjAcqThread->wait();

    // Turn off stream
    emStatus = GXStreamOff(m_hDevice);

    // isStart flag set false
    m_bAcquisitionStart = false;

    return;
}

void IrisCameraController::SetCameraFrameRate(float rate)
{
    GXSetFloat(m_hDevice, GX_FLOAT_ACQUISITION_FRAME_RATE, rate);
}

bool IrisCameraController::SetAcquisitionBufferNum()
{
    GX_STATUS emStatus = GX_STATUS_SUCCESS;
    uint64_t ui64BufferNum = 0;
    int64_t i64PayloadSize = 0;

    // Get device current payload size
    emStatus = GXGetInt(m_hDevice, GX_INT_PAYLOAD_SIZE, &i64PayloadSize);
    if (emStatus != GX_STATUS_SUCCESS)
    {
        return false;
    }

    // Set buffer quantity of acquisition queue
    if (i64PayloadSize == 0)
    {
        return false;
    }

    // Calculate a reasonable number of Buffers for different payload size
    // Small ROI and high frame rate will requires more acquisition Buffer
    const size_t MAX_MEMORY_SIZE = 8 * 1024 * 1024; // The maximum number of memory bytes available for allocating frame Buffer
    const size_t MIN_BUFFER_NUM  = 5;               // Minimum frame Buffer number
    const size_t MAX_BUFFER_NUM  = 450;             // Maximum frame Buffer number
    ui64BufferNum = MAX_MEMORY_SIZE / i64PayloadSize;
    ui64BufferNum = (ui64BufferNum <= MIN_BUFFER_NUM) ? MIN_BUFFER_NUM : ui64BufferNum;
    ui64BufferNum = (ui64BufferNum >= MAX_BUFFER_NUM) ? MAX_BUFFER_NUM : ui64BufferNum;

    emStatus = GXSetAcqusitionBufferNumber(m_hDevice, ui64BufferNum);
    if (emStatus != GX_STATUS_SUCCESS)
    {
        return false;
    }

    // Transfer buffer number to acquisition thread class for using GXDQAllBufs
    m_pobjAcqThread->m_ui64AcquisitionBufferNum = ui64BufferNum;

    return true;
}