海康相机 像素坐标(px,py)到sdk ptz 坐标转换最后到onvif ptz坐标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
                                     基于当前相机PTZ位置的相对定位坐标计算
 
// ONVIF 坐标转为 SDK 坐标
    public Map<String, Double> ONvifFPtzToSdk(Map<String, Float> posOnvif) {
        Map<String, Double> posSdk = new HashMap<>();
        double panSdk = Math.min(180 * posOnvif.get("pan") + 180, 360);
        double tiltSdk = 45 * posOnvif.get("tilt") + 45;
        double zoomSdk = 3 * posOnvif.get("zoom") + 1;
        posSdk.put("pan", panSdk);
        posSdk.put("tilt", tiltSdk);
        posSdk.put("zoom", zoomSdk);
        return posSdk;
    }
 
    // SDK 坐标转为 ONVIF 坐标
    public Map<String, Float> SDKPtzToOnvif(Map<String, Double> posSdk) {
        Map<String, Float> posOnvif = new HashMap<>();
        float panOnvif = (float) ((posSdk.get("pan") - 180) / 180);
        float tiltOnvif = (float) ((posSdk.get("tilt") - 45) / 45);
        float zoomOnvif = (float) ((posSdk.get("zoom") - 1) / 3);
        posOnvif.put("pan", panOnvif);
        posOnvif.put("tilt", tiltOnvif);
        posOnvif.put("zoom", zoomOnvif);
        return posOnvif;
    }
    /****
     *
     * @param targetX 像素坐标
     * @param targetY 像素坐标
     * @param posOnvif
     * @return
     */
    public Map<String, Float> locate(int targetX, int targetY,  Map<String, Float>  posOnvif) {
        // 将 ONVIF 坐标转换为 SDK 坐标
        Map<String, Double> posSdk = ONvifFPtzToSdk(posOnvif);
        //Map<String, Double> posOnvif  onvif 获取当前状态下的 ptz 坐标
        // 直接使用 posOnvif 来计算 SDK 坐标
        // 水平视场角(参照《视场角相关计算》,通过相机标定,获取像素焦)
        double fovH = 37.75;
 
        double fovV = 21.80; // 垂直视场角
        int width = 2560;    // 图像宽度
        int height = 1440;   // 图像高度
 
        // 计算水平方向的偏移量 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", posSdk.get("pan") + deltX);
        posSdk.put("tilt", posSdk.get("tilt") - deltY); // 注意:SDK 是倒置的,所以需要减去 deltY
         
        // 将 SDK 坐标转换回 ONVIF 坐标
        return SDKPtzToOnvif(posSdk);
    }
  

  

posted @   Fitz  阅读(110)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示