Итак, я пытаюсь считать тепловые данные с IP-камеры Dahua модели TPC-BF5401. Мне не удалось найти каких-либо подробных документов, поэтому я просто прочитал руководство и попытался следовать примерам, включенным в SDK, по адресу https://depp.dahuasecurity.com/integrat ... wnload/SDK (я использую версию Java x64 в Linux). Мне удалось прочитать температуру по точкам с помощью этого скрипта
package com.netsdk.demo.frame;
import java.io.File;
import java.util.Scanner;
import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.NetSDKLib.*;
import com.netsdk.lib.ToolKits;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
/**
* Console demo:
* - Init SDK
* - Login to camera
* - Query temperature at a given (x,y) pixel coordinate on a channel
* - Print the result
*/
public class QueryTempEx {
public static final NetSDKLib netSdk = NetSDKLib.NETSDK_INSTANCE;
private LLong loginHandle = new LLong(0);
private NET_DEVICEINFO_Ex deviceInfo = new NET_DEVICEINFO_Ex();
/**
* SDK init + log settings (similar to RealplayEx.InitTest)
*/
public void initSdk() {
netSdk.CLIENT_Init(DisConnectCallBack.getInstance(), null);
netSdk.CLIENT_SetAutoReconnect(HaveReConnectCallBack.getInstance(), null);
NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO();
String logPath = new File(".").getAbsoluteFile().getParent()
+ File.separator + "sdk_log" + File.separator + "sdk.log";
setLog.bSetFilePath = 1;
System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length);
setLog.bSetPrintStrategy = 1;
setLog.nPrintStrategy = 0;
if (!netSdk.CLIENT_LogOpen(setLog)) {
System.err.println("Open SDK Log Failed!!!");
}
}
/**
* Login to device (similar style to RealplayEx.Login)
*/
public void login(String ip, int port, String user, String password) {
int nSpecCap = NetSDKLib.EM_LOGIN_SPAC_CAP_TYPE.EM_LOGIN_SPEC_CAP_TCP; // TCP login
IntByReference nError = new IntByReference(0);
loginHandle = netSdk.CLIENT_LoginEx2(
ip,
port,
user,
password,
nSpecCap,
null,
deviceInfo,
nError);
if (loginHandle.longValue() != 0) {
System.out.printf("Login Device[%s] Success!\n", ip);
} else {
System.err.printf("Login Device[%s] Fail. Error[0x%x]\n",
ip, netSdk.CLIENT_GetLastError());
logoutAndCleanup();
}
}
/**
* Query temperature at a single (x,y) pixel on a channel..
*/
public NET_RADIOMETRYINFO queryPointTemper(int channel, short x, short y) {
int nQueryType = NetSDKLib.NET_QUERY_DEV_RADIOMETRY_POINT_TEMPER;
NET_IN_RADIOMETRY_GETPOINTTEMPER stIn = new NET_IN_RADIOMETRY_GETPOINTTEMPER();
stIn.nChannel = channel;
stIn.stCoordinate.nx = x;
stIn.stCoordinate.ny = y;
NET_OUT_RADIOMETRY_GETPOINTTEMPER stOut = new NET_OUT_RADIOMETRY_GETPOINTTEMPER();
stIn.write();
stOut.write();
boolean bRet = netSdk.CLIENT_QueryDevInfo(
loginHandle,
nQueryType,
stIn.getPointer(),
stOut.getPointer(),
null,
3000);
if (!bRet) {
System.err.printf("QueryPointTemper Failed! %s\n", ToolKits.getErrorCodePrint());
return null;
}
stOut.read();
return stOut.stPointTempInfo; // This struct holds the temperature info
}
/**
* Logout + cleanup (similar to RealplayEx.LoginOut but without System.exit)
*/
public void logoutAndCleanup() {
System.out.println("End Test");
if (loginHandle.longValue() != 0) {
netSdk.CLIENT_Logout(loginHandle);
loginHandle.setValue(0);
}
System.out.println("See You...");
netSdk.CLIENT_Cleanup();
}
/**
* Disconnect callback (copied from RealplayEx)
*/
private static class DisConnectCallBack implements NetSDKLib.fDisConnect {
private DisConnectCallBack() {}
private static class CallBackHolder {
private static final DisConnectCallBack instance = new DisConnectCallBack();
}
public static DisConnectCallBack getInstance() {
return CallBackHolder.instance;
}
@Override
public void invoke(NetSDKLib.LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) {
System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort);
}
}
/**
* Reconnect callback (copied from RealplayEx)
*/
private static class HaveReConnectCallBack implements NetSDKLib.fHaveReConnect {
private HaveReConnectCallBack() {}
private static class CallBackHolder {
private static final HaveReConnectCallBack instance = new HaveReConnectCallBack();
}
public static HaveReConnectCallBack getInstance() {
return CallBackHolder.instance;
}
@Override
public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) {
System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort);
}
}
/**
* Main – console app:
*/
public static void main(String[] args) {
QueryTempEx app = new QueryTempEx();
Scanner scanner = new Scanner(System.in);
// --- Default login config (you can edit these) ---
String ip = "0.0.0.0";
int port = 37777;
String username = "admin";
String password = "password";
String defaultConfig = String.format(
"ip:%s, port:%d, username:%s, password:%s, 需要修改吗?(y/n)",
ip, port, username, password);
System.out.println(defaultConfig);
String answer = "";
do {
answer = scanner.nextLine();
if ("y".equalsIgnoreCase(answer) || "yes".equalsIgnoreCase(answer)) {
System.out.println("please input ip:");
ip = scanner.nextLine().trim();
System.out.println("please input port:");
port = Integer.parseInt(scanner.nextLine().trim());
System.out.println("please input username:");
username = scanner.nextLine().trim();
System.out.println("please input password:");
password = scanner.nextLine().trim();
break;
} else if ("n".equalsIgnoreCase(answer) || "no".equalsIgnoreCase(answer)) {
break;
}
System.out.println("please input the right word. y/yes/n/no, try again.");
} while (!(answer.equalsIgnoreCase("y")
|| answer.equalsIgnoreCase("yes")
|| answer.equalsIgnoreCase("no")
|| answer.equalsIgnoreCase("n")));
// --- Init + Login ---
app.initSdk();
app.login(ip, port, username, password);
// --- Ask for channel + pixel coordinates ---
try {
System.out.println("please input channel (default 0):");
String chStr = scanner.nextLine().trim();
int channel = chStr.isEmpty() ? 0 : Integer.parseInt(chStr);
System.out.println("please input x coordinate (pixel, short):");
short x = Short.parseShort(scanner.nextLine().trim());
System.out.println("please input y coordinate (pixel, short):");
short y = Short.parseShort(scanner.nextLine().trim());
// --- Query temperature ---
NET_RADIOMETRYINFO info = app.queryPointTemper(channel, x, y);
if (info == null) {
System.err.println("Failed to get temperature info.");
} else {
System.out.println("Got radiometry info for point (" + x + ", " + y + ") on channel " + channel);
// Basic dump (at least this always compiles)
System.out.println("Radiometry info struct: " + info.toString());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
app.logoutAndCleanup();
scanner.close();
}
}
}
(этот сценарий очень похож на пример RealplayEx, который поставляется вместе с SDK, если вы знакомы. Просто заполняет структуру информации о точке значениями пикселей x и y, и она возвращает временные данные)
Теперь проблема в том, что я хочу читать тепловые данные по регионам, а не по точкам. Я добавляю в приведенный выше скрипт следующую функцию:
Согласно интернет-источникам, эта строка на китайском языке вместе с кодом ошибки 21 может указывать на то, что проблема либо:
камера настроена неправильно
неправильная структура ответа
Здесь я застрял. Ошибка возникает внутри динамически связанной библиотеки, поэтому я не знаю, что делать. Кроме того, мне еще предстоит точно определить, какой идентификатор правила и идентификатор предварительной настройки для настройки на камеру и обратно, идентификатор правила региона/прямоугольника/многоугольника и идентификатор предварительной настройки PTZ, я полагаю? И канал, кажется, всегда 0, а счетчик типа 1, поправьте меня, если я ошибаюсь? У кого-нибудь была такая же проблема, поделитесь чем-нибудь?
Итак, я пытаюсь считать тепловые данные с IP-камеры Dahua модели TPC-BF5401. Мне не удалось найти каких-либо подробных документов, поэтому я просто прочитал руководство и попытался следовать примерам, включенным в SDK, по адресу https://depp.dahuasecurity.com/integration/guide/download/SDK (я использую версию Java x64 в Linux). Мне удалось прочитать температуру по точкам с помощью этого скрипта [code]package com.netsdk.demo.frame;
/** * Console demo: * - Init SDK * - Login to camera * - Query temperature at a given (x,y) pixel coordinate on a channel * - Print the result */ public class QueryTempEx {
public static final NetSDKLib netSdk = NetSDKLib.NETSDK_INSTANCE;
private LLong loginHandle = new LLong(0);
private NET_DEVICEINFO_Ex deviceInfo = new NET_DEVICEINFO_Ex();
/** * SDK init + log settings (similar to RealplayEx.InitTest) */ public void initSdk() { netSdk.CLIENT_Init(DisConnectCallBack.getInstance(), null); netSdk.CLIENT_SetAutoReconnect(HaveReConnectCallBack.getInstance(), null);
/** * Query temperature at a single (x,y) pixel on a channel.. */ public NET_RADIOMETRYINFO queryPointTemper(int channel, short x, short y) { int nQueryType = NetSDKLib.NET_QUERY_DEV_RADIOMETRY_POINT_TEMPER;
System.out.println("please input x coordinate (pixel, short):"); short x = Short.parseShort(scanner.nextLine().trim());
System.out.println("please input y coordinate (pixel, short):"); short y = Short.parseShort(scanner.nextLine().trim());
// --- Query temperature --- NET_RADIOMETRYINFO info = app.queryPointTemper(channel, x, y);
if (info == null) { System.err.println("Failed to get temperature info."); } else { System.out.println("Got radiometry info for point (" + x + ", " + y + ") on channel " + channel);
// Basic dump (at least this always compiles) System.out.println("Radiometry info struct: " + info.toString());
[/code] (этот сценарий очень похож на пример RealplayEx, который поставляется вместе с SDK, если вы знакомы. Просто заполняет структуру информации о точке значениями пикселей x и y, и она возвращает временные данные) Теперь проблема в том, что я хочу читать тепловые данные по регионам, а не по точкам. Я добавляю в приведенный выше скрипт следующую функцию: [code] public NET_RADIOMETRYINFO queryTemper(int channel, int presetID, int ruleID, int nMeterType) { int nQueryType = NetSDKLib.NET_QUERY_DEV_RADIOMETRY_TEMPER;
if (!bRet) { System.err.printf("QueryTemper Failed! %s\n", ToolKits.getErrorCodePrint()); return null; }
stOut.read(); return stOut.stTempInfo; } [/code] и вызвать его с помощью [code] NET_RADIOMETRYINFO info = app.queryTemper(channel, presetID, ruleID, meterType); [/code] Все комбинации (канал, PresetID, RuleID, MeterType), которые я пробовал, возвращают это: [code]Login Device[192.168.127.108] Success! please input channel (default 0): 0 please input presetID (default 0): 1 please input ruleID (default 0): 1 please input meterType (default 0): 1 QueryTemper Failed! {error code: (0x80000000|21).参考 NetSDKLib.java } - {error info:对返回数据的校验出错} [/code] Согласно интернет-источникам, эта строка на китайском языке вместе с кодом ошибки 21 может указывать на то, что проблема либо: [list] [*]камера настроена неправильно [*]неправильная структура ответа [/list] Здесь я застрял. Ошибка возникает внутри динамически связанной библиотеки, поэтому я не знаю, что делать. Кроме того, мне еще предстоит точно определить, какой идентификатор правила и идентификатор предварительной настройки для настройки на камеру и обратно, идентификатор правила региона/прямоугольника/многоугольника и идентификатор предварительной настройки PTZ, я полагаю? И канал, кажется, всегда 0, а счетчик типа 1, поправьте меня, если я ошибаюсь? У кого-нибудь была такая же проблема, поделитесь чем-нибудь?