public Map<String, Double> locate(int targetX, int targetY, Map<String, Double> posOnvif) { //Map<String, Double> posOnvif onvif 獲取當前狀態下的 ptz 座標 // 直接使用 posOnvif 來計算 SDK 座標 // 水平視場角(參照《視場角相關計算》,透過相機標定,獲取畫素焦) double fovH = 37.75; double fovV = 21.80; // 垂直視場角 int width = 2560; // 影像寬度 int height = 1440; // 影像高度 Map<String, Double> posSdk = new HashMap<>(); double pan = posOnvif.get("pan"); double tilt = posOnvif.get("tilt"); double zoom = posOnvif.get("zoom"); // 計算水平方向的偏移量 deltX double deltX = 0; if (targetX > (width / 2)) { deltX = Math.toDegrees(Math.atan((targetX - width / 2) / (width / 2) * Math.tan(Math.toRadians(fovH / 2)))); } else { deltX = -Math.toDegrees(Math.atan((width / 2 - targetX) / (width / 2) * Math.tan(Math.toRadians(fovH / 2)))); } // 計算垂直方向的偏移量 deltY double deltY = 0; if (targetY > (height / 2)) { deltY = Math.toDegrees(Math.atan((targetY - height / 2) / (height / 2) * Math.tan(Math.toRadians(fovV / 2)))); } else { deltY = -Math.toDegrees(Math.atan((height / 2 - targetY) / (height / 2) * Math.tan(Math.toRadians(fovV / 2)))); } // 更新 SDK 的 PTZ 座標 posSdk.put("pan", pan + deltX); posSdk.put("tilt", tilt - deltY); // 注意:SDK 是倒置的,所以需要減去 deltY posSdk.put("zoom", zoom); return posSdk; }