海康文档链接: 海康文档链接
硬件是海康立式拍照+测量体温的门禁设备。使用的时候用户站在设备摄像头前,设备拍照并且同时测量用户体温。
下面是我根据海康文档中明眸门禁 => 报警事件 => 报警布防 中的示例C++代码,放入VS2022开发工具中,调试C++代码通过后的代码,并且逻辑做了一定修改,是拍照的时候同时记录下体温。
#include <stdio.h>
#include <iostream>
#include "Windows.h"
#include "HCNetSDK.h"
using namespace std;
char* gip;
int iNum = 0; //已保存的图片个数
void CALLBACK MessageCallback(LONG lCommand, NET_DVR_ALARMER* pAlarmer, char* pAlarmInfo, DWORD dwBufLen, void* pUser)
{
// 是否有体温信息
int hasTemperature = FALSE;
// 体温
float fCurrTemperature = 0;
switch (lCommand)
{
case COMM_ALARM_ACS: //门禁主机报警信息
{
NET_DVR_ACS_ALARM_INFO struAcsAlarmInfo = { 0 };
memcpy(&struAcsAlarmInfo, pAlarmInfo, sizeof(NET_DVR_ACS_ALARM_INFO));
printf("门禁主机报警信息[0x5002]: struTim{%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d}, dwMajor[0x%x], dwMinor[0x%x], byCardNo[%s], dwEmployeeNo[%d], dwCardReaderNo[%d], "\
"ip[%s]\n",
struAcsAlarmInfo.struTime.dwYear, struAcsAlarmInfo.struTime.dwMonth, struAcsAlarmInfo.struTime.dwDay, struAcsAlarmInfo.struTime.dwHour,
struAcsAlarmInfo.struTime.dwMinute, struAcsAlarmInfo.struTime.dwSecond, struAcsAlarmInfo.dwMajor, struAcsAlarmInfo.dwMinor,
struAcsAlarmInfo.struAcsEventInfo.byCardNo, struAcsAlarmInfo.struAcsEventInfo.dwEmployeeNo, struAcsAlarmInfo.struAcsEventInfo.dwCardReaderNo,
struAcsAlarmInfo.struRemoteHostAddr.sIpV4);
//扩展信息,包含以人为中心下发人员触发事件中的工号参数
if (struAcsAlarmInfo.byAcsEventInfoExtend == 1)
{
NET_DVR_ACS_EVENT_INFO_EXTEND struAcsEventInfoExtend = { 0 };
memset(&struAcsEventInfoExtend, 0, sizeof(struAcsEventInfoExtend));
memcpy(&struAcsEventInfoExtend, struAcsAlarmInfo.pAcsEventInfoExtend, sizeof(struAcsEventInfoExtend));
printf("门禁扩展事件信息: dwFrontSerialNo[%d], byUserType[%d], byEmployeeNo[%s]\n", struAcsEventInfoExtend.dwFrontSerialNo,
struAcsEventInfoExtend.byUserType, (char*)struAcsEventInfoExtend.byEmployeeNo);
}
//扩展信息,包含人体测温温度数据
if (struAcsAlarmInfo.byAcsEventInfoExtendV20 == 1)
{
NET_DVR_ACS_EVENT_INFO_EXTEND_V20 struAcsEventInfoExtendV20 = { 0 };
memcpy(&struAcsEventInfoExtendV20, struAcsAlarmInfo.pAcsEventInfoExtendV20, sizeof(struAcsEventInfoExtendV20));
if (struAcsEventInfoExtendV20.byRemoteCheck != 0)
{
//需要远程核验
printf("remote check:%d\n", struAcsEventInfoExtendV20.byRemoteCheck);
}
if (struAcsEventInfoExtendV20.fCurrTemperature != 0)
{
hasTemperature = TRUE;
fCurrTemperature = struAcsEventInfoExtendV20.fCurrTemperature;
printf("temperature[%f]fX[%f]fY[%f]byThermometryUnit[%d]byIsAbnomalTemperature[%d]\n",
struAcsEventInfoExtendV20.fCurrTemperature, struAcsEventInfoExtendV20.struRegionCoordinates.fX,
struAcsEventInfoExtendV20.struRegionCoordinates.fY, struAcsEventInfoExtendV20.byThermometryUnit,
struAcsEventInfoExtendV20.byIsAbnomalTemperature);
}
}
//保存报警抓拍图片
if (struAcsAlarmInfo.dwPicDataLen > 0 && struAcsAlarmInfo.pPicData != NULL && hasTemperature)
{
char cFilename[256] = { 0 };
char chTime[128];
sprintf_s(chTime, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d", struAcsAlarmInfo.struTime.dwYear, struAcsAlarmInfo.struTime.dwMonth,
struAcsAlarmInfo.struTime.dwDay, struAcsAlarmInfo.struTime.dwHour, struAcsAlarmInfo.struTime.dwMinute,
struAcsAlarmInfo.struTime.dwSecond);
// 拼接输出文件名称
sprintf_s(cFilename, "D:\\yourpath\\COMM_ALARM_ACS_CapPic[%d][%s][%f][%s].jpg", pAlarmer->lUserID, chTime, fCurrTemperature, gip);
FILE *fSnapPicPlate;
fopen_s(&fSnapPicPlate, cFilename, "wb");
fwrite(struAcsAlarmInfo.pPicData, struAcsAlarmInfo.dwPicDataLen, 1, fSnapPicPlate);
fclose(fSnapPicPlate);
iNum++;
}
}
break;
case COMM_ID_INFO_ALARM: //门禁主机报警信息 - 身份证
{
NET_DVR_ID_CARD_INFO_ALARM struIDCardInfo = { 0 };
memcpy(&struIDCardInfo, pAlarmInfo, sizeof(NET_DVR_ID_CARD_INFO_ALARM));
printf("门禁身份证刷卡信息[0x5200]: struTim{%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d}, dwMajor[0x%x], dwMinor[0x%x], byName[%s], byIDNum[%s], dwCardReaderNo[%d]" \
", ip[%s]\n",
struIDCardInfo.struSwipeTime.wYear, struIDCardInfo.struSwipeTime.byMonth, struIDCardInfo.struSwipeTime.byDay, struIDCardInfo.struSwipeTime.byHour,
struIDCardInfo.struSwipeTime.byMinute, struIDCardInfo.struSwipeTime.bySecond, struIDCardInfo.dwMajor, struIDCardInfo.dwMinor,
(char*)struIDCardInfo.struIDCardCfg.byName, (char*)struIDCardInfo.struIDCardCfg.byIDNum, struIDCardInfo.dwCardReaderNo,
struIDCardInfo.struRemoteHostAddr.sIpV4);
//扩展信息,包含人体测温温度数据
if (struIDCardInfo.byIDCardInfoExtend == 1)
{
NET_DVR_ID_CARD_INFO_EXTEND struIDCardExtendV20 = { 0 };
memcpy(&struIDCardExtendV20, struIDCardInfo.pIDCardInfoExtend, sizeof(struIDCardExtendV20));
if (struIDCardExtendV20.byRemoteCheck != 0)
{
//需要远程核验
printf("remote check:%d\n", struIDCardExtendV20.byRemoteCheck);
}
if (struIDCardExtendV20.fCurrTemperature != 0)
{
hasTemperature = TRUE;
fCurrTemperature = struIDCardExtendV20.fCurrTemperature;
printf("temperature[%f]fX[%f]fY[%f]byThermometryUnit[%d]byIsAbnomalTemperature[%d]\n",
struIDCardExtendV20.fCurrTemperature, struIDCardExtendV20.struRegionCoordinates.fX,
struIDCardExtendV20.struRegionCoordinates.fY, struIDCardExtendV20.byThermometryUnit,
struIDCardExtendV20.byIsAbnomalTemperature);
}
}
//保存身份证图片数据大小
if (struIDCardInfo.dwPicDataLen > 0 && struIDCardInfo.pPicData != NULL && hasTemperature)
{
char cCardFilename[256] = { 0 };
char chTime[128];
sprintf_s(chTime, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d", struIDCardInfo.struSwipeTime.wYear, struIDCardInfo.struSwipeTime.byMonth,
struIDCardInfo.struSwipeTime.byDay, struIDCardInfo.struSwipeTime.byHour,
struIDCardInfo.struSwipeTime.byMinute, struIDCardInfo.struSwipeTime.bySecond);
// 拼接输出文件名称
sprintf_s(cCardFilename, "D:\\yourpath\\COMM_ID_INFO_ALARM_IDCardPic[%d][%s][%f][%s].jpg", pAlarmer->lUserID, chTime,
fCurrTemperature, gip);
FILE* fSnapPicPlate;
fopen_s(&fSnapPicPlate, cCardFilename, "wb");
fwrite(struIDCardInfo.pPicData, struIDCardInfo.dwPicDataLen, 1, fSnapPicPlate);
fclose(fSnapPicPlate);
iNum++;
}
//保存抓拍图片数据大小
if (struIDCardInfo.dwCapturePicDataLen > 0 && struIDCardInfo.pCapturePicData != NULL && hasTemperature)
{
char cFilename[256] = { 0 };
char chTime[128];
sprintf_s(chTime, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d", struIDCardInfo.struSwipeTime.wYear, struIDCardInfo.struSwipeTime.byMonth,
struIDCardInfo.struSwipeTime.byDay, struIDCardInfo.struSwipeTime.byHour,
struIDCardInfo.struSwipeTime.byMinute, struIDCardInfo.struSwipeTime.bySecond);
// 拼接输出文件名称
sprintf_s(cFilename, "D:\\yourpath\\COMM_ID_INFO_ALARM_CapPic[%d][%s][%f][%s].jpg", pAlarmer->lUserID, chTime,
fCurrTemperature, gip);
FILE* fSnapPicPlate;
fopen_s(&fSnapPicPlate, cFilename, "wb");
fwrite(struIDCardInfo.pCapturePicData, struIDCardInfo.dwCapturePicDataLen, 1, fSnapPicPlate);
fclose(fSnapPicPlate);
iNum++;
}
}
break;
default:
printf("其他报警,报警信息类型: %d\n", lCommand);
break;
}
return;
}
int main(int argc, char* argv[]) {
cout << "The program starts." << endl;
if (argc < 2) {
cout << "NoIP" << endl;
return 0;
}
char* ip = argv[1];
gip = ip;
cout << ip << endl;
//---------------------------------------
// 初始化
NET_DVR_Init();
char arr[] = "D:\\ws\\ry\\junan\\vclog\\temperature\\";
char* logFileDir = arr;
NET_DVR_SetLogToFile(3, logFileDir, FALSE);
//设置连接时间与重连时间
NET_DVR_SetConnectTime(2000, 1);
NET_DVR_SetReconnect(10000, true);
//---------------------------------------
// 注册设备
LONG lUserID;
//登录参数,包括设备地址、登录用户、密码等
NET_DVR_USER_LOGIN_INFO struLoginInfo = { 0 };
struLoginInfo.bUseAsynLogin = 0; //同步登录方式
strcpy_s(struLoginInfo.sDeviceAddress, ip); //设备IP地址
struLoginInfo.wPort = 8000; //设备服务端口
strcpy_s(struLoginInfo.sUserName, "your_username"); //设备登录用户名
strcpy_s(struLoginInfo.sPassword, "your_password"); //设备登录密码
//设备信息, 输出参数
NET_DVR_DEVICEINFO_V40 struDeviceInfoV40 = { 0 };
lUserID = NET_DVR_Login_V40(&struLoginInfo, &struDeviceInfoV40);
if (lUserID < 0)
{
printf("Login failed, error code: %d\n", NET_DVR_GetLastError());
NET_DVR_Cleanup();
return 0;
}
//设备登录成功,获取设备字符集编码类型
printf("Login successfully, byCharEncodeType: %d\n", struDeviceInfoV40.byCharEncodeType);
//设置报警回调函数
NET_DVR_SetDVRMessageCallBack_V50(0, MessageCallback, NULL);
//启用布防
LONG lHandle;
NET_DVR_SETUPALARM_PARAM struAlarmParam = { 0 };
struAlarmParam.dwSize = sizeof(struAlarmParam);
//不需要设置其他报警布防参数,不支持
lHandle = NET_DVR_SetupAlarmChan_V41(lUserID, &struAlarmParam);
if (lHandle < 0)
{
printf("NET_DVR_SetupAlarmChan_V41 failed, error code: %d\n", NET_DVR_GetLastError());
NET_DVR_Logout(lUserID);
NET_DVR_Cleanup();
return 0;
}
//事件信息在回调函数里面获取
//控制台输入q退出程序,否则一直运行
// char c = 0;
// while ('q' != c)
// {
// printf("input 'q' to quit\n");
// printf("input: ");
// scanf_s("%c", &c);
// }
Sleep(50000);
//---------------------------------------
//退出程序
//撤销布防上传通道
if (!NET_DVR_CloseAlarmChan_V30(lHandle))
{
printf("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;
}
依赖引入方法参考:【160】VS2022调试通过海康摄像头烟火识别SDK