Qt C++海康SDK主函数中注册回调代码:
海康SDK原则上与车道号没有任何关系,仅在回调中根据车道号进行逻辑判断,获取想要的数据,在注册回调时,可以不提供车道号,必要的参数表:ip地址、用户名、密码、端口号,按照官方提供的文档进行注册即可。在主函数和类中都可以注册,一般放在主函数中即可,所有设备共用一个回调,只要注册过的设备都会分配一个线程,都会生成一个句柄,回调中可以直接获取设备的IP地址,可以根据设备的IP地址过滤所需数据。相当业务逻辑在回调函数中实现。特殊场景,也可以在类中注册回调,只不过要写回调代理,因为回调是静态函数,在类中的使用方法与主函数中不同。可以参考我的上一篇文章《Qt C++海康SDK类中注册回调代码》
#include <stdio.h>
#include <iostream>
#include <QCoreApplication>
#include "Windows.h"
#include "HCNetSDK.h"
#include "hkcardetect.h"
#include <memory>
#include <QThread>
#include <QDateTime>
#include <QDebug>
#include <QString>
#include <QTextCodec>
using namespace std;
int count_1=0;
int count_2=0;
int count_3=0;
int iNum=0;
void CALLBACK cbMessageCallback(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser)
{
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));
// 将前12位转换为 QString
QString absTimeStr = QString::fromLatin1((char *)struITSPlateResult.struPicInfo[0].byAbsTime);
printf("%s %s\n",QString("车牌号:").toLocal8Bit().toStdString().c_str(),struITSPlateResult.struPlateInfo.sLicense);//车牌号
qDebug()<<"current time:"<<absTimeStr;
for (i=0;i < struITSPlateResult.dwPicNum-1;i++)
{
// printf("车牌号: %s\n", struITSPlateResult.struPlateInfo.sLicense);//车牌号
//byDriveChan:车道号 东左:1 东直1:2 东直2:3
if(struITSPlateResult.byDriveChan==1){
count_1++;
std::cout<<"count:"<<count_1<<std::endl;
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 registerHikonSDK(int channelNO)
{
//---------------------------------------
//初始化
NET_DVR_Init();
//设置连接时间与重连时间
NET_DVR_SetConnectTime(2000, 1);
NET_DVR_SetReconnect(10000, true);
//---------------------------------------
//注册设备
//登录参数,包括设备地址、登录用户、密码等
LONG lUserID = -1; //初始化lUserID
NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};//创建一个数据结构对象并为每个属性赋初值为0
struLoginInfo.bUseAsynLogin = 0; //设置为同步登录方式
strcpy(struLoginInfo.sDeviceAddress, "192.168.2.184"); //设置设备IP地址为192.168.2.9
struLoginInfo.wPort = 8000; //设置服务端口为8000
strcpy(struLoginInfo.sUserName, "admin"); //设置:用户名
strcpy(struLoginInfo.sPassword, "a12131415"); //设置:密码
//设备信息, 输出参数
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, NULL);
//启用布防
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;
}
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;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
registerHikonSDK(1);
return a.exec();
}
秋风写淄博,业务咨询与技术交流:Q375172665