海康相机 像素坐标(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); } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具