海康SDK在主线程中的使用方法

海康SDK在主线程中的使用方法,注意:海康SDK不限制注册回调位置,在回调函数内部已经使用了多线程管理,每注册一个摄像头,就会分配一个线程。所以应用层无需考虑多线程使用SDK。对于获取回调中的数据有多种方法:1、采用指针的方式,可以从函数外部定义指针,回调中对应修改其值的方式,这样回调函数外就可以拿到回调中的数据了。根据业务逻辑不同,可定义多个指针用于接收回调函数内返回的数据。2、采用静态变量的方式也可以。方法类似,不再赘述。
一、mainform.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QLabel>
#include <QVector>
#include <QThread>
#include "ui_mainwindow.h"
#include "Windows.h"
#include "HCNetSDK.h"
#include "cameraglobaldata.h"
using namespace  std;
class MainWindow : public QWidget
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    static void CALLBACK cbMessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser);
    void cbMessageCallbackInstance(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen);
    int registerHikonSDKCallback(char* ipaddress,char* username,char* password,int port,int channelNO);
    static int iNum;
    static int count_1;
    static int count_2;
    static int count_3;
    static int count_4;
    static int count_5;
    static int count_6;
    static int count_7;
    static int count_8;
    static string tempip;
private:
    Ui::MainWindow *ui;
    QVector<QLabel*> labelList;
    QVector<QThread*> threadList;
    bool sdkinit_tag=false;
    CameraGlobalData cgd;
};
#endif // MAINWINDOW_H

二、.mainform.cpp文件:

#include "mainwindow.h"
#include "camerathread.h"
#include "sdkthread.h"
#include <QHBoxLayout>
#include <QPen>
#include <QPainter>
#include <QPointF>
#include <QTextCodec>
string Sdkthread::tempip="";
int MainWindow::count_1=0;
int MainWindow::count_2=0;
int MainWindow::count_3=0;
int MainWindow::count_4=0;
int MainWindow::count_5=0;
int MainWindow::count_6=0;
int MainWindow::count_7=0;
int MainWindow::count_8=0;
int MainWindow::iNum=0;
string MainWindow::tempip="";
MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent)
{
    QVBoxLayout *verticalLayout=new QVBoxLayout();
    QHBoxLayout *horizontaiLayout_11=new QHBoxLayout();
    QHBoxLayout *horizontaiLayout_12=new QHBoxLayout();
    QHBoxLayout *horizontaiLayout_21=new QHBoxLayout();
    QHBoxLayout *horizontaiLayout_22=new QHBoxLayout();
    // 初始化8个QLabel并添加到主窗口
    for (int k = 0; k < 4; ++k) {
        QLabel *label = new QLabel();
        label->setStyleSheet("border:1px solid gray");
        label->setFixedSize(352,288);
        label->setScaledContents(true);
        horizontaiLayout_11->addWidget(label);
        labelList.append(label);
    }
    for (int h = 0; h < 4; ++h) {
        QLabel *label2 = new QLabel();
        label2->setStyleSheet("border:1px solid gray");
        label2->setFixedSize(200,20);
        label2->setScaledContents(true);
        horizontaiLayout_12->addWidget(label2);
        labelList.append(label2);
    }
    for (int i = 0; i < 4; ++i) {
        QLabel *label2 = new QLabel();
        label2->setStyleSheet("border:1px solid gray");
        label2->setFixedSize(352,288);
        label2->setScaledContents(true);
        horizontaiLayout_21->addWidget(label2);
        labelList.append(label2);
    }
    for (int j = 0; j < 4; ++j) {
        QLabel *label = new QLabel();
        label->setStyleSheet("border:1px solid gray");
        label->setFixedSize(200,20);
        label->setScaledContents(true);
        horizontaiLayout_22->addWidget(label);
        labelList.append(label);
    }
    verticalLayout->addLayout(horizontaiLayout_11);
    verticalLayout->addLayout(horizontaiLayout_12);
    verticalLayout->addLayout(horizontaiLayout_21);
    verticalLayout->addLayout(horizontaiLayout_22);
    setLayout(verticalLayout);
    setFixedSize(1600,800);
    std::cout<<"labelList length:"<<labelList.length()<<std::endl;
    for (int i = 0; i < 8; ++i) {
        CameraThread *cameraThread = new CameraThread(labelList[i],i);
        connect(cameraThread, &CameraThread::frameReady, this, [this](const QImage &frame, int index) {
            if(index<4){
               labelList[index]->setPixmap(QPixmap::fromImage(frame));
            }else{
               labelList[index+4]->setPixmap(QPixmap::fromImage(frame));
            }
        });
        threadList.append(cameraThread);
        cameraThread->start();
        QThread::msleep(30);
    }
    for (int i = 0; i < 2; ++i) {
        registerHikonSDKCallback((char *)cgd.cameras.at(i).ipaddress.c_str(),(char *)cgd.cameras.at(i).username.c_str(),(char *)cgd.cameras.at(i).sdkpassword.c_str(),cgd.cameras.at(i).port,2);
    }
}
void CALLBACK MainWindow::cbMessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen,void* pUser){
    if (pUser != nullptr)
    {
        MainWindow* pThis = static_cast<MainWindow*>(pUser);
        pThis->cbMessageCallbackInstance(lCommand, pAlarmer, pAlarmInfo, dwBufLen);
    }
}
void MainWindow::cbMessageCallbackInstance(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen){
    int i=0;
    char filename[100];
    FILE *fSnapPic=NULL;
    FILE *fSnapPicPlate=NULL;
    //以下代码仅供参考,实际应用中不建议在该回调函数中直接处理数据保存文件,
    //例如可以使用消息的方式(PostMessage)在消息响应函数里进行处理。
    switch (lCommand)
    {
    case COMM_UPLOAD_PLATE_RESULT:
    {
        NET_DVR_PLATE_RESULT struPlateResult={0};
        memcpy(&struPlateResult, pAlarmInfo, sizeof(struPlateResult));
        printf("%s %s\n",QString("车牌号:").toLocal8Bit().toStdString().c_str(), struPlateResult.struPlateInfo.sLicense);//车牌号
        switch(struPlateResult.struPlateInfo.byColor)//车牌颜色
        {
        case VCA_BLUE_PLATE:
            printf("车辆颜色: 蓝色\n");
            break;
        case VCA_YELLOW_PLATE:
            printf("车辆颜色: 黄色\n");
            break;
        case VCA_WHITE_PLATE:
            printf("车辆颜色: 白色\n");
            break;
        case VCA_BLACK_PLATE:
            printf("车辆颜色: 黑色\n");
            break;
        default:
            break;
        }
        //场景图
        if (struPlateResult.dwPicLen != 0 && struPlateResult.byResultType == 1 )
        {
            sprintf(filename,"testpic_%d.jpg",iNum);
            fSnapPic=fopen(filename,"wb");
            fwrite(struPlateResult.pBuffer1,struPlateResult.dwPicLen,1,fSnapPic);
            iNum++;
            fclose(fSnapPic);
        }
        //车牌图
        if (struPlateResult.dwPicPlateLen != 0 && struPlateResult.byResultType == 1)
        {
            sprintf(filename,"testPicPlate_%d.jpg",iNum);
            fSnapPicPlate=fopen(filename,"wb");
            fwrite(struPlateResult.pBuffer1,struPlateResult.dwPicLen,1,fSnapPicPlate);
            iNum++;
            fclose(fSnapPicPlate);
        }
        //其他信息处理......
        break;
    }
    case COMM_ITS_PLATE_RESULT:
    {
        //COMM_ALARM_TPS_REAL_TIME             0x3081  //TPS实时过车数据上传
        NET_ITS_PLATE_RESULT struITSPlateResult={0};
        memcpy(&struITSPlateResult, pAlarmInfo, sizeof(struITSPlateResult));
        for (i=0;i < struITSPlateResult.dwPicNum-1;i++)
        {
            // printf("车牌号: %s\n", struITSPlateResult.struPlateInfo.sLicense);//车牌号
            //byDriveChan:车道号 东左:1 东直1:2 东直2:3
if(struITSPlateResult.byDriveChan==1||struITSPlateResult.byDriveChan==2||struITSPlateResult.byDriveChan==3){
                // 将前12位转换为 QString
                QString absTimeStr = QString::fromLatin1((char *)struITSPlateResult.struPicInfo[0].byAbsTime);
                cout<<"sDeviceIP:"<<pAlarmer->sDeviceIP<<endl;

                // 创建GBK编码的QTextCodec实例
                QTextCodec *gbkCodec = QTextCodec::codecForName("GBK");
                // 将GBK编码的char数据转换为QByteArray(UTF-8编码)
                QByteArray gbkByteArray = gbkCodec->toUnicode(struITSPlateResult.struPlateInfo.sLicense).toStdString().c_str();
                // 使用QByteArray构造一个UTF-8编码的QString对象
                QString utf8String = QString::fromUtf8(gbkByteArray);

                if(pAlarmer->sDeviceIP==string("192.168.2.184")){
                    count_1++;
                    labelList[4]->setText("车流量:"+QString::number(count_1)+"   "+utf8String);
                }
                if(pAlarmer->sDeviceIP==string("192.168.0.140")){
                    count_2++;
                     labelList[5]->setText("车流量:"+QString::number(count_2)+"   "+utf8String);
                }
                printf("%s %s\n",QString("车牌号:").toLocal8Bit().toStdString().c_str(),struITSPlateResult.struPlateInfo.sLicense);//车牌号
                tempip=pAlarmer->sDeviceIP;
                WORD w_year= struITSPlateResult.struSnapFirstPicTime.wYear;
                byte b_month=struITSPlateResult.struSnapFirstPicTime.byMonth;
                byte b_day=struITSPlateResult.struSnapFirstPicTime.byDay;
                byte b_hour=struITSPlateResult.struSnapFirstPicTime.byHour;
                byte b_minute=struITSPlateResult.struSnapFirstPicTime.byMinute;
                byte b_second=struITSPlateResult.struSnapFirstPicTime.bySecond;
                byte b_milliSec=struITSPlateResult.struSnapFirstPicTime.wMilliSec;
                QString year_str=QString::number(w_year);
                QString month_str=QString::number(b_month);
                if(b_month<10){
                    month_str="0"+month_str;
                }
                QString day_str=QString::number(b_day);
                if(b_day<10){
                    day_str="0"+day_str;
                }
                QString hour_str=QString::number(b_hour);
                if(b_hour<10){
                    hour_str="0"+hour_str;
                }
                QString minute_str=QString::number(b_minute);
                if(b_minute<10){
                    minute_str="0"+minute_str;
                }
                QString second_str=QString::number(b_second);
                if(b_second<10){
                    second_str="0"+second_str;
                }
                QString milliSec_str=QString::number(b_milliSec);
                if(b_milliSec<10){
                    milliSec_str="0"+milliSec_str;
                }
                QString car_inTime=year_str+"-"+month_str+"-"+day_str+" "+hour_str+":"+minute_str+":"+second_str+"."+milliSec_str;
                QString car_outTime=QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
                //                qDebug()<<"car_inTime:"<<car_inTime;
                //                qDebug()<<"car_outTime:"<<car_outTime;
                WORD speed=struITSPlateResult.struVehicleInfo.wSpeed;
                //                std::cout<<"speed:"<<speed<<std::endl;
            }
        }
        break;
    }
    default:
        break;
    }
    return;
}
int MainWindow::registerHikonSDKCallback(char* ipaddress,char* username,char* password,int port,int channelNO)
{
    //---------------------------------------
    //初始化
    if(!sdkinit_tag){
        NET_DVR_Init();
        //设置连接时间与重连时间
        NET_DVR_SetConnectTime(2000, 1);
        NET_DVR_SetReconnect(10000, true);
        sdkinit_tag=true;
    }
    //---------------------------------------
    //注册设备
    //登录参数,包括设备地址、登录用户、密码等
    LONG lUserID = -1; //初始化lUserID
    NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};//创建一个数据结构对象并为每个属性赋初值为0
    struLoginInfo.bUseAsynLogin = 0; //设置为同步登录方式
    strcpy(struLoginInfo.sDeviceAddress, ipaddress); //设置设备IP地址为192.168.2.9
    struLoginInfo.wPort = port; //设置服务端口为8000
    strcpy(struLoginInfo.sUserName, username); //设置:用户名
    strcpy(struLoginInfo.sPassword, password); //设置:密码
    //设备信息, 输出参数
    NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = {0};//创建一个V40数据结构对象
    lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);//登录注册并将设备信息存储在struDeviceInfoV40结构中
    if (lUserID < 0)
    {
        //登录失败时提示错误信息
        qDebug("Login failed, error code: %d\n", NET_DVR_GetLastError());
        NET_DVR_Cleanup();//登出
        return 0;
    }
    //---------------------------------------
    //报警布防
    //设置报警回调函数
    //NET_DVR_SetDVRMessageCallBack_V31(MSesGCallback, NULL);
    /*注:多台设备对接时也只需要调用一次设置一个回调函数,不支持不同设备的事件在不同的回调函数里面返回*/
    NET_DVR_SetDVRMessageCallBack_V50(0, cbMessageCallback,this);//如果是主线程中调用第三个参数可为NULL,如果是在类中调用设置为this
    //启用布防
    NET_DVR_SETUPALARM_PARAM struSetupParam={0};//创建布防结构对象并初始化为0
    struSetupParam.dwSize=sizeof(NET_DVR_SETUPALARM_PARAM);//根据NET_DVR_SETUPALARM_PARAM的大小来设置dwSize的值
    struSetupParam.byLevel = 1; //布防优先级:0- 一等级(高),1- 二等级(中)
    struSetupParam.byAlarmInfoType = 1; //上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)

    LONG lHandle = NET_DVR_SetupAlarmChan_V41(lUserID,&struSetupParam);//开始布防并设置回调函数
    //如果lHandle<0则布防失败,然后出登出并清除
    if (lHandle < 0)
    {
        qDebug("NET_DVR_SetupAlarmChan_V41 failed, error code: %d\n", NET_DVR_GetLastError());
        NET_DVR_Logout(lUserID);
        NET_DVR_Cleanup();
        return 0;
    }

    cout<<struLoginInfo.sDeviceAddress<<endl;
    qDebug("布防成功!\n");

    //---------------------------------------
    //网络触发抓拍

    NET_DVR_SNAPCFG struSnapCfg;
    memset(&struSnapCfg, 0, sizeof(NET_DVR_SNAPCFG));

    //结构体大小
    struSnapCfg.dwSize = sizeof(NET_DVR_SNAPCFG);

    //线圈抓拍次数,0-不抓拍,非0-连拍次数,目前最大5次
    struSnapCfg.bySnapTimes  = 0;

    //抓拍等待时间,单位ms,取值范围[0,60000]
    struSnapCfg.wSnapWaitTime   = 1;//1000

    //连拍间隔时间,单位ms,取值范围[67,60000]
    struSnapCfg.wIntervalTime[0]  = 67;//1000
    struSnapCfg.wIntervalTime[1]  = 67;//1000

    //触发IO关联的车道号,取值范围[0,9]
    struSnapCfg.byRelatedDriveWay = channelNO;

    //网络触发连拍
    if (!NET_DVR_ContinuousShoot(lUserID, &struSnapCfg))
    {
        qDebug("NET_DVR_ContinuousShoot failed, error code: %d\n", NET_DVR_GetLastError());
        return 0;
    }
    qDebug("网络触发连拍!\n");

    //    Sleep(20000); //等待接收数据

    //    //---------------------------------------
    //    //退出

    //    //撤销布防上传通道
    //    if (!NET_DVR_CloseAlarmChan_V30(lHandle))
    //    {
    //        qDebug("NET_DVR_CloseAlarmChan_V30 failed, error code: %d\n", NET_DVR_GetLastError());
    //        NET_DVR_Logout(lUserID);
    //        NET_DVR_Cleanup();
    //        return 0;
    //    }

    //    //注销用户
    //    NET_DVR_Logout(lUserID);

    //    //释放SDK资源
    //    NET_DVR_Cleanup();

    return 0;
}
MainWindow::~MainWindow()
{
    for (QLabel *label : labelList) {
        delete  label;
    }
    for (QThread *thread : threadList) {
        thread->quit();
        thread->wait();
    }
}

秋风写于淄博,技术交流与业务联系:Q375172665

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值