qt配合映美精取图开发

  1. 最近开发一个项目,用映美精相机配合halcon做取图开发,由于网上资料小特意写个记录。
  2. 到映美精官网下载驱动,映美精官网,下载映美精的工具开发包SDK 映美精的SDK
  3. 下载SDK后找到classlib文件夹

    里面就是SDK
  4. 新建一个qt程序,引入SDK
  5. 新建一个相机类

头文件

cpp 复制代码
#ifndef CAMERAGRAP_H
#define CAMERAGRAP_H

#include <QObject>
#include "QDebug"
#include <tisudshl.h>
#include <algorithm>

/***sink监控***/
class SinkListener : public DShowLib::FrameQueueSinkListener
{
public:
    /***槽链接成功***/
    void    sinkConnected(DShowLib::FrameQueueSink& sink,
                       const DShowLib::FrameTypeInfo& frameType );
    /***取到图片是响应***/
    void framesQueued( DShowLib::FrameQueueSink& sink );
    /***槽链接断开回调***/
    void sinkDisconnected(DShowLib::FrameQueueSink& sink );
};

class CameraGrap : public QObject
{
    Q_OBJECT
public:
    explicit CameraGrap(QObject *parent = nullptr);
    ~CameraGrap();
    /***初始化***/
    void Init();
    /***读取配置***/
    void ReadConfig();
    /***保存配置***/
    bool WriteConfig();
    /***开始相机***/
    void StartCamera();
    /***停止相机***/
    void StopCamera();
    /***释放资源***/
    void ReleaseSource();
    /***设置相机的触发模式为触发取图***/
    void SetCameraTriggerTakeImage();
    /***设置相机试试视频取图***/
    void SetCameraLiveTakeImage();
    /***设置相机曝光***/
    void SetCameraExpource(double expource_);
    /***设置相机增益***/
    void SetCameraGain(double gain_);
    /***触发下相机取图***/
    void TriggerCameraTakeImage();

    // /***槽链接成功***/
    // void    sinkConnected(DShowLib::FrameQueueSink& sink,
    //                    const DShowLib::FrameTypeInfo& frameType );
    // /***取到图片是响应***/
    // void framesQueued( DShowLib::FrameQueueSink& sink );
    // /***槽链接断开回调***/
    // void sinkDisconnected(DShowLib::FrameQueueSink& sink );

    // /***重写取图回调函数***/
    // void frameReady(DShowLib::Grabber& caller, smart_ptr<DShowLib::MemBuffer> pBuffer, DWORD FrameNumber ) override;

    // void overlayCallback(DShowLib::Grabber& caller, smart_ptr<DShowLib::OverlayBitmap> pBitmap, const DShowLib::tsMediaSampleDesc& desc );

signals:
    // /***获取图片完成标志***/
    // void FinallyGetImage();
public:
    static CameraGrap _camer_grap;
    /***相机名称***/
    QString _camera_name;
    /***相机视频的格式***/
    QString _camera_video_format;
    /***相机曝光***/
    double _camera_expource;
    /***相机增益***/
    double _camera_gain;
    /***相机抗干扰数***/
    double _camera_noise_suppression;
    /***相机有无标志***/
    bool _camera_exist;
    /***创建一个抓拍,一定创建成指针形式,不然会跟***/
    DShowLib::Grabber* _grabber;
    // /***sink监控***/
    SinkListener _listener_instance;
    // DShowLib::FrameTypeInfoArray _accepted_types;
    /***接受图片的格式***/
    DShowLib::FrameTypeInfo _accepted_type;
    /***槽***/
    DShowLib::tFrameQueueSinkPtr _psink;
};

#endif // CAMERAGRAP_H

内容文件

cpp 复制代码
#include "cameragrap.h"
#include <DeeplearnInspection/deeplearninspection.h>
#include <QCoreApplication>
#include "xlsxdocument.h"
#include "QMetaMethod"
// #include "ic4-interop/interop-HALCON.h"

CameraGrap CameraGrap::_camer_grap;

void SinkListener::sinkConnected(DShowLib::FrameQueueSink& sink,
                                 const DShowLib::FrameTypeInfo& frameType )
{
    UNREFERENCED_PARAMETER( frameType );
    /***链接成功分配内存***/
    sink.allocAndQueueBuffers(1);
}

void SinkListener::framesQueued(DShowLib::FrameQueueSink& sink)
{
    DShowLib::tFrameQueueBufferPtr buffer = sink.popOutputQueueBuffer();
    //unsigned int frame_number = buffer->getFrameMetaData().mediaSampleDesc.FrameNumber;
    // DShowLib::tColorformatEnum format_= buffer->getFrameType().getColorformat();
    int width_=buffer->getFrameType().dim.cx;
    int height_=buffer->getFrameType().dim.cy;

    // HalconCpp::GenImageInterleaved(&ho_Image, (void*)pBuffer, "rgb", width, height, 0, "byte", width * 3, height, 0, 0);

    HalconCpp::HTuple hptr_=(Hlong)buffer->getPtr();
    HalconCpp::GenImage1(&DeeplearnInspection::_deeplearn_inspection._image,
                         "byte",
                         width_,
                         height_,
                         hptr_);
    DeeplearnInspection::_deeplearn_inspection._image_exist=true;
    hptr_.Clear();

    /***释放内存资源***/
    buffer.destroy();
    int size_input_= sink.getInputQueueSize();
    int size_output_=sink.getOutputQueueSize();

    sink.popAllOutputQueueBuffers().clear();
    sink.popAllInputQueueBuffers().clear();

    /***重新分配内存资源***/
    sink.allocAndQueueBuffers(1);

    size_input_= sink.getInputQueueSize();
    size_output_=sink.getOutputQueueSize();
    /***触发相机取图完成***/
    DeeplearnInspection::_deeplearn_inspection.TriggerCameraImageWriteFinally();
}

void SinkListener::sinkDisconnected(DShowLib::FrameQueueSink& sink)
{
    ;
}

CameraGrap::CameraGrap(QObject *parent)
    : QObject{parent}
{
}

CameraGrap::~CameraGrap()
{
}

void CameraGrap::Init()
{
    /***读取配置***/
    ReadConfig();
    /***初始化相机底层***/
    DShowLib::InitLibrary();
    /***创建一个抓拍***/
    _grabber=new DShowLib::Grabber();
    /***获取相机驱动***/
    auto cameras_= _grabber->getAvailableVideoCaptureDevices();
    /***判断有没有相机***/
    int camera_count_= cameras_->size();
    if(camera_count_>0)
    {
        for(int i=0;i<camera_count_;i++)
        {
            /***获取相机名称***/
            std::string camera_name_;
            camera_name_=cameras_->at(i).getName();
            if(camera_name_==_camera_name.toStdString())
            {
                i=camera_count_;
                if(_grabber->openDev(camera_name_))
                {
                    //_grabber->showVCDPropertyPage();

                    /***设置图片格式***/
                    // _grabber->setVideoFormat("Y800 (1424x712)");
                    DShowLib::dstringa video_format_=_camera_video_format.toStdString();
                    _grabber->setVideoFormat(video_format_);

                    /***设置外部出发***/
                    _grabber->setExternalTrigger(1);

                    /***给如抗误触发参数***/
                    DShowLib::tIVCDAbsoluteValuePropertyPtr noise_suppression_time_ = _grabber->getVCDPropertyInterface<DShowLib::IVCDAbsoluteValueProperty>(DShowLib::VCDID_Trigger, DShowLib::VCDElement_TriggerNoiseSuppressionTime);
                    if(noise_suppression_time_==NULL)
                    {
                        qDebug() << "noise suppression time auto is failed";
                    }
                    else
                    {
                        long max_=noise_suppression_time_->getRangeMax();
                        long min_=noise_suppression_time_->getRangeMin();
                        long cvalue_;
                        cvalue_=noise_suppression_time_->getValue();
                        qDebug() << "noise suppression time is "+QString::number(cvalue_);

                        if((max_>=_camera_noise_suppression)
                            &&(min_<=_camera_noise_suppression))
                        {
                            noise_suppression_time_->setValue(_camera_noise_suppression);
                        }
                        else
                        {
                            noise_suppression_time_->setValue(min_);
                        }
                    }

                    /***设置帧率***/
                    _grabber->setFPS(120);

                    // Enable the overlay bitmap to display the frame counter in the live video.
                    _grabber->setOverlayBitmapPathPosition( DShowLib::ePP_DEVICE );
                    _grabber->getOverlay(DShowLib::ePP_DEVICE )->setEnable( true );

                    // Create a FrameTypeInfoArray data structure describing the allowed color formats.
                    //_accepted_types= DShowLib::FrameTypeInfoArray::createStandardTypesArray();
                    /***设置槽接受图片的格式***/
                    _accepted_type =DShowLib::eY800;
                    // Create the frame sink
                    _psink= DShowLib::FrameQueueSink::create(this->_listener_instance, _accepted_type);

                    // Apply the sink to the grabber.
                    _grabber->setSinkType(_psink);

                    /***设置曝光手动***/
                    DShowLib::tIVCDSwitchPropertyPtr exposure_auto = _grabber->getVCDPropertyInterface<DShowLib::IVCDSwitchProperty>( DShowLib::VCDID_Exposure, DShowLib::VCDElement_Auto);
                    if( exposure_auto == NULL )
                    {
                        qDebug() << "exposure auto is failed";
                    }
                    else
                    {
                        exposure_auto->setSwitch(false);
                    }

                    /***获取曝光的范围,设置相机曝光***/
                    DShowLib::tIVCDRangePropertyPtr exposure_range = _grabber->getVCDPropertyInterface<DShowLib::IVCDRangeProperty>(DShowLib::VCDID_Exposure, DShowLib::VCDElement_Value);
                    if( exposure_range == NULL )
                    {
                        qDebug() << "exposure auto is failed";
                    }
                    else
                    {
                        // std::cout << "Current Exposure range value: " << exposure_range->getValue() << std::endl;
                        // std::cout << "Exposure range range: [" << exposure_range->getRangeMin() << ".." << exposure_range->getRangeMax() << "]" << std::endl;
                        long max_=exposure_range->getRangeMax();
                        long min_=exposure_range->getRangeMin();
                        long cvalue_;
                        cvalue_=exposure_range->getValue();
                        qDebug() << "expource is "+QString::number(cvalue_);

                        if((max_>=_camera_expource)
                            &&(min_<=_camera_expource))
                        {
                            exposure_range->setValue(_camera_expource);
                        }
                        else
                        {
                            exposure_range->setValue(min_);
                        }
                    }

                    // /***确认曝光是否设置成功***/
                    // DShowLib::tIVCDAbsoluteValuePropertyPtr exposure_absolute = _grabber.getVCDPropertyInterface<DShowLib::IVCDAbsoluteValueProperty>( DShowLib::VCDID_Exposure,DShowLib::VCDElement_Value);
                    // if( exposure_absolute == NULL )
                    // {
                    //     qDebug() << "vilation is failed";
                    // }
                    // else
                    // {
                    //     long exposure_= exposure_absolute->getValue();
                    //     qDebug() << "expource is "+QString::number(exposure_);
                    // }

                    /***设置增益手动***/
                    DShowLib::tIVCDSwitchPropertyPtr gain_auto = _grabber->getVCDPropertyInterface<DShowLib::IVCDSwitchProperty>( DShowLib::VCDID_Gain, DShowLib::VCDElement_Auto);
                    if( gain_auto == NULL )
                    {
                        qDebug() << "exposure auto is failed";
                    }
                    else
                    {
                        gain_auto->setSwitch(false);
                    }

                    /***获取增益范围,设置增益***/
                    DShowLib::tIVCDRangePropertyPtr gain_range = _grabber->getVCDPropertyInterface<DShowLib::IVCDRangeProperty>(DShowLib::VCDID_Gain, DShowLib::VCDElement_Value);
                    if( gain_range == NULL )
                    {
                        qDebug() << "exposure auto is failed";
                    }
                    else
                    {
                        long max_=gain_range->getRangeMax();
                        long min_=gain_range->getRangeMin();
                        long cvalue_;
                        cvalue_=gain_range->getValue();

                        if((max_>=_camera_gain)
                            &&(min_<=_camera_gain))
                        {
                            gain_range->setValue(_camera_gain);
                        }
                        else
                        {
                            gain_range->setValue(min_);
                        }
                    }

                    // /***确认曝光是否设置成功***/
                    // DShowLib::tIVCDAbsoluteValuePropertyPtr gain_absolute = _grabber.getVCDPropertyInterface<DShowLib::IVCDAbsoluteValueProperty>( DShowLib::VCDID_Gain,DShowLib::VCDElement_Value);
                    // if( gain_absolute == NULL )
                    // {
                    //     qDebug() << "vilation is failed";
                    // }
                    // else
                    // {
                    //     long gain_= gain_absolute->getValue();
                    //     qDebug() << "gain is "+QString::number(gain_);
                    // }
                    _camera_exist=true;
                }
            }
        }
    }
    else
    {
        _camera_exist=false;
        qDebug() << "no found devices";
    }
}

void CameraGrap::ReadConfig()
{
    QString config_path_=QCoreApplication::applicationDirPath()+"/CameraConfig.xlsx";
    QFile file_(config_path_);
    if(file_.exists())
    {
        QXlsx::Document xlsx_(config_path_);
        if(xlsx_.load())
        {
            int row_count_=xlsx_.dimension().rowCount();
            int column_count_=xlsx_.dimension().columnCount();
            if((row_count_>4)
                &&(column_count_>1))
            {
                _camera_name= xlsx_.cellAt(2,2)->value().toString();
                _camera_expource=xlsx_.cellAt(3,2)->value().toDouble();
                _camera_gain=xlsx_.cellAt(4,2)->value().toDouble();
                _camera_video_format=xlsx_.cellAt(5,2)->value().toString();
                _camera_noise_suppression=xlsx_.cellAt(6,2)->value().toDouble();
            }
            else
            {
                qDebug() << "Failed to load CameraConfig.xlsx file.";
            }
        }
    }
    else
    {
        qDebug() << "CameraConfig.xlsx file is not exist";
    }
    file_.close();
}

bool CameraGrap::WriteConfig()
{
    bool ok_=false;
    QString config_path_=QCoreApplication::applicationDirPath()+"/CameraConfig.xlsx";
    QXlsx::Document xlsx_;
    /***写入抬头***/
    xlsx_.write(1,1,"名称");
    xlsx_.write(1,2,"值");

    xlsx_.write(2,1,"CameraName");
    xlsx_.write(2,2,_camera_name);

    xlsx_.write(3,1,"Expource");
    xlsx_.write(3,2,QString::number(_camera_expource));

    xlsx_.write(4,1,"Gain");
    xlsx_.write(4,2,QString::number(_camera_gain));

    xlsx_.write(5,1,"VideoFormat");
    xlsx_.write(5,2,_camera_video_format);

    xlsx_.write(6,1,"NoiseSuppression");
    xlsx_.write(6,2,_camera_noise_suppression);

    if(!xlsx_.saveAs(config_path_))
    {
        qDebug() << "save the DataCache.xlsx failed";
    }
    else
    {
        ok_=true;
    }
    return ok_;
}

void CameraGrap::StartCamera()
{
    if(_camera_exist==true)
    {
        _grabber->startLive(false);
    }
}

void CameraGrap::StopCamera()
{
    if(_camera_exist==true)
    {
        _grabber->stopLive();
    }
}

void CameraGrap::ReleaseSource()
{
    if(_camera_exist==true)
    {
        if (_grabber->isDevOpen())
        {
            if(_grabber->isLive())
            {
                _grabber->stopLive();
            }
            _grabber->closeDev();
        }
    }
    delete _grabber;
}

void CameraGrap::SetCameraTriggerTakeImage()
{
    if(_camera_exist==true)
    {
        /***设置触发模式为软触发***/
        _grabber->setExternalTrigger(true);
    }
}

void CameraGrap::SetCameraLiveTakeImage()
{
    if(_camera_exist==true)
    {
        /***设置相机直播模式***/
        _grabber->setExternalTrigger(false);
    }
}

void CameraGrap::SetCameraExpource(double expource_)
{
    if(_camera_exist==true)
    {
        _camera_expource =expource_;
        /***获取曝光的范围,设置相机曝光***/
        DShowLib::tIVCDRangePropertyPtr exposure_range = _grabber->getVCDPropertyInterface<DShowLib::IVCDRangeProperty>(DShowLib::VCDID_Exposure, DShowLib::VCDElement_Value);
        if( exposure_range == NULL )
        {
            qDebug() << "exposure auto is failed";
        }
        else
        {
            // std::cout << "Current Exposure range value: " << exposure_range->getValue() << std::endl;
            // std::cout << "Exposure range range: [" << exposure_range->getRangeMin() << ".." << exposure_range->getRangeMax() << "]" << std::endl;
            long max_=exposure_range->getRangeMax();
            long min_=exposure_range->getRangeMin();
            long cvalue_;
            cvalue_=exposure_range->getValue();
            qDebug() << "expource is "+QString::number(cvalue_);

            if((max_>_camera_expource)
                &&(min_<_camera_expource))
            {
                exposure_range->setValue(_camera_expource);
            }
            else
            {
                exposure_range->setValue(min_);
            }
        }
    }
}

void CameraGrap::SetCameraGain(double gain_)
{
    if(_camera_exist==true)
    {
        _camera_gain=gain_;
        DShowLib::tIVCDRangePropertyPtr gain_range = _grabber->getVCDPropertyInterface<DShowLib::IVCDRangeProperty>(DShowLib::VCDID_Gain, DShowLib::VCDElement_Value);
        if( gain_range == NULL )
        {
            qDebug() << "exposure auto is failed";
        }
        else
        {
            long max_=gain_range->getRangeMax();
            long min_=gain_range->getRangeMin();
            long cvalue_;
            cvalue_=gain_range->getValue();

            if((max_>_camera_gain)
                &&(min_<_camera_gain))
            {
                gain_range->setValue(_camera_gain);
            }
            else
            {
                gain_range->setValue(min_);
            }
        }
    }
}

void CameraGrap::TriggerCameraTakeImage()
{
    if(_camera_exist==true)
    {
        DShowLib::tIVCDButtonPropertyPtr btn_= _grabber->getVCDPropertyInterface<DShowLib::IVCDButtonProperty>(DShowLib::VCDID_TriggerMode, DShowLib::VCDElement_SoftwareTrigger);
        if(btn_==NULL)
        {
        }
        else
        {
            btn_->push();
        }
    }
}

// void CameraGrap::frameReady(DShowLib::Grabber& caller,smart_ptr<DShowLib::MemBuffer> pBuffer,DWORD FrameNumber)
// {
//     // int width_=pBuffer->getFrameType().dim.cx;
//     // int height_=pBuffer->getFrameType().dim.cy;

//     // uchar* ptr_=static_cast<uchar*>(pBuffer->getPtr());
//     // HalconCpp::HTuple hptr_=(int)ptr_;

//     // HalconCpp::GenImage1(&DeeplearnInspection::_deeplearn_inspection._image,
//     //                      "byte",
//     //                      width_,
//     //                      height_,
//     //                      hptr_);
//     // hptr_.Clear();

//     // QMetaMethod value_change_signal_=QMetaMethod::fromSignal(&CameraGrap::FinallyGetImage);
//     // if(this->isSignalConnected(value_change_signal_))
//     // {
//     //     emit FinallyGetImage();
//     // }
//     ;
// }

// void CameraGrap::overlayCallback(DShowLib::Grabber& caller,
//                                  smart_ptr<DShowLib::OverlayBitmap> pBitmap,
//                                  const DShowLib::tsMediaSampleDesc& desc)
// {

// }

6.代码分析

要获取相机的图片,主要创建一个类继承public DShowLib::FrameQueueSinkListener,

然后设置sink,代码如下:

// Create the frame sink

_psink= DShowLib::FrameQueueSink::create(this->_listener_instance, _accepted_type);

// Apply the sink to the grabber.

_grabber->setSinkType(_psink);

在相机取到图片后会回调sink,即回调framesQueued函数,在里面进行转换。

相关推荐
上趣工作室14 分钟前
uniapp中使用全局样式文件引入的三种方式
开发语言·rust·uni-app
提笔惊蚂蚁20 分钟前
java-web-苍穹外卖-day1:软件开发步骤简化版+后端环境搭建
java·开发语言·前端·程序人生
Ethan Hunt丶20 分钟前
C语言实现IIR型零相位带通滤波器
c语言·开发语言·算法
liang081141 小时前
C# DataTable使用Linq查询详解
开发语言·c#
爱吃糖的范同学1 小时前
【前端学习指南】第三站 Vue 组件之间通信
开发语言·前端·javascript·vue.js·前端框架·ecmascript
Ni-Guvara1 小时前
对象优化及右值引用优化(四)
开发语言·c++
安杰爱编程1 小时前
Python讲解(第六篇)
开发语言·python
许野平1 小时前
Rust:GUI 开源框架
开发语言·后端·rust·gui
呼啦啦啦啦啦啦啦啦2 小时前
【Java多线程】wait方法和notify方法
java·开发语言
刘翔在线犯法2 小时前
Scala的迭代器
开发语言·后端·scala