3:QT联合HALCON编程—海康相机SDK二次程序开发

news2025/7/17 14:52:06

思路:

1.定义带UI界面的主函数类

         1.1在主函数中包含其它所有类头文件,进行声明和实例化;使用相机时,是用公共相机的接口在某一个具体函数中去实例化具体的海康相机对象。

        1.2设计界面:连接相机,单次采集,连续采集,停止采集,关闭相机

        1.3在连续采集中,开始启用线程。需要在线程类中采集图像,通过信号与槽在主函数中接收并显示图像。

2.定义公共相机接口类

3.定义海康相机类

4.定义线程类

        4.1里面包含:接收海康相机的函数,在主函数中可以直接调用线程里面的这个函数,并通过指针传参。

        4.2定义run函数,在函数里面采集图像,并发送信号。

         4.3定义if语句判断线程状态,控制线程启停。

        4.4定义bool变量去结合if进行判断

5.定义日志类

6.定义加载保存参数,公共结构体类

7.定义其它图像处理功能类

        7.1例如:测量,匹配,检测等...............


1.主目录框架

列表中含有:

1.src里面是图像处理的各种模块功能以及公共文件(日志和参数加载)

2.相机的公共接口类

3.Halcon类

4.海康相机类

5.主函数

6.线程类


2.定义公共相机接口(camerainterface)

camerainterface.h

#ifndef CAMERAINTERFACE_H
#define CAMERAINTERFACE_H

#include "HalconCpp.h"
#include "HDevThread.h"
using namespace HalconCpp;
#include"iostream"
class CameraInterface
{
public:
    CameraInterface();
    ~CameraInterface();


        //关闭相机采集 // ch:连接设备
        virtual int connectCamera(int id)=0;

        //设置是否为触发模式
        virtual int setTriggerMode(unsigned int TriggerModeNum)=0;

        //开启相机采集
        virtual int startCamera()=0;

        virtual int stopCamera()=0;

        //关闭相机
        virtual int closeCamera()=0;

        //软触发
        virtual int softTrigger()=0;

        //读取buffer
        virtual int ReadBuffer(HObject &image)=0;

        //设置图像高度
        virtual int setHeight(unsigned int height)=0;

        //设置图像ROI宽度
        virtual int setWidth(unsigned int width)=0;

        //获取图像高度值
        virtual int getHeight()=0;

        //获取图像宽度值
        virtual int getWidth()=0;

        //获取相机曝光时间
        virtual float getExposureTime()=0;

        //设置图像水平偏移OffsetX
        virtual int setOffsetX(unsigned int offsetX)=0;

        //设置图像竖直偏移OffsetY
        virtual int setOffsetY(unsigned int offsetY)=0;

        //设置触发源
        virtual int setTriggerSource(unsigned int TriggerSourceNum)=0;

        //设置帧率控制使能
        virtual int setFrameRateEnable(bool comm)=0;

        //设置心跳时间
        virtual int setHeartBeatTime(unsigned int time)=0;

        //设置曝光时间
        virtual int setExposureTime(float ExposureTimeNum)=0;

        //设置增益
        virtual int setGain(float Gain)=0;

        //关闭自动曝光
        virtual int setExposureAuto(bool exposureAutoFlag)=0;

        //关闭自动增益
        virtual int setGainAuto(bool gainAutoFlag)=0;

        //virtual int setGain(float Gain)=0;
        //清理相机缓存
        virtual void clearBuffer()=0;
};

#endif // CAMERAINTERFACE_H

3.定义海康相机类(hikvisionsdk)

1.hikvisionsdk.h文件,海康相机功能函数声明(包含公共相机头文件)

#ifndef HIKVISIONSDK_H
#define HIKVISIONSDK_H
#include"camerainterface.h"
#include"MvCameraControl.h"
#include "HalconCpp.h"
#include "HDevThread.h"
#include <QImage>
using namespace HalconCpp;
class HikvisionSDK:public CameraInterface
{
public:
    HikvisionSDK();
    ~HikvisionSDK();

    // ch:连接设备
    //int connectCamera(std::string id);
    int connectCamera(int id);


    //设置是否为触发模式
    int setTriggerMode(unsigned int TriggerModeNum);

    //开启相机采集
    int startCamera();

    //关闭相机采集
    int stopCamera();

    //关闭相机
    int closeCamera();

    //软触发
    int softTrigger();

    //读取buffer
    int ReadBuffer(HObject &image);


    //设置图像高度
    int setHeight(unsigned int height);

    //设置图像ROI宽度
    int setWidth(unsigned int width);

    //获取图像高度值
    int getHeight();

    //获取图像宽度值
    int getWidth();

    //获取相机曝光时间
    float getExposureTime();

    //设置图像水平偏移OffsetX
    int setOffsetX(unsigned int offsetX);

    //设置图像竖直偏移OffsetY
    int setOffsetY(unsigned int offsetY);

    //设置触发源
    int setTriggerSource(unsigned int TriggerSourceNum);

    //设置帧率控制使能
    int setFrameRateEnable(bool comm);

    //设置心跳时间
    int setHeartBeatTime(unsigned int time);

    //设置曝光时间
    int setExposureTime(float ExposureTimeNum);

    //设置增益
    int  setGain(float Gain);
    //关闭自动曝光
    int setExposureAuto(bool exposureAutoFlag);

    //关闭自动增益
    int setGainAuto(bool gainAutoFlag);

    //清理相机缓存
    void clearBuffer();

    bool QImage2HObject(QImage &qImg, HObject &hImg);

private:
    void*         m_hDevHandle;
public:
    // 用于保存图像的缓存
    unsigned int    m_nBufSizeForSaveImage;
    // 用于从驱动获取图像的缓存
    unsigned int    m_nBufSizeForDriver;
};

#endif // HIKVISIONSDK_H

2.hikvisionsdk.cpp文件(海康相机各功能实现)

在读图相机中图像函数里面有个事件,此时需要找到自己相机的型号才能执行,要不然程序容易闪退

#include "hikvisionsdk.h"

MV_CC_DEVICE_INFO_LIST m_stDevList;         // ch:设备信息列表结构体变量,用来存储设备列表
MV_CC_DEVICE_INFO* m_Device=NULL;                 //设备对象

#include <QDebug>
#include <QString>
#include <QDebug>
HikvisionSDK::HikvisionSDK()
{
    m_hDevHandle    = NULL;
}

HikvisionSDK::~HikvisionSDK()
{
    if (m_hDevHandle)
    {
        MV_CC_DestroyHandle(m_hDevHandle);
        m_hDevHandle    = NULL;
    }
}

//连接相机
int  HikvisionSDK::connectCamera(int id)
{
    // Enum device
    MV_CC_DEVICE_INFO_LIST stDeviceList;
    memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
    int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);
    if (nRet!=0)
    {
         qDebug()<<"nRet:="<<nRet;
         return -1;
    }
    if (stDeviceList.nDeviceNum > 0)
    {
        for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++)
        {
            MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];
            if (NULL == pDeviceInfo)
            {
                break;
            }
        }
    }
    else
    {

        return -1;
    }
    unsigned int nIndex = 0;
    // Select device and create handle
    nRet = MV_CC_CreateHandle(&m_hDevHandle, stDeviceList.pDeviceInfo[nIndex]);
    if (nRet!=0)
    {
        //printf("Create Handle fail! nRet [0x%x]\n", nRet);
        return -1;
    }

    // open device
    nRet = MV_CC_OpenDevice(m_hDevHandle);
    if (nRet!=0)
    {
        //printf("Open Device fail! nRet [0x%x]\n", nRet);
        return -1;
    }

    return 0;
}



//启动相机采集
int HikvisionSDK::startCamera()
{
    int tempValue=MV_CC_StartGrabbing(m_hDevHandle);
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return 0;
    }
}

//停止相机采集
int HikvisionSDK::stopCamera()
{
    int tempValue=MV_CC_StopGrabbing(m_hDevHandle);
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return 0;
    }
}

//关闭相机
int HikvisionSDK::closeCamera()
{
    if (NULL == m_hDevHandle)
    {
        return -1;
    }
    MV_CC_CloseDevice(m_hDevHandle);
    int tempValue = MV_CC_DestroyHandle(m_hDevHandle);
    m_hDevHandle = NULL;
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return 0;
    }
}

//发送软触发
int HikvisionSDK::softTrigger()
{
    int tempValue= MV_CC_SetCommandValue(m_hDevHandle, "TriggerSoftware");
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return 0;
    }
}

//读取相机中的图像
int HikvisionSDK::ReadBuffer(HObject &halconImage)
{
    //Mat* getImage=new Mat();
    unsigned int nRecvBufSize = 0;
    MVCC_INTVALUE stParam;
    qDebug()<<"enter3";
    memset(&stParam, 0, sizeof(MVCC_INTVALUE));
    int tempValue = MV_CC_GetIntValue(m_hDevHandle, "PayloadSize", &stParam);
    qDebug()<<"enter4";
    if (tempValue != 0)
    {
        return -1;
    }

    //分配一个指针的内存大小 ,  c语言的库函数  malloc;
    nRecvBufSize = stParam.nCurValue;
    //指针  图像接收数据的指针
    unsigned char* pDate;
    pDate=(unsigned char *)malloc(nRecvBufSize);
    qDebug()<<"enter41";

    //句柄  指针   nRecvBufSize  700 ,  输出  (指针和图像信息的结构体)stImageInfo。
    MV_FRAME_OUT_INFO_EX stImageInfo = {0};
    tempValue= MV_CC_GetOneFrameTimeout(m_hDevHandle, pDate, nRecvBufSize, &stImageInfo, 700);
    if(tempValue!=0)
    {
        return -1;
    }
//    m_nBufSizeForSaveImage = stImageInfo.nWidth * stImageInfo.nHeight * 3 + 2048;
//    unsigned char* m_pBufForSaveImage;
//    m_pBufForSaveImage = (unsigned char*)malloc(m_nBufSizeForSaveImage);
    qDebug()<<"enter42";

    bool isMono;
    //HObject halconImage;
    //stImageInfo.enPixelType
    //像素格式  的  stImageInfo  ,switch  调整,
    switch (stImageInfo.enPixelType)
    {
    case PixelType_Gvsp_Mono8:
    case PixelType_Gvsp_Mono10:
    case PixelType_Gvsp_Mono10_Packed:
    case PixelType_Gvsp_Mono12:
    case PixelType_Gvsp_Mono12_Packed:
     case      17301512:
        isMono=true;
        break;
    default:
        isMono=false;
        break;
    }
    if(isMono)
    {
        //*getImage=Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC1,pDate);
        //imwrite("d:\\测试opencv_Mono.tif", image);
        qDebug()<<" stImageInfo.nHeight:"<< stImageInfo.nHeight;
        qDebug()<<" stImageInfo.nWidth:"<< stImageInfo.nWidth;
        qDebug()<<"pDate:"<<pDate;
        GenImage1(&halconImage, "byte", stImageInfo.nWidth,stImageInfo.nHeight,(Hlong)(pDate));//转换为hoject
//        GenImage1(&hImg, "byte", tFrameInfo.iWidth, tFrameInfo.iHeight, (Hlong)m_pchImgBuffer[camId]);
//         qDebug()<<"pDate11:"<<pDate;
        //WriteImage(halconImage, "png", 0, "./picture/halcon_Mono.png");
    }
    else
    {
        //转换图像格式为BGR8
        MV_CC_PIXEL_CONVERT_PARAM stConvertParam = {0};
        memset(&stConvertParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));
        stConvertParam.nWidth = stImageInfo.nWidth;                 //ch:图像宽 | en:image width
        stConvertParam.nHeight = stImageInfo.nHeight;               //ch:图像高 | en:image height
        //stConvertParam.pSrcData = m_pBufForDriver;                  //ch:输入数据缓存 | en:input data buffer
        stConvertParam.pSrcData = pDate;                  //ch:输入数据缓存 | en:input data buffer
        stConvertParam.nSrcDataLen = stImageInfo.nFrameLen;         //ch:输入数据大小 | en:input data size
        stConvertParam.enSrcPixelType = stImageInfo.enPixelType;    //ch:输入像素格式 | en:input pixel format
        stConvertParam.enDstPixelType = PixelType_Gvsp_BGR8_Packed; //ch:输出像素格式 | en:output pixel format  适用于OPENCV的图像格式
        //stConvertParam.enDstPixelType = PixelType_Gvsp_RGB8_Packed; //ch:输出像素格式 | en:output pixel format
        //stConvertParam.pDstBuffer = m_pBufForSaveImage;                    //ch:输出数据缓存 | en:output data buffer
        stConvertParam.nDstBufferSize = m_nBufSizeForSaveImage;            //ch:输出缓存大小 | en:output buffer size
        MV_CC_ConvertPixelType(m_hDevHandle, &stConvertParam);


        QImage img = QImage((const uchar*)pDate,  stImageInfo.nWidth,stImageInfo.nHeight, QImage::Format_RGB888);
        QImage2HObject(img, halconImage);
        //QImage2HObject(img, hImg);
        //halconImage  输出  rgb   hobject 格式的图像 。
        //因为 这里没有 图片 输出  所以 代码就奔溃了。



        //*getImage=Mat(stImageInfo.nHeight,stImageInfo.nWidth,CV_8UC3,m_pBufForSaveImage);
        //imwrite("d:\\测试opencv_Color.tif", image);
    }

    //CopyImage(halconImage, &image);
    free(pDate);
    //free(m_pBufForSaveImage);
    return 0;
}


//Qimage  转换成 hobject image
bool HikvisionSDK::QImage2HObject(QImage &qImg, HObject &hImg)
{
    try
    {
        if (qImg.isNull()) return false;
        int width = qImg.width();
        int height = qImg.height();
        QImage::Format format = qImg.format();
        if (format == QImage::Format_RGB32 ||
            format == QImage::Format_ARGB32 ||
            format == QImage::Format_ARGB32_Premultiplied)
        {
            GenImageInterleaved(&hImg, Hlong(qImg.bits()), "bgrx", width, height, 0, "byte", width, height, 0, 0, 8, 0);
        }
        else if (format == QImage::Format_RGB888)
        {
            GenImageInterleaved(&hImg, Hlong(qImg.bits()), "bgr", width, height, 0, "byte", width, height, 0, 0, 8, 0);
        }
        else if (format == QImage::Format_Grayscale8 || format == QImage::Format_Indexed8)
        {
            GenImage1Extern(&hImg, "byte", width, height, Hlong(qImg.bits()), NULL);
        }
    }
    catch (const std::exception&)
    {
        return false;
    }
    return true;
}


//获取图像高度值
int HikvisionSDK::getHeight()
{
    MVCC_INTVALUE stParam;
    memset(&stParam, 0, sizeof(MVCC_INTVALUE));
    int tempValue=MV_CC_GetIntValue(m_hDevHandle, "Height", &stParam);
    int value= stParam.nCurValue;
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return value;
    }
}

//获取图像宽度值
int HikvisionSDK::getWidth()
{
    MVCC_INTVALUE stParam;
    memset(&stParam, 0, sizeof(MVCC_INTVALUE));
    int tempValue=MV_CC_GetIntValue(m_hDevHandle, "Width", &stParam);
    int value= stParam.nCurValue;
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return value;
    }
}

//获取相机曝光时间
float HikvisionSDK::getExposureTime()
{
    MVCC_FLOATVALUE stParam;
    memset(&stParam, 0, sizeof(MVCC_INTVALUE));
    int tempValue=MV_CC_GetFloatValue(m_hDevHandle, "ExposureTime", &stParam);
    float value= stParam.fCurValue;
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return value;
    }
}

//设置图像ROI高度
int HikvisionSDK::setHeight(unsigned int height)
{
    int tempValue=MV_CC_SetIntValue(m_hDevHandle, "Height", height);
    if(tempValue!=0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//设置图像ROI宽度
int HikvisionSDK::setWidth(unsigned int width)
{
    int tempValue=MV_CC_SetIntValue(m_hDevHandle, "Width", width);
    if(tempValue!=0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//设置图像水平偏移OffsetX
int HikvisionSDK::setOffsetX(unsigned int offsetX)
{
    int tempValue=MV_CC_SetIntValue(m_hDevHandle, "OffsetX", offsetX);
    if(tempValue!=0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//设置图像竖直偏移OffsetY
int HikvisionSDK::setOffsetY(unsigned int offsetY)
{
    int tempValue=MV_CC_SetIntValue(m_hDevHandle, "OffsetY", offsetY);
    if(tempValue!=0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//设置是否为触发模式
int HikvisionSDK::setTriggerMode(unsigned int TriggerModeNum)
{
     //0:Off  1:On
     int tempValue= MV_CC_SetEnumValue(m_hDevHandle,"TriggerMode", TriggerModeNum);
     if(tempValue!=0)
     {
         return -1;
     }else
     {
         return 0;
     }
}

//设置触发源
int HikvisionSDK::setTriggerSource(unsigned int TriggerSourceNum)
{
    //0:Line0  1:Line1  7:Software
    int tempValue= MV_CC_SetEnumValue(m_hDevHandle,"TriggerSource", TriggerSourceNum);
    if(tempValue!=0)
    {
        return -1;
    }else
    {
        return 0;
    }
}

//设置帧率控制使能
int HikvisionSDK::setFrameRateEnable(bool comm)
{
    int tempValue =MV_CC_SetBoolValue(m_hDevHandle, "AcquisitionFrameRateEnable", comm);
    if (tempValue != 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//设置心跳时间
int HikvisionSDK::setHeartBeatTime(unsigned int time)
{
    //心跳时间最小为500ms
    if(time<500)
        time=500;
    int tempValue=MV_CC_SetIntValue(m_hDevHandle, "GevHeartbeatTimeout", time);
    if(tempValue!=0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//设置曝光时间
int HikvisionSDK::setExposureTime(float ExposureTimeNum)
{
    int tempValue= MV_CC_SetFloatValue(m_hDevHandle, "ExposureTime",ExposureTimeNum );
    if(tempValue!=0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}


//设置曝光时间
int HikvisionSDK::setGain(float Gain)
{
    int tempValue= MV_CC_SetFloatValue(m_hDevHandle, "Gain",Gain);
    if(tempValue!=0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//关闭自动曝光
int HikvisionSDK::setExposureAuto(bool exposureAutoFlag)
{
    int tempValue= MV_CC_SetEnumValue(m_hDevHandle,"ExposureAuto", exposureAutoFlag);
    if (tempValue != 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//关闭自动增益
int HikvisionSDK::setGainAuto(bool gainAutoFlag)
{
    int tempValue= MV_CC_SetEnumValue(m_hDevHandle,"GainAuto", gainAutoFlag);
    if (tempValue != 0)
    {
        return -1;
    }
    else
    {
        return 0;
    }
}

//清理相机缓存
void HikvisionSDK::clearBuffer()
{
    //stopCamera();
    //startCamera();
}

4.在主程序相机实例化

1.首先包含公共相机和海康相机的头文件

2.用公共相机接口去实例化海康相机

.h主文件

private: 
//相机指针
    CameraInterface * camera=NULL;

.cpp主文件

  camera=new HikvisionSDK();用公共相机接口实例化海康相机类

析构函数中


    if(camera!=NULL)
    {
        delete camera;
        camera=NULL;
    }

5.连接相机

1.在IU界面下添加连接相机按钮转到槽函数

//连接相机
void MainWindow::on_btn_Connect_clicked()
{
     //初始化相机句柄
    if(camera!=NULL)
    {
        delete camera;
        camera=NULL;
    }

    qDebug()<<111;
    if(camera==NULL)
    {
          qDebug()<<112;
          InitCam();//连接相机函数

         //控制按钮是否可以按下
          ui->btn_Close->setEnabled(false);
          ui->btn_Connect->setEnabled(false);
          ui->btn_Trigger->setEnabled(true);
          ui->lxcj->setEnabled(true);
          ui->StopAcquisition->setEnabled(true);
    }

}

2.连接相机函数实现

注意:次函数是实例化具体的相机(因为在项目中可能用到不同类型的相机,所以在头文件首先用公共相机接口)然后在具体的连接相机下面去实例化具体的相机类型对象。

  最后一行程序,是把这个具体的海康相机对象通过传参,传入到线程类中去。

void MainWindow::InitCam()
{
    camera=new HikvisionSDK();此时用到了上面提到的海康相机实例化
    //连接相机
    //std::cout<<"Connect:  "<<camera->connectCamera(1)<<std::endl;
    int  ret=camera->connectCamera(1);
    if(ret!=0)
    {
        //失败
        //QMessageBox::warning()
    }

    //设置为触发模式  打开
    std::cout<<"TriggerMode:  "<<camera->setTriggerMode(1)<<std::endl;
    //设置触发源为软触发
    std::cout<<"TriggerSource:  "<<camera->setTriggerSource(7)<<std::endl;
    //设置曝光时间
    std::cout<<"SetExposureTime:  "<<camera->setExposureTime(40000)<<std::endl;
    //开启相机采集
    std::cout<<"StartCamera:  "<<camera->startCamera()<<std::endl;



    myThread->getCameraPtr(camera);//把实例化后的海康相机类传入到线程中去
  //myThread->getImagePtr(myImage);
    
}

6.定义线程类(mythread)

1.在线程里面需要包含公共相机的头文件

#include "QThread"//线程
#include "camerainterface.h"//公共相机接口
#include <QImage>

2.头文件定义接收海康相机类的函数

    void getCameraPtr(CameraInterface* camera);

3..cpp文件具体实现

//析构函数
MyThread::~MyThread()
{
    if(cameraPtr==NULL)
    {
        delete cameraPtr;
    }
}



//具体实现
void MyThread::getCameraPtr(CameraInterface *camera)
{
    cameraPtr=camera;
}

7.单次采集

1.在IU界面添加单次采集按钮转跳槽函数

2.需要在主头文件中,private: 下面去声明 bool IsRun = false;(目的是为了更好的调节相机采图启停,方便后续操作(在这里可以不用))

3.转到线程中,去执行停止线程工作内容(因为单次采集不需要启动线程)

//单次采集
void MainWindow::on_btn_Trigger_clicked()
{
        HObject image;
      HTuple hv_Width,hv_Height;
        IsRun =true;//单次采图状态
      
        myThread->ChangeCloseStatus();//线程状态启停
        std::cout<<"TriggerMode:  "<<camera->setTriggerMode(1)<<std::endl;
        std::cout<<"SoftTrigger:  "<<camera->softTrigger()<<std::endl;
        //读取Mat格式的图像
        qDebug()<<"enter1";
        camera->ReadBuffer(image);   //相机类里面的读图函数
        CopyImage(image, &halconImage);
        if(ui->checkBox_saveImage->isChecked())
        {
           //保存图像
         QString path="./data/"+QString::number(ui->sB_Num->value())+".png";
         WriteImage(halconImage, "png", 0, HTuple(path.toLatin1().data()));
        }
             GetImageSize(image, &hv_Width, &hv_Height);
              SetPart(WindowHandle, 0, 0, hv_Height,hv_Width); // 1944 2592
        qDebug()<<"enter2";
        DispObj(halconImage, WindowHandle);
         //其它图像处理功能
        //m_pMeasure01->OutMeasure01(halconImage);
}

4.在线程类中,.h的public:下定义 bool Status=false;

同时定义线程状态启停函数

    void ChangeCloseStatus();//关闭
    void ChangeOpenStatus();//打开






.cpp文件


void MyThread::ChangeCloseStatus()
{
    Status=false;
    //qDebug()<<"Status:="<<Status;
}

void MyThread::ChangeOpenStatus()
{
    Status=true;
    //qDebug()<<"Status:="<<Status;
}


8.连续采集

1.此时需要利用线程进行连续图像采集,需要在主程序中实例化线程类(应该在一开始就实例化)

    //线程对象
    MyThread* myThread=NULL;
   //  线程对象实例化
      myThread = new MyThread();
    if(myThread!=NULL)
    {
        delete myThread;
        myThread=NULL;
    }

2.在IU界面上添加连续采集按钮转到槽函数

void MainWindow::on_lxcj_clicked()
{

   std::cout<<"TriggerMode:  "<<camera->setTriggerMode(0)<<std::endl;

   myThread->ChangeOpenStatus();//打开线程工作内容

    if(!IsRun)//判断单次采集是否打开
    {
          IsRun = false;关闭单次采集
        myThread->start();//开启连续彩图线程
       
    }
    else
    {
          IsRun = false;//关闭单次采集
        myThread->start();//开启连续彩图线程
      
    }
}

3.在线程类里面

.h文件

    void run();//定义run函数(线程里的工作内容)


  void display( HObject imagePtr);//(用来其它作用显示)


signals:
    void CaptureImage(HObject);//定义一个发送图像的信号

.cpp文件

void MyThread::run()
{
    if(cameraPtr==NULL)
    {
        return;
    }
    while(!isInterruptionRequested())
    {
       if(Status)  //判断是否停止的状态
        {
           qDebug()<<"thread current" <<currentThread();
           std::cout<<"Thread_Trigger:"<<cameraPtr->softTrigger()<<std::endl;

           HObject image;
           //读取Mat格式的图像
           cameraPtr->ReadBuffer(image);
        
           emit CaptureImage(image);//发送图像信号
           msleep(100);
         
        }
    }
}
void MyThread::display( HObject imagePtr)
{
    //qDebug()<<"Enter2";
    //std::cout<<"so"<<std::endl;
    //判断是黑白、彩色图像
    DispObj((imagePtr), WindowHandle);
    QString path="./picture/halcon"+QString::number(1)+".png";
    //WriteImage((*imagePtr), "png", 0, HTuple(path.toLatin1().data()));
    //int num=ui->sB_Num->value();
    //ui->sB_Num->setValue(num+1);
}

4.在线程中发送图像信号之后,需要在主函数中去接收这个图像信号

 //信号与槽
 connect(myThread,SIGNAL(CaptureImage(HObject)),this,SLOT(ImageProcess01(HObject)),\
             Qt::BlockingQueuedConnection);//信号槽函数   。必须display  是slot
private slots:

    //显示连续图像,接收槽函数
    void ImageProcess01(HObject image); //信号槽函数  --收到图像之后的  图像处理槽函数

//槽函数接收显示图像
void MainWindow::ImageProcess01(HObject halconImage)
{
    HTuple hv_Width,hv_Height;

    qDebug()<<"Enter1";
    GetImageSize(halconImage, &hv_Width, &hv_Height);
    SetPart(WindowHandle, 0, 0, hv_Height,hv_Width); // 1944 2592
    display(halconImage);
    m_pMeasure01->OutMeasure01(halconImage);  //输出一个宽度
    //tuple -length  ,length ==1   识别 成功
    //TCP  服务器 发给客户端  ,一个字符串。
    myThread->ChangeOpenStatus();//采图   收到图像处理完的信号,可以启动继续采图。同步采集!
    qDebug()<<"Enter2";

}

9.停止采集

void MainWindow::on_StopAcquisition_clicked()
{
    myThread->ChangeCloseStatus();//停止线程状态
          ui->btn_Close->setEnabled(true);
    if(IsRun)
    {
        myThread->requestInterruption();
        myThread->wait();//线程等待

        IsRun =false;//单次采集关闭
       // camera->stopCamera();
       // camera->closeCamera();
    }
}

10.关闭相机

void MainWindow::on_btn_Close_clicked()
{
        ui->btn_Trigger->setEnabled(false);
        ui->lxcj->setEnabled(false);
        ui->StopAcquisition->setEnabled(false);




    if(camera!=NULL)
    {
        myThread->requestInterruption();
         camera->closeCamera();
    }
    //ui->Image_Label->clear();
    ui->btn_Connect->setEnabled(true);

}

11.保存图像

void MainWindow::on_saveImage_clicked()
{
    QString filePath ="./data/picture/"+ QDateTime::currentDateTime().toString("yyyy-MM-dd");
    HTuple file1=HTuple(filePath.toStdString().c_str());
    WriteImage(halconImage, "bmp", 0, file1);
    //ui->textBrowser_log->append("write image success.");
}

12.设置曝光、增益

//曝光
void MainWindow::on_pB_exposTime_clicked()
{
    int exposTime=ui->sB_exposure->value();
    int ret=camera->setExposureTime(exposTime);
    qDebug()<<"ret:="<<ret;
}



//增益
void MainWindow::on_pB_setGain_clicked()
{
    int Gain =ui->sB_Gain->value();
    int ret=camera->setGain(Gain);
    qDebug()<<"ret:="<<ret;
}

13.保存参数

//把界面的参数  固化 到 本地文件
void Measure01::on_pB_saveParameters_clicked()
{
    /*
    AmplitudeThreshold = 23;
    RoiWidthLen = 67;
    Alpha1 = 3.4;

    LineRowStart = 879.281;
    LineColumnStart = 1436.34;
    LineRowEnd = 1769.58;
    LineColumnEnd = 3055.55;
    */

   //把界面的参数 赋值 给局部作用域的变量
   MeasureParam01.AmplitudeThreshold=ui->SpinBox_AmpThre->value();
   MeasureParam01.Alpha1=ui->SpinBox_Alpha1->value();
   MeasureParam01.RoiWidthLen=ui->SpinBox_RoiWidthLen->value();
   MeasureParam01.LineRowStart=ui->SpinBox_LineRowStart->value();
   MeasureParam01.LineColumnStart=ui->SpinBox_LineColumnStart->value();
   MeasureParam01.LineRowEnd=ui->SpinBox_LineRowEnd->value();
   MeasureParam01.LineColumnEnd=ui->SpinBox_LineColumnEnd->value();
   //再通过qsetting的方法 把参数保存到qt 本地的 文件中去
   SaveSetting(CONFIG_FILEPATH,"Measure01","AmplitudeThreshold",\
                            QVariant(MeasureParam01.AmplitudeThreshold));//AmpThre
   SaveSetting(CONFIG_FILEPATH,"Measure01","Alpha1",\
                            QVariant(MeasureParam01.Alpha1));//AmpThre
   SaveSetting(CONFIG_FILEPATH,"Measure01","RoiWidthLen",\
                            QVariant(MeasureParam01.RoiWidthLen));//AmpThre

   SaveSetting(CONFIG_FILEPATH,"Measure01","LineRowStart",\
                            QVariant(MeasureParam01.LineRowStart));//AmpThre
   SaveSetting(CONFIG_FILEPATH,"Measure01","LineColumnStart",\
                            QVariant(MeasureParam01.LineColumnStart));//AmpThre
   SaveSetting(CONFIG_FILEPATH,"Measure01","LineRowEnd",\
                            QVariant(MeasureParam01.LineRowEnd));//AmpThre
   SaveSetting(CONFIG_FILEPATH,"Measure01","LineColumnEnd",\
                            QVariant(MeasureParam01.LineColumnEnd));//AmpThre


}

14.加载参数

构造函数里面

 // //把界面的参数 赋值 给局部作用域的变量
    //double AmpThre=ui->SpinBox_AmpThre->value();
    //再通过qsetting的方法 把参数保存到qt 本地的 文件中去
    //SaveSetting(CONFIG_FILEPATH,"Measure01","AmplitudeThreshold",QVariant(AmpThre));//AmpThre


    QVariant ValueAmpThre;
    QVariant ValueAlpha1;
    QVariant ValueRoiWidthLen;
    QVariant ValueRowStart;
    QVariant ValueColumnStart;
    QVariant ValueRowEnd;
    QVariant ValueColumnEnd;
    LoadSetting(CONFIG_FILEPATH,"Measure01","AmplitudeThreshold",ValueAmpThre);
    LoadSetting(CONFIG_FILEPATH,"Measure01","Alpha1",ValueAlpha1);//AmpThre
    LoadSetting(CONFIG_FILEPATH,"Measure01","RoiWidthLen",ValueRoiWidthLen);//AmpThre

    LoadSetting(CONFIG_FILEPATH,"Measure01","LineRowStart",ValueRowStart);//AmpThre
    LoadSetting(CONFIG_FILEPATH,"Measure01","LineColumnStart",ValueColumnStart);//AmpThre
    LoadSetting(CONFIG_FILEPATH,"Measure01","LineRowEnd",ValueRowEnd);//AmpThre
    LoadSetting(CONFIG_FILEPATH,"Measure01","LineColumnEnd",ValueColumnEnd);//AmpThre

    //把QVariant 类型 转换 double 类型
    MeasureParam01.AmplitudeThreshold=ValueAmpThre.toDouble();
    MeasureParam01.Alpha1=ValueAlpha1.toDouble();
    MeasureParam01.RoiWidthLen=ValueRoiWidthLen.toDouble();
    MeasureParam01.LineRowStart=ValueRowStart.toDouble();
    MeasureParam01.LineColumnStart=ValueColumnStart.toDouble();
    MeasureParam01.LineRowEnd=ValueRowEnd.toDouble();
    MeasureParam01.LineColumnEnd=ValueColumnEnd.toDouble();
    ui->SpinBox_AmpThre->setValue(MeasureParam01.AmplitudeThreshold);
    ui->SpinBox_Alpha1->setValue(MeasureParam01.Alpha1);
    ui->SpinBox_RoiWidthLen->setValue(MeasureParam01.RoiWidthLen);
    ui->SpinBox_LineRowStart->setValue(MeasureParam01.LineRowStart);
    ui->SpinBox_LineColumnStart->setValue(MeasureParam01.LineColumnStart);
    ui->SpinBox_LineRowEnd->setValue(MeasureParam01.LineRowEnd);
    ui->SpinBox_LineColumnEnd->setValue(MeasureParam01.LineColumnEnd);

    ui->SpinBox_AmpThre->setStyleSheet("background-color: green");

15.日志类(lxlog)

.h

#ifndef __LX_LOG_H__
#define __LX_LOG_H__

#include<QString>
#include <QTextBrowser>

void WriteLog(QString LogType, QString str);
void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);

#endif

.cpp

#include "lxlog.h"
#include "paramsconfig.h"
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QTextBrowser>

extern QTextBrowser * g_pTb;

void WriteLog(QString LogType, QString str)
{
    //文件名
    QString filePath = QString(LOG_PATH) + '/'+ QDateTime::currentDateTime().toString("yyyy-MM-dd")+".log";

    //时间
    QString strToWrite = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

    //类型
    strToWrite.append(QString(" %1 ").arg(LogType));

    //信息
    strToWrite.append(QString("%1").arg(str));

    QFile file(filePath);
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream text_stream(&file);
    text_stream << strToWrite << "\r\n";
    file.flush();
    file.close();

    g_pTb->append(strToWrite);
}

void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QString txtMessage = "";
    QString messageType = "";
    switch (type) {
    case QtDebugMsg:    //调试信息提示
        messageType = "Debug";
        txtMessage = QString("Debug: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);
        break;
    case QtInfoMsg:
        messageType = "Info";
        txtMessage = QString("Warning: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);
        break;
    case QtWarningMsg:    //一般的warning提示
        messageType = "Waring";
        txtMessage = QString("Warning: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);
        break;
    case QtCriticalMsg:    //严重错误提示
        messageType = "Critical";
        txtMessage = QString("Critical: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);
        //PostErrorMessage(txtMessage, messageType);
        break;
    case QtFatalMsg:    //致命错误提示
        messageType = "Fatal";
        txtMessage = QString("Fatal: %1 (%2:%3, %4)\n").arg(msg).arg(context.file).arg(QString::number(context.line)).arg(context.function);
        abort();

    }
    WriteLog(txtMessage, messageType);
}


16.公共参数、结构体类(paramsconfig)

.h

#ifndef PARAMSCONFIG_H
#define PARAMSCONFIG_H

#include <QString>
#include <QVariant>

#define SYS_CONFIG_FILE				"./data/sysConfig/params.ini"
#define USER_CONFIG_PATH			"./data/userConfig"
#define LOG_PATH					"./data/log"
#define TRAIN_FILEPATH              "./data/train"
#define CALIB_DATA_PATH             "data/calib"
#define IMG_DEPETH_FILEPATH         "data/imageDepth"
#define IMG_RAW_FILEPATH            "data/imageRaw"
#define MODEL_FILEPATH              "data/model"
#define SENCE_FILEPATH              "data/sence"
#define CONFIG_FILEPATH             "data/config/params.ini"
#define CONFIG_Main_FILEPAT         "data/config/my.ini"
#define CONFIG_Face_FILEPAT         "data/config/Face.ini"
#define CONFIG_Box_FILEPAT          "data/config/Box.ini"
#define CONFIG_CreatModel_FILEPAT   "data/config/CreatModel.ini"

#define POSE_TO_HTUPLE(pose, hTuple) {hTuple[0] = pose.x; hTuple[1] = pose.y; hTuple[2] = pose.z; hTuple[3] = pose.rx; hTuple[4] = pose.ry; hTuple[5] = pose.rz; hTuple[6] = 0.0;}
#define HTUPLE_TO_POSE(hTuple, pose) {pose.x = hTuple[0]; pose.y = hTuple[1]; pose.z = hTuple[2]; pose.rx = hTuple[3]; pose.ry = hTuple[4]; pose.rz = hTuple[5];}

#define KD_PI 3.141592653
#define LENGTH_UNIT "mm"
#define LX_STATIONS_NUM    3       // 相机数量


#include "HalconCpp.h"
using namespace HalconCpp;

/**
 * measure
 */
typedef struct
{
    double AmplitudeThreshold;
    double RoiWidthLen;
    double Alpha1;

    double LineRowStart;
    double LineColumnStart;
    double LineRowEnd;
    double LineColumnEnd;
}MeasureParam;




/**
 * pose
 */
typedef struct {
    double x;                               ///X偏移
    double y;                               ///Y偏移
    double z;                               ///Z偏移
    double rx;                              ///X旋转
    double ry;                              ///Y旋转
    double rz;                              ///Z旋转
    int type;                               ///姿态类型
} KD_POSE;

/**
 * point select
 */
typedef struct {
    double xMin;                            ///X范围
    double xMax;                            ///X范围
    double yMin;                            ///Y范围
    double yMax;                            ///Y范围
    double zMin;                            ///Z范围
    double zMax;                            ///Z范围
    int type;                               ///备用
} KD_POINT_SELECT;

/**
 * 机械臂工具类型
 */
typedef enum {
    ROT_TOOL_SUCKER = 0,                    ///吸盘
    ROT_POSE_GRIPPER_PNEUMATIC,             ///夹具气动
    ROT_POSE_GRIPPER_ELECTRIC,              ///夹具电动
}ROT_TOOL_TYPE;

/**
 * 三维点云控制参数
 */
typedef struct {
    KD_POSE calibPose;                      ///校正Pose
    KD_POINT_SELECT potSelc;                ///范围限定
} KD_3D_CTRL;                               ///三维控制参数

/**
 * 三维物体参数
 */
typedef struct {
    KD_POSE * pObjChangePose;               ///偏移pose
    unsigned int surfaceNum;                ///面数
    double objGuideHigh;                    ///物体抓取引导高度
} KD_OBJECT_CTRL;                           ///三维控制参数

/**
 * 3d匹配参数
 */
typedef struct {
    double objectMaxLength;                 ///物体最大长度
    double sampleDis;                       ///采样距离
    double keyPotFraction;                  ///特征点最小得分
    double minScore;                        ///最小得分
    QString * modelFileName;                ///模型文件名
    KD_POSE toolInFlangeCenter;             ///工具在法兰盘中心(由机械臂标定得出)
    KD_POSE camInBase;                      ///相机在基础 (由halcon手眼标定得出)
    KD_POSE toolInObj;                      ///工具在物体 (由halcon手眼标定得出)
    KD_3D_CTRL bgInfo;                      ///背景抽取参数
} KD_SURFACE_MATCH_CTRL;

/**
 * 机械臂参数
 */
typedef struct {
    int speed;                              ///速度(测试用)
    double jointVelc;                       ///角速度
    double jointAcc;                        ///角加速度
    double lineVelc;                        ///线速度
    double lineAcc;                         ///线加速度
    int colliClass;                         ///防撞等级
    KD_POSE toolInFlangeCenter;             ///工具在法兰盘中心
} KD_ROBOT_CTRL;

/**
 * 机械臂码垛参数
 */
typedef struct {
    KD_POSE oriPose;                        ///起始码垛姿态
    KD_POSE offsetPose;                     ///偏移码垛姿态
    int palletNum;                          ///码垛数量
    double palletSize;                      ///工件尺寸
} KD_ROBOT_PALLET_CTRL;

/**
 * 机械臂运动参数
 */
typedef struct {
    double doorHigh;                        ///门型高度
    int ioId;                               ///吸盘、夹具IO口
    int moveTime;                           ///机械臂从抓取到放置位置延时时间
    int doorUpDownTime;                     ///门型上下移动延时时间
    int suctionTime;                        ///吸盘、夹具延时时间
    KD_POSE halfWayPose;                    ///中途路点
    KD_ROBOT_PALLET_CTRL pallet;            ///码垛参数
    ROT_TOOL_TYPE toolType;                 ///工具类型
} KD_ROBOT_MOVE_CTRL;


typedef enum {
    UNINIT,				//还未初始化
    RUNNING,			//运行
    STOP				//停止
}PROGRAM_STATUS;


/**
* DO输出0
*/
typedef enum {
    KEY_RELEASE = 0,
    KEY1 = 1,
    KEY2 = 2,
    KEY3 = 4,
    KEYS = 8,
    KEYU = 16,
    KEYD = 32
}HC_KEY_TYPE;

/**
* DO输出1
*/
typedef enum {
    DO_NONE	   = 0,
    DO_GUIDE1  = 1,	// 推进
    DO_GUIDE2  = 2, // 推出
    DO_BUZZER  = 4,
    DO_LIGHT   = 8,
    DO_BACKUP1 = 16,
    DO_BACKUP2 = 32
}HC_DO_TYPE;

/**
* DI输入
*/
typedef enum {
    DI_GUIDE1 = 1,	// 推进状态
    DI_GUIDE2 = 2,  // 推出状态
    DI_START  = 4,
    DI_RESET  = 8,
    DI_STOP   = 16,
    DI_BACKUP = 32
}HC_DI_TYPE;

/**
 * 矩形
 */
typedef struct {
    int x;
    int y;
    int w;
    int h;
} LX_RECT;

/**
 * 识别参数
 */
typedef struct {
    LX_RECT roiRect;                    ///ROI区域
    int erosionVal;                     ///腐蚀参数
    int dilationVal;                    ///膨胀参数
    int noiseArea;                      ///噪声面积(小于该面积都被认为是噪声)
    int decimalPointArea;				///小数点面积
    double confidence;					///最低置信率
    QString trainFile;					///训练文件
    QString usrconfigFile;				///测试项目配置文件
} LX_RECOGNISE_CTRL;

//LX_RECOGNISE_CTRL LX_RECOGNISE_CTRL1;
//LX_RECOGNISE_CTRL LX_RECOGNISE_CTRL2;
/**
 * 相机参数
 */
typedef struct {
    int exposureTime;
    int exposureTimeMin;
    int exposureTimeMax;
    int gain;
    int gainMin;
    int gainMax;
//    bool bMiroH;
//    bool bMiroV;
} LX_CAMERA_CTRL;

/**
 * io
 */
typedef struct {
    QString key1Do;									//io口ID
    QString key2Do;									//io口ID
    QString key3Do;									//io口ID
    QString keySDo;									//io口ID
    QString keyUpDo;								//io口ID
    QString keyDownDo;								//io口ID
    QString keyBuzzerDo;                            //io口ID
    QString keyStartDi;								//io口ID
    QString keyResetDi;								//io口ID
    QString keyStopDi;								//io口ID
} LX_IO_CTRL;

/**
 * 初始化参数
 */
typedef struct {
    int pressTime;                      ///按下时间
    QString defaultVal;                 ///初始值
} HC_INIT_CTRL;

/**
 * 公英制参数
 */
typedef struct {
    int unit;							///0为公制值, 1为英制
} HC_METRIC_IMPERIAL_CTRL;

/**
 * 数字缺失
 */
typedef struct {
    QString defaultVal;					///预设值
} HC_NUM_MISS_CTRL;

/**
 * 记忆位
 */
typedef struct {
    int pressTime;                     ///单次上升时间
} HC_MEMORY_POS_CTRL;

/**
 * 陀螺仪
 */
typedef struct {
    QString defaultVal;                ///陀螺仪预设等级
} HC_GYRO_CTRL;

/**
 * 上升下降锁
 */
typedef struct {
    int pressTime;                      ///按下时间
} HC_LOCK_CTRL;

/**
 * 异常码
 */
//typedef struct {
//    int pressTimeE05;                   ///E05按下时间
//}HC_EXCEPTION_CTRL;

/**
 * 手控器检测和预设参数
 */
typedef struct {
    HC_INIT_CTRL initCtrl;
    HC_METRIC_IMPERIAL_CTRL metricImperialCtrl;
    HC_NUM_MISS_CTRL numMisCtrl;
    HC_MEMORY_POS_CTRL memoryPosCtrl;
    HC_GYRO_CTRL gyroCtrl;
    HC_LOCK_CTRL lockCtrl;
    int testItem;														//测试项
    int workStationId;
} LX_HC_CTRL;

/**
  *2d模板匹配的预设参数
  */

typedef  struct {
    double OffsetRow;
    double OffsetColumn;
    double TPhi;
    double TLength1;
    double TLength2;
    int m_nModecase;   // =1
    HTuple ModelID;
    HObject ShapeModel;
} LX_MATCH_CTRL;


//保存加载配置
void SaveSetting(QString fileName, QString group, QString key, QVariant value);
void LoadSetting(QString fileName, QString group, QString key, QVariant &value);

//保存加载识别配置
void SaveRecogniseCtrl(QString fileName, QString group, LX_RECOGNISE_CTRL recCtrl);
void LoadRecogniseCtrl(QString fileName, QString group, LX_RECOGNISE_CTRL &recCtrl);

//保存加载IO配置
void SaveIoCtrl(QString fileName, QString group, LX_IO_CTRL ioCtrl);
void LoadIoCtrl(QString fileName, QString group, LX_IO_CTRL &ioCtrl);

//保存加载相机配置
void SaveCameraCtrl(QString fileName, QString group, LX_CAMERA_CTRL camCtrl);
void LoadCameraCtrl(QString fileName, QString group, LX_CAMERA_CTRL &camCtrl);

//保存加载手控器配置
void SaveHandCtrlerCtrl(QString fileName, QString group, LX_HC_CTRL hcCtrl);
void LoadHandCtrlerCtrl(QString fileName, QString group, LX_HC_CTRL &hcCtrl);

//保存相机的 产品唯一序列号和工位
void  SaveCameraAscn(QString fileName, QString Key,QString  CameraNumber );
void  LoadCameraAscn(QString fileName, QString Key,QString  &CameraNumber );

double AngleToRad(double angle);
double RadToAngle(double rad);

//保存pose
void SavePose(QString group, KD_POSE pose);

//加载pose
void LoadPose(QString group, KD_POSE &pose);



class paramsConfig
{
public:
    paramsConfig();
};

#endif // PARAMSCONFIG_H

.cpp

#include "paramsconfig.h"
#include <QSettings>
#include <QDebug>

paramsConfig::paramsConfig()
{

}

void SaveRecogniseCtrl(QString fileName, QString group, LX_RECOGNISE_CTRL recCtrl)
{

}

void SaveCameraCtrl(QString fileName, QString group, LX_CAMERA_CTRL camCtrl)
{  // 淇濆瓨鍔犺浇鐩告満閰嶇疆
    SaveSetting(fileName, group, "exposureTime", QVariant(camCtrl.exposureTime));
    SaveSetting(fileName, group, "gain", QVariant(camCtrl.gain));
    SaveSetting(fileName, group, "gainMin", QVariant(camCtrl.gainMin));
    SaveSetting(fileName, group, "gainMax", QVariant(camCtrl.gainMax));
    SaveSetting(fileName, group, "exposureTimeMin", QVariant(camCtrl.exposureTimeMin));
    SaveSetting(fileName, group, "exposureTimeMax", QVariant(camCtrl.exposureTimeMax));
}

void LoadCameraCtrl(QString fileName, QString group, LX_CAMERA_CTRL &camCtrl)
{  // 鍔犺浇鐩告満閰嶇疆
    QVariant qexposureTime;
    QVariant qexposureTimeMin;
    QVariant qexposureTimeMax;
    QVariant qGain;
    QVariant qGainMin;
    QVariant qGainMax;

    LoadSetting(fileName, group, "exposureTime", qexposureTime);
    LoadSetting(fileName, group, "exposureTimeMin", qexposureTimeMin);
    LoadSetting(fileName, group, "exposureTimeMax", qexposureTimeMax);
    LoadSetting(fileName, group, "gain", qGain);
    LoadSetting(fileName, group, "gainMin", qGainMin);
    LoadSetting(fileName, group, "gainMax", qGainMax);


    camCtrl.exposureTime = qexposureTime.toInt();
    camCtrl.exposureTimeMin = qexposureTimeMin.toInt();
    camCtrl.exposureTimeMax = qexposureTimeMax.toInt();
    camCtrl.gain = qGain.toInt();
    camCtrl.gainMin = qGainMin.toInt();
    camCtrl.gainMax = qGainMax.toInt();
//    qDebug()<<"camCtrl.gain"<<camCtrl.gain;
//    qDebug()<<"camCtrl.qexposureTime:+"<<camCtrl.exposureTime;
}

void SaveHandCtrlerCtrl(QString fileName, QString group, LX_HC_CTRL hcCtrl)
{

}

void LoadCameraAscn(QString fileName, QString Key, QString &CameraNumber)
{
    QString group = "CameraManage";
    QVariant ValueCameraNumber;
    LoadSetting(fileName,group,Key,ValueCameraNumber);
    CameraNumber = ValueCameraNumber.toString();
    qDebug() << "CameraName:= " << CameraNumber;
}

void LoadSetting(QString fileName, QString group, QString key, QVariant &value)
{
    QSettings settings(fileName,QSettings::IniFormat);
    if(group.size() != 0)
    {
        settings.beginGroup(group);
    }
    value = settings.value(key);
    if(group.size() != 0)
    {
        settings.endGroup();
    }
}

void SaveSetting(QString fileName, QString group, QString key, QVariant value)
{
    QSettings settings(fileName, QSettings::IniFormat);
    if (group.size() != 0) {
        settings.beginGroup(group);
    }
    settings.setValue(key, value);
    if (group.size() != 0) {
        settings.endGroup();
    }
}

void SavePose(QString group, KD_POSE pose)
{

}

已经看到这里了,点个赞和关注吧!

      刚开始写文章,如有不足请多多包含;之后会持续更新关于(halcon学习,VS联合编程,QT联合编程,C++,C#,Opencv图像处理库,三维点云库pcl,相机以及机器人的二次开发)等系统化学习文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2343816.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前后端分离项目】Vue+Springboot+MySQL

文章目录 1.安装 Node.js2.配置 Node.js 环境3.安装 Node.js 国内镜像4.创建 Vue 项目5.运行 Vue 项目6.访问 Vue 项目7.创建 Spring Boot 项目8.运行 Spring Boot 项目9.访问 Spring Boot 项目10.实现 Vue 与 Spring Boot 联动11.安装 axios12.编写请求13.调用函数请求接口14.…

数据结构和算法(八)--2-3查找树

目录 一、平衡树 1、2-3查找树 1.1、定义 1.2、查找 1.3、插入 1.3.1、向2-结点中插入新键 1.3.2、向一棵只含有一个3-结点的树中插入新键 1.3.3、向一个父结点为2-结点的3-结点中插入新键 1.3.4、向一个父结点为3-结点的3-结点中插入新键 1.3.5、分解根结点 1.4、2…

Unity-Shader详解-其二

前向渲染和延迟渲染 前向渲染和延迟渲染总的来说是我们的两种主要的渲染方式。 我们在Unity的Project Settings中的Graphic界面能够找到渲染队列的设定&#xff1a; 我们也可以在Main Camera这里进行设置&#xff1a; 那这里我们首先介绍一下两种渲染&#xff08;Forward R…

深入浅出理解并应用自然语言处理(NLP)中的 Transformer 模型

1 引言 随着信息技术的飞速发展&#xff0c;自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;作为人工智能领域的一个重要分支&#xff0c;已经取得了长足的进步。从早期基于规则的方法到如今的深度学习技术&#xff0c;NLP 正在以前所未有的速度改变着我…

当自动驾驶遇上“安全驾校”:NVIDIA如何用技术给无人驾驶赋能?

自动驾驶技术的商业化落地&#xff0c;核心在于能否通过严苛的安全验证。国内的汽车企业其实也在做自动驾驶&#xff0c;但是吧&#xff0c;基本都在L2级别。换句话说就是在应急时刻内&#xff0c;还是需要人来辅助驾驶&#xff0c;AI驾驶只是决策层&#xff0c;并不能完全掌握…

【OSG学习笔记】Day 9: 状态集(StateSet)与渲染优化 —— 管理混合、深度测试、雾效等渲染状态

干货开始。_ 一、StateSet核心概念与作用 StateSet 是OSG(OpenSceneGraph)中管理渲染状态的核心类,用于封装 OpenGL 渲染状态(如混合、深度测试、雾效、材质、纹理、着色器等),并将这些状态应用于节点或几何体。 通过合理组织 StateSet,可实现: 渲染状态的高效复用:…

Operating System 实验七 Linux文件系统实验

实验目标: 使用dd命令创建磁盘镜像文件ext2.img并格式化为ext2文件系统,然后通过mount命令挂载到Linux主机文件系统。查看ext2文件系统的超级块的信息,以及数据块的数量、数据块的大小、inode个数、空闲数据块的数量等信息 在文件系统中创建文件xxxxx.txt(其中xxxxx为你的学…

linux中shell脚本的编程使用

linux中shell脚本的编程使用 1.shell的初步理解1.1 怎么理解shell1.2 shell命令 2.shell编程2.1 什么是shell编程2.2 C语言编程 和 shell编程的区别 3.编写和运行第一个shell脚本程序3.1 编写时需要注意以下几点&#xff1a;3.1.1 shell脚本没有main函数&#xff0c;没有头文件…

图像畸变-径向切向畸变实时图像RTSP推流

实验环境 注意&#xff1a;ffmpeg进程stdin写入两张图片的时间间隔不能太长&#xff0c;否则mediamtx会出现对应的推流session超时退出。 实验效果 全部代码 my_util.py #进度条 import os import sys import time import shutil import logging import time from datetime i…

手搓雷达图(MATLAB)

看下别人做出来什么效果 话不多说&#xff0c;咱们直接开始 %% 可修改 labels {用户等级, 发帖数, 发帖频率, 点度中心度, 中介中心度, 帖子类型计分, 被列为提案数}; cluster_centers [0.8, 4.5, 3.2, 4.0, 3.8, 4.5, 4.2; % 核心用户0.2, 0.5, 0.3, 0.2, 0.1, 0.0, 0.0;…

汽车零配件供应商如何通过EDI与主机厂生产采购流程结合

当前&#xff0c;全球汽车产业正经历深刻的数字化转型&#xff0c;供应链协同模式迎来全新变革。作为产业链核心环节&#xff0c;汽车零部件供应商与主机厂的高效对接已成为企业发展的战略要务。然而&#xff0c;面对主机厂日益严格的数字化采购要求&#xff0c;许多供应商在ED…

闻性与空性:从耳根圆通到究竟解脱的禅修路径

一、闻性之不动&#xff1a;超越动静的觉性本质 在《楞严经》中&#xff0c;佛陀以钟声为喻揭示闻性的奥秘&#xff1a;钟声起时&#xff0c;闻性显现&#xff1b;钟声歇时&#xff0c;闻性不灭。此“不动”并非如磐石般凝固&#xff0c;而是指觉性本身超越生灭、来去的绝对性…

第34课 常用快捷操作——按“空格键”旋转图元

概述 旋转某个图元&#xff0c;是设计过程中常需要用到的操作&#xff0c;无论是在原理图中旋转某个图形&#xff0c;还是在PCB图中旋转某个元素。 旋转操作的快捷键是空格键。下面作详细介绍。 按空格键旋转图元 当我们选中一个图元时&#xff0c;按下空格键&#xff0c;即…

基于亚马逊云科技构建音频转文本无服务器应用程序

Amazon Transcribe是一项基于机器学习模型自动将语音转换为文本的服务。它提供了多种可以提高文本转录准确性的功能&#xff0c;例如语言自定义、内容过滤、多通道音频分析和说话人语音分割。Amazon Transcribe 可用作独立的转录服务&#xff0c;也可以集成到应用程序中提供语音…

K8S Service 原理、案例

一、理论介绍 1.1、3W 法则 1、是什么&#xff1f; Service 是一种为一组功能相同的 pod 提供单一不变的接入点的资源。当 Service 存在时&#xff0c;它的IP地址和端口不会改变。客户端通过IP地址和端口号与 Service 建立连接&#xff0c;这些连接会被路由到提供该 Service 的…

实验四 进程调度实验

一、实验目的 1、了解操作系统CPU管理的主要内容。 2、加深理解操作系统管理控制进程的数据结构--PCB。 3、掌握几种常见的CPU调度算法&#xff08;FCFS、SJF、HRRF、RR&#xff09;的基本思想和实现过程。 4、用C语言模拟实现CPU调度算法。 5、掌握CPU调度算法性能评价指…

linux blueZ 第四篇:BLE GATT 编程与自动化——Python 与 C/C++ 实战

本篇聚焦 BLE(Bluetooth Low Energy)GATT 协议层的编程与自动化实践,涵盖 GATT 基础、DBus API 原理、Python(dbus-next/bleak)示例、C/C++ (BlueZ GATT API)示例,以及自动发现、读写特征、订阅通知、安全配对与脚本化测试。 目录 BLE GATT 基础概念 BlueZ DBus GATT 模…

Linux线程与进程:探秘共享地址空间的并发实现与内

Linux系列 文章目录 Linux系列前言一、线程的概念二、线程与地址空间2.1 线程资源的分配2.2 虚拟地址到物理地址的转换 三 、线程VS进程总结 前言 在Linux操作系统中&#xff0c;线程作为CPU调度的基本单位&#xff0c;起着至关重要的作用。深入理解线程控制机制&#xff0c;是…