海康sdk通过透传设置roi测温
参考:https://blog.csdn.net/Ai_Smith/article/details/122229577
通过透传修改测温规则
1.进入web端修改测温规则,保存后按F12复制请求正文
2.打开demo
3.测试透传是否成功
4.刷新浏览器看修改规则是否成功
5.写代码,pbuf是透传xml的规则,szurl是请求路径
void HK_Infrared::__SetRoiWithXML() { NET_DVR_XML_CONFIG_INPUT struInput = { 0 }; NET_DVR_XML_CONFIG_OUTPUT struOutput = { 0 }; struInput.dwSize = sizeof(struInput); struOutput.dwSize = sizeof(struOutput); //透传xml char * pBuf = ""; char szUrl[256] = {0}; sprintf(szUrl, "PUT /ISAPI/Thermal/channels/1/thermometry/1"); memset(&struInput, 0, sizeof(struInput)); memset(&struOutput, 0, sizeof(struOutput)); struInput.dwSize = sizeof(struInput); struOutput.dwSize = sizeof(struOutput); struInput.lpRequestUrl = szUrl; struInput.dwRequestUrlLen = strlen(szUrl); struInput.lpInBuffer = pBuf; struInput.dwInBufferSize = strlen(pBuf); if (!NET_DVR_STDXMLConfig(lUserID, &struInput, &struOutput)) printf("error\n"); else printf("success\n"); } 1 1000 1000 1 true 啊啊啊 region 30 876 94 434 355 453 348 842 meter 2 false point 500 500 meter 3 false point 500 500 meter 4 false point 500 500 meter 5 false point 500 500 meter 6 false point 500 500 meter 7 false point 500 500 meter 8 false point 500 500 meter 9 false point 500 500 meter 10 false point 500 500 meter 11 false point 500 500 meter 12 false point 500 500 meter 13 false point 500 500 meter 14 false point 500 500 meter 15 false point 500 500 meter 16 false point 500 500 meter 17 false point 500 500 meter 18 false point 500 500 meter
6.完整代码:
#define _CRT_SECURE_NO_WARNINGS #include#include #include "HK_Infrared.h" //时间解析宏定义 #define GET_YEAR(_time_) (((_time_)>>26) + 2000) #define GET_MONTH(_time_) (((_time_)>>22) & 15) #define GET_DAY(_time_) (((_time_)>>17) & 31) #define GET_HOUR(_time_) (((_time_)>>12) & 31) #define GET_MINUTE(_time_) (((_time_)>>6) & 63) #define GET_SECOND(_time_) (((_time_)>>0) & 63) int iNum = 0; #define ISAPI_OUT_LEN 3 * 1024 * 1024 #define ISAPI_STATUS_LEN 8*1024 //实时测温的回调 void CALLBACK GetThermInfoCallback(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData) { if (dwType == NET_SDK_CALLBACK_TYPE_DATA) { LPNET_DVR_THERMOMETRY_UPLOAD lpThermometry = new NET_DVR_THERMOMETRY_UPLOAD; memcpy(lpThermometry, lpBuffer, sizeof(*lpThermometry)); NET_DVR_TIME struAbsTime = { 0 }; struAbsTime.dwYear = GET_YEAR(lpThermometry->dwAbsTime); struAbsTime.dwMonth = GET_MONTH(lpThermometry->dwAbsTime); struAbsTime.dwDay = GET_DAY(lpThermometry->dwAbsTime); struAbsTime.dwHour = GET_HOUR(lpThermometry->dwAbsTime); struAbsTime.dwMinute = GET_MINUTE(lpThermometry->dwAbsTime); struAbsTime.dwSecond = GET_SECOND(lpThermometry->dwAbsTime); printf("实时测温结果:byRuleID[%d]wPresetNo[%d]byRuleCalibType[%d]byThermometryUnit[%d]byDataType[%d]" "dwAbsTime[%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d]\n", lpThermometry->byRuleID, lpThermometry->wPresetNo, lpThermometry->byRuleCalibType, lpThermometry->byThermometryUnit, lpThermometry->byDataType, struAbsTime.dwYear, struAbsTime.dwMonth, struAbsTime.dwDay, struAbsTime.dwHour, struAbsTime.dwMinute, struAbsTime.dwSecond); if (lpThermometry->byRuleCalibType == 0) //点测温 { printf("点测温信息:fTemperature[%f]\n", lpThermometry->struPointThermCfg.fTemperature); } //默认lpThermometry->byRuleCalibType == 1,框测温,有效点4个,(0,0),(1,0),(1,1),(1,0)(归一化后的值) if ((lpThermometry->byRuleCalibType == 1) || (lpThermometry->byRuleCalibType == 2)) //框/线测温 { printf("框/线测温信息:fMaxTemperature[%f]fMinTemperature[%f]fAverageTemperature[%f]fTemperatureDiff[%f]\n", lpThermometry->struLinePolygonThermCfg.fMaxTemperature, lpThermometry->struLinePolygonThermCfg.fMinTemperature, lpThermometry->struLinePolygonThermCfg.fAverageTemperature, lpThermometry->struLinePolygonThermCfg.fTemperatureDiff); } if (lpThermometry != NULL) { delete lpThermometry; lpThermometry = NULL; } } else if (dwType == NET_SDK_CALLBACK_TYPE_STATUS) { DWORD dwStatus = *(DWORD*)lpBuffer; if (dwStatus == NET_SDK_CALLBACK_STATUS_SUCCESS) { printf("dwStatus:NET_SDK_CALLBACK_STATUS_SUCCESS\n"); } else if (dwStatus == NET_SDK_CALLBACK_STATUS_FAILED) { DWORD dwErrCode = *(DWORD*)((char *)lpBuffer + 4); printf("NET_DVR_GET_MANUALTHERM_INFO failed, Error code %d\n", dwErrCode); } } } //手动测温的回调函数 void CALLBACK GetManualThermInfoCallback(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData) { if (dwType == NET_SDK_CALLBACK_TYPE_DATA) { LPNET_SDK_MANUAL_THERMOMETRY lpManualThermometry = new NET_SDK_MANUAL_THERMOMETRY; memcpy(lpManualThermometry, lpBuffer, sizeof(*lpManualThermometry)); NET_DVR_TIME struAbsTime = { 0 }; struAbsTime.dwYear = GET_YEAR(lpManualThermometry->dwAbsTime); struAbsTime.dwMonth = GET_MONTH(lpManualThermometry->dwAbsTime); struAbsTime.dwDay = GET_DAY(lpManualThermometry->dwAbsTime); struAbsTime.dwHour = GET_HOUR(lpManualThermometry->dwAbsTime); struAbsTime.dwMinute = GET_MINUTE(lpManualThermometry->dwAbsTime); struAbsTime.dwSecond = GET_SECOND(lpManualThermometry->dwAbsTime); printf("手动测温结果:dwChannel[%d]byThermometryUnit[d%]dwAbsTime[%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d]\n", lpManualThermometry->dwChannel, lpManualThermometry->byThermometryUnit, struAbsTime.dwYear, struAbsTime.dwMonth, struAbsTime.dwDay, struAbsTime.dwHour, struAbsTime.dwMinute, struAbsTime.dwSecond); if (lpManualThermometry != NULL) { delete lpManualThermometry; lpManualThermometry = NULL; } } else if (dwType == NET_SDK_CALLBACK_TYPE_STATUS) { DWORD dwStatus = *(DWORD*)lpBuffer; if (dwStatus == NET_SDK_CALLBACK_STATUS_SUCCESS) { printf("dwStatus:NET_SDK_CALLBACK_STATUS_SUCCESS\n"); } else if (dwStatus == NET_SDK_CALLBACK_STATUS_FAILED) { DWORD dwErrCode = *(DWORD*)((char *)lpBuffer + 4); printf("NET_DVR_GET_MANUALTHERM_INFO failed, Error code %d\n", dwErrCode); } } } HK_Infrared::HK_Infrared() { } HK_Infrared::~HK_Infrared() { } bool HK_Infrared::Init() { if (NET_DVR_Init()) { return true; } else { return false; } } bool HK_Infrared::Login(char* sIpAddress, char* sUserName, char* sPassword, WORD wPort) { //设置连接时间与重连时间 NET_DVR_SetConnectTime(2000, 1); NET_DVR_SetReconnect(10000, true); NET_DVR_USER_LOGIN_INFO loginInfo={0}; strcpy_s(loginInfo.sUserName, sUserName); strcpy_s(loginInfo.sDeviceAddress, sIpAddress); strcpy_s(loginInfo.sPassword, sPassword); loginInfo.wPort = wPort; loginInfo.bUseAsynLogin = 0;//同步登录方式 NET_DVR_DEVICEINFO_V40 devInfo={0}; this->lUserID = NET_DVR_Login_V40(&loginInfo, &devInfo); if (this->lUserID < 0) { cout << "Login Failed! error code: " << NET_DVR_GetLastError() << endl; return false; } else { cout << "Login Success!" << endl; return true; } } void HK_Infrared::Logout() { //注销用户 NET_DVR_Logout(this->lUserID); //释放sdk资源 NET_DVR_Cleanup(); } void HK_Infrared::__SetRoiWithXML() { NET_DVR_XML_CONFIG_INPUT struInput = { 0 }; NET_DVR_XML_CONFIG_OUTPUT struOutput = { 0 }; struInput.dwSize = sizeof(struInput); struOutput.dwSize = sizeof(struOutput); //透传xml char * pBuf = " "; char szUrl[256] = {0}; sprintf(szUrl, "PUT /ISAPI/Thermal/channels/1/thermometry/1"); memset(&struInput, 0, sizeof(struInput)); memset(&struOutput, 0, sizeof(struOutput)); struInput.dwSize = sizeof(struInput); struOutput.dwSize = sizeof(struOutput); struInput.lpRequestUrl = szUrl; struInput.dwRequestUrlLen = strlen(szUrl); struInput.lpInBuffer = pBuf; struInput.dwInBufferSize = strlen(pBuf); if (!NET_DVR_STDXMLConfig(lUserID, &struInput, &struOutput)) printf("error\n"); else printf("success\n"); } void HK_Infrared::RealTimeDetectTemperature() { DWORD dwChannel = 1;//热成像通道 char *m_pOutBuf = new char[ISAPI_OUT_LEN]; memset(m_pOutBuf, 0, ISAPI_OUT_LEN); char *m_pStatusBuf = new char[ISAPI_STATUS_LEN]; memset(m_pStatusBuf, 0, ISAPI_STATUS_LEN); //NET_DVR_STD_ABILITY struStdAbility = { 0 }; //struStdAbility.lpCondBuffer = &dwChannel; //struStdAbility.dwCondSize = sizeof(DWORD); //struStdAbility.lpOutBuffer = m_pOutBuf; //struStdAbility.dwOutSize = ISAPI_OUT_LEN; //struStdAbility.lpStatusBuffer = m_pStatusBuf; //struStdAbility.dwStatusSize = ISAPI_STATUS_LEN; ////测温能力集: ////NET_DVR_GET_MANUALTHERM_CAPABILITIES no ////NET_DVR_GET_THERMAL_CAPABILITIES ok ////NET_DVR_GET_FIREDETECTION_CAPABILITIES no ////NET_DVR_GET_THERMOMETRY_BASICPARAM_CAPABILITIES ok ////NET_DVR_GET_BAREDATAOVERLAY_CAPABILITIES no ////NET_DVR_GET_MANUALTHERM_CAPABILITIES no ////NET_DVR_GET_THERMAL_CAPABILITIES ok //if (!NET_DVR_GetSTDAbility(this->lUserID, NET_DVR_GET_THERMAL_CAPABILITIES, &struStdAbility)) //{ // //NET_DVR_GetLastError() 返回错误码: 23 设备不支持 // cout << "NET_DVR_GET_MANUALTHERM_CAPABILITIES failed, error code: " << NET_DVR_GetLastError() << endl; // return; //} //else //{ // cout << "NET_DVR_GET_MANUALTHERM_CAPABILITIES is successful!" << endl; //} //设置ROI测温 this->__SetRoiWithXML(); //启动实时温度检测 NET_DVR_REALTIME_THERMOMETRY_COND struThermCond = { 0 }; struThermCond.dwSize = sizeof(struThermCond); //规则ID,0代表获取全部规则,具体规则ID从1开始 /* 1 - 定时模式:设备每隔一秒上传各个规则测温数据的最高温、最低温和平均温度值、温差 2 - 温差模式:若上一秒与下一秒的最高温或者最低温或者平均温或者温差值的温差大于等于2摄氏度, 则上传最高温、最低温和平均温度值。若大于等于一个小时温差值均小于2摄氏度,则上传最高温、最低温、平均温和温差值 */ struThermCond.byRuleID = 0; struThermCond.dwChan = dwChannel; //struThermCond.byMode = 1; LONG lHandle = NET_DVR_StartRemoteConfig(this->lUserID, NET_DVR_GET_REALTIME_THERMOMETRY, &struThermCond, sizeof(struThermCond), GetThermInfoCallback, NULL); if (lHandle < 0) { cout << "NET_DVR_GET_REALTIME_THERMOMETRY failed, error code : " << NET_DVR_GetLastError() << endl; return; } else { cout << "NET_DVR_GET_REALTIME_THERMOMETRY is successful!" << endl; } Sleep(5000);//等待一段时间,接收手动测温结果 //关闭长连接配置接口所创建的句柄,释放资源 if (!NET_DVR_StopRemoteConfig(lHandle)) { cout << "NET_DVR_StopRemoteConfig failed, error code: " << NET_DVR_GetLastError() << endl; return; } } void HK_Infrared::ManualDetectTemperature() { DWORD dwChannel = 1;//热成像通道 char *m_pOutBuf = new char[ISAPI_OUT_LEN]; memset(m_pOutBuf, 0, ISAPI_OUT_LEN); char *m_pStatusBuf = new char[ISAPI_STATUS_LEN]; memset(m_pStatusBuf, 0, ISAPI_STATUS_LEN); //手动测温能力集 NET_DVR_STD_ABILITY struStdAbility = { 0 }; struStdAbility.lpCondBuffer = &dwChannel; struStdAbility.dwCondSize = sizeof(DWORD); struStdAbility.lpOutBuffer = m_pOutBuf; struStdAbility.dwOutSize = ISAPI_OUT_LEN; struStdAbility.lpStatusBuffer = m_pStatusBuf; struStdAbility.dwStatusSize = ISAPI_STATUS_LEN; //测温能力集: //NET_DVR_GET_MANUALTHERM_CAPABILITIES no //NET_DVR_GET_THERMAL_CAPABILITIES ok //NET_DVR_GET_FIREDETECTION_CAPABILITIES no //NET_DVR_GET_THERMOMETRY_BASICPARAM_CAPABILITIES ok //NET_DVR_GET_BAREDATAOVERLAY_CAPABILITIES no //NET_DVR_GET_MANUALTHERM_CAPABILITIES no if (!NET_DVR_GetSTDAbility(this->lUserID, NET_DVR_GET_MANUALTHERM_CAPABILITIES, &struStdAbility)) { //NET_DVR_GetLastError() 返回错误码: 23 设备不支持 cout << "NET_DVR_GET_MANUALTHERM_CAPABILITIES failed, error code: " << NET_DVR_GetLastError() << endl; return; } else { cout << "NET_DVR_GET_MANUALTHERM_CAPABILITIES is successful!" << endl; } //手动测温基本参数配置 /*手动测温的距离和发射率等参数可以通过NET_DVR_GetSTDConfig(命令: NET_DVR_GET_MANUALTHERM_BASICPARAM)、 *NET_DVR_SetSTDConfig(命令: NET_DVR_SET_MANUALTHERM_BASICPARAM)获取和设置。 *手动测温规则包括规则ID、检测类型(点、线、框)、 *区域等通过NET_DVR_SetSTDConfig(命令: NET_DVR_SET_MANUALTHERM)进行设置。*/ NET_DVR_STD_CONFIG struStdConfig = { 0 }; struStdConfig.lpCondBuffer = &dwChannel; struStdConfig.dwCondSize = sizeof(dwChannel); struStdConfig.lpInBuffer = NULL; struStdConfig.dwInSize = 0; NET_SDK_MANUALTHERM_BASICPARAM struManualThermBasicParam = { 0 }; struStdConfig.lpOutBuffer = (LPVOID)&struManualThermBasicParam; struStdConfig.dwOutSize = sizeof(struManualThermBasicParam); struStdConfig.lpStatusBuffer = m_pStatusBuf; struStdConfig.dwStatusSize = ISAPI_STATUS_LEN; DWORD dwReturned = 0; if (!NET_DVR_GetSTDConfig(this->lUserID, NET_DVR_GET_MANUALTHERM_BASICPARAM, &struStdConfig)) { cout << "NET_DVR_GET_MANUALTHERM failed, error code: " << NET_DVR_GetLastError() << endl; return; } else { cout << "NET_DVR_GET_MANUALTHERM is successful!" << endl; } struManualThermBasicParam.wDistance = 10;//距离(m)[0,10000] struStdConfig.lpInBuffer = (LPVOID)&struManualThermBasicParam; struStdConfig.dwInSize = sizeof(struManualThermBasicParam); if (!NET_DVR_SetSTDConfig(this->lUserID, NET_DVR_SET_MANUALTHERM_BASICPARAM, &struStdConfig)) { cout << "NET_DVR_SET_MANUALTHERM failed, error code: " << NET_DVR_GetLastError() << endl; return; } else { cout << "NET_DVR_SET_MANUALTHERM is successful!" << endl; } //手动测温规则配置 NET_SDK_MANUAL_THERMOMETRY struManualTherm = { 0 }; struManualTherm.dwSize = sizeof(struManualTherm); struManualTherm.dwChannel = dwChannel; struManualTherm.byThermometryUnit = 0; //测温单位: 0-摄氏度(℃),1-华氏度(℉),2-开尔文(K) struManualTherm.struRuleInfo.byRuleID = 1; struManualTherm.struRuleInfo.byEnable = 1; strcpy_s(struManualTherm.struRuleInfo.szRuleName, "TestName"); struManualTherm.struRuleInfo.byRuleCalibType = 0; struManualTherm.struRuleInfo.struPointTherm.struPoint.fX = 0.5; //归一化值,取值范围[0.001,1] struManualTherm.struRuleInfo.struPointTherm.struPoint.fY = 0.5; //归一化值,取值范围[0.001,1] struStdConfig.lpCondBuffer = &dwChannel; struStdConfig.dwCondSize = sizeof(dwChannel); struStdConfig.lpInBuffer = (LPVOID)&struManualTherm;; struStdConfig.dwInSize = sizeof(struManualTherm); if (!NET_DVR_SetSTDConfig(this->lUserID, NET_DVR_SET_MANUALTHERM, &struStdConfig)) { cout << "NET_DVR_SET_MANUALTHERM failed, error code:" << NET_DVR_GetLastError() << endl; return; } else { cout << "NET_DVR_SET_MANUALTHERM is successful!" << endl; } //启动手动测温 NET_DVR_REALTIME_THERMOMETRY_COND struThermCond = { 0 }; struThermCond.dwSize = sizeof(struThermCond); //规则ID,0代表获取全部规则,具体规则ID从1开始 /* 1 - 定时模式:设备每隔一秒上传各个规则测温数据的最高温、最低温和平均温度值、温差 2 - 温差模式:若上一秒与下一秒的最高温或者最低温或者平均温或者温差值的温差大于等于2摄氏度, 则上传最高温、最低温和平均温度值。若大于等于一个小时温差值均小于2摄氏度,则上传最高温、最低温、平均温和温差值 */ struThermCond.byRuleID = 1; struThermCond.dwChan = dwChannel; LONG ManualHandle = NET_DVR_StartRemoteConfig(this->lUserID, NET_DVR_GET_MANUALTHERM_INFO, &struThermCond, sizeof(struThermCond), GetManualThermInfoCallback, NULL); if (ManualHandle < 0) { cout << "NET_DVR_GET_MANUALTHERM_INFO failed, error code : " << NET_DVR_GetLastError() << endl; return; } else { cout << "NET_DVR_GET_MANUALTHERM_INFO is successful!" << endl; } Sleep(5000);//等待一段时间,接收手动测温结果 //关闭长连接配置接口所创建的句柄,释放资源 if (!NET_DVR_StopRemoteConfig(ManualHandle)) { cout << "NET_DVR_StopRemoteConfig failed, error code: " << NET_DVR_GetLastError() << endl; return; } if (m_pOutBuf != NULL) { delete[]m_pOutBuf; m_pOutBuf = NULL; } if (m_pStatusBuf != NULL) { delete[]m_pStatusBuf; m_pStatusBuf = NULL; } } 1 1000 1000 1 true 啊啊啊 region 30 876 94 434 355 453 348 842 meter 2 false point 500 500 meter 3 false point 500 500 meter 4 false point 500 500 meter 5 false point 500 500 meter 6 false point 500 500 meter 7 false point 500 500 meter 8 false point 500 500 meter 9 false point 500 500 meter 10 false point 500 500 meter 11 false point 500 500 meter 12 false point 500 500 meter 13 false point 500 500 meter 14 false point 500 500 meter 15 false point 500 500 meter 16 false point 500 500 meter 17 false point 500 500 meter 18 false point 500 500 meter