C#上位机实战:基于海康威视SDK的热成像测温系统开发

发布时间:2026/9/1 7:44:08
C#上位机实战:基于海康威视SDK的热成像测温系统开发 简介面向需要在.NET环境下对接海康威视热成像设备的开发者这份C#海康SDK测温项目源码提供了完整的热成像测温功能参考实现适用于工业巡检、安防监控、电力设备温度预警等需要温度实时监测的场景。资源包共12个文件整体仅19KB其中4个C#脚本承担SDK调用与测温核心逻辑2个json文件用于项目配置并搭配Unity场景、asset资源及说明文档目录按Assets/Scenes/Scripts分层结构清晰。源码覆盖SDK初始化、设备登录、测温区域与最高温度阈值设置、实时测温回调处理、停止测温等完整流程同时提供截图保存、错误处理与资源释放示例。已有76人学习/下载。对刚接触海康SDK或希望在Unity/C#应用中快速集成热成像测温的开发者这份轻量级源码可直接作为基础框架减少接口联调与底层兼容性排查的工作量帮助快速搭建具备实时测温能力的软件原型或演示项目。1. 项目从哪来产线设备测温的真实需求前阵子我接了一个产线设备在线测温的项目现场有七八台传动设备和几个电柜需要24小时监控轴承座、电机外壳和母线排的表面温度超过阈值要联动声光报警温度数据要留痕做趋势分析。设备端清一色的海康威视热成像网络相机客户看完海康自带的客户端之后还是决定让我用 C# 写一套上位机。原因很现实现场相机分散在不同位置要集中显示在一面大屏上报警信息要对接厂里的数据库操作界面要按班组使用习惯定制。这些需求用官方客户端很难满足。这套项目最后整理成了一份完整源码代号就叫 HikThermalDemo。核心就三块用 C# 封装海康设备网络 SDK把热成像相机拉流预览再通过 SDK 的测温能力拿到点、线、区域的温度值做报警和存储。文章会把选型理由、每一步的原理、关键代码和实测踩坑全部讲清楚。适合手里正拿着海康热成像相机准备用 WinForms 快速做一版测温上位机的朋友也想给打算深入 P/Invoke 调用海康 SDK 的读者一个完整的技术路线参考。选 C# WinForms 不是情怀问题。海康设备网络 SDK 的底层是 C/C 动态库但官方 demo 里提供了完整的 C# 工程P/Invoke 直调 HCNetSDK.dll 就能把相机接入上位机。对交付周期短、界面要反复改的现场项目来说WinForms 比 C 开发效率高得多比 Web 拉流稳得多现场电脑往往没装浏览器插件也没条件依赖外网环境。这个项目里我没有引入任何重框架全部基于 .NET Framework 4.7.2原生 DLL 负责底层托管层只做封装和业务逻辑。2. 动手前的准备SDK 包结构、运行库和开发环境海康设备网络 SDK 从官网下载后解压出来的目录通常包含 doc文档、includeC/C 头文件、lib各平台动态库、demo各语言示例工程。我第一次做的时候习惯先去翻 C# demo把里面的结构体定义和 P/Invoke 声明直接拿来改比自己重写省很多事。真正放到项目里用的 DLL 其实就那么几个缺一个都会运行时报错。DLL 文件作用HCNetSDK.dll核心业务库登录、配置、预览、报警等所有主流程入口HCCore.dll基础依赖库HCNetSDK 正常工作必须加载PlayCtrl.dll播放库负责码流解码和画面渲染hlog.dllSDK 日志组件排查问题时很关键zlib1.dll压缩解压依赖部分设备通信需要AudioRender.dll音频渲染本项目没用到但建议一起拷过去一个特别容易翻车的点是位数匹配。海康官方 C# demo 默认按 x86 编译而很多人建项目时随手选了 x64结果一运行就抛 BadImageFormatException或者干脆 DLL 加载失败。我在这个项目里选的就是 x86因为老版本 SDK 对 32 位进程兼容性最稳定。如果你的项目用了 64 位第三方控件、内存确实紧张那就整套都用 64 位 SDK关键是进程位数、托管代码 Platform Target、原生 DLL 三者必须一致。C# 侧封装海康 SDK 的写法核心是 DllImport 加结构体定义。下面这是登录接口的示意代码结构体字段顺序必须和头文件完全一致少一个字段或类型对不上轻则返回密码错误重则直接 AccessViolationException[StructLayout(LayoutKind.Sequential, CharSet CharSet.Ansi)] public struct NET_DVR_USER_LOGIN_INFO { [MarshalAs(UnmanagedType.ByValTStr, SizeConst 129)] public string sDeviceAddress; public ushort wPort; [MarshalAs(UnmanagedType.ByValTStr, SizeConst 64)] public string sUserName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst 64)] public string sPassword; // 后续还有一堆保留字段务必按头文件补全 } [DllImport(HCNetSDK.dll)] public static extern int NET_DVR_Login_V40( ref NET_DVR_USER_LOGIN_INFO pLoginInfo, ref NET_DVR_DEVICEINFO_V40 lpDeviceInfo);写这种封装最容易犯的错是自行精简结构体。C 语言结构体里那些保留字段很多 SDK 内部会做内存校验字节长度不对就会报错。我建议直接从官方 C# demo 拷贝结构体定义不要自己重写。3. 测温功能是这样做出来的从登录到拿到温度的完整链路3.1 登录设备和实时预览通道号不是随便填的拿到 SDK 依赖之后第一步流程很固定NET_DVR_Init()初始化然后NET_DVR_Login_V40()登录登录成功拿到 userId后面所有操作都靠这个 userId 传递。登录参数就是 IP、端口、用户名、密码端口在海康设备上默认是 8000但热成像相机的固件里有的是 8000有的改过最好先用海康 SADP 工具确认一遍。预览这里有一个项目里最容易卡住的细节热成像相机的通道号映射。双光谱相机通常同时存在热成像通道和可见光通道两者在 SDK 里的通道编号不一定是 1。我在现场就遇到过登录成功后用通道 1 拉出来的是一路可见光画面温度数据怎么都拿不到。排查办法很简单用海康自带客户端看设备通道列表记住热成像画面对应的通道号再在代码里用那个通道去做NET_DVR_RealPlay_V40预览。3.2 开启测温并设置核心参数先读后写才是正确姿势测温功能不是登录就能用的设备端默认可能没开测温模式。这一步的接口逻辑是先通过NET_DVR_GetDVRConfig读当前的测温配置改完需要的字段再NET_DVR_SetDVRConfig写回去。我见过很多人直接把结构体 new 成空对象就 Set 上去结果把设备里的加密配置、其他功能开关一并清掉了。正确操作永远是先把当前值读出来再对指定字段做修改。这一步涉及的几个核心参数分别为测温模式工业测温还是人体测温、发射率、目标距离、环境温度和反射温度。项目做的是设备表面测温必须选工业测温模式如果误选人体测温模式SDK 会按人体皮肤发射率做补偿测金属表面会差出一大截。发射率是最敏感的参数不同材料表面发射率差异巨大放几组常用值做个参考被测表面发射率参考值氧化钢铁表面0.75 ~ 0.95抛光铝0.04 ~ 0.10氧化铝0.76 ~ 0.80混凝土/砖墙0.92 ~ 0.96黑胶带校准用约 0.95发射率设置错了测出来的就不是真实温度而是“等效辐射温度”。比如抛光金属反射了周围环境辐射测温值会偏得离谱这种场景光靠调发射率还不够需要调整拍摄角度、减少反射干扰。距离参数影响的是大气透过率计算短距离时影响不大但超过 5 米建议按实际安装距离填准。3.3 配置点、线、区域测温规则海康热成像相机的测温规则分点测温、线测温、区域测温三类。点测温给一个坐标点测的是该点温度线测温会给一条线段上的最低、最高、平均温度区域测温则给出区域内的最高、最低、平均温度。坐标走的是归一化方式范围 0 到 10000而不是像素坐标这样不同分辨率下规则位置不会漂移。设置规则的示意代码如下一个点位结构体包含名称、坐标和返回的温度字段规则有数量上限不同型号相机支持的点位数量差别很大现场需要测多少点就配多少点别一上来堆几十个NET_DVR_THERMALPOINT_BLOCK pt new NET_DVR_THERMALPOINT_BLOCK(); pt.dwSize (uint)Marshal.SizeOf(typeof(NET_DVR_THERMALPOINT_BLOCK)); // 名称按设备要求中文要转 GBK pt.byPointName Encoding.Default.GetBytes(电机轴承); pt.struPoint.x 3000; // 归一化坐标 0~10000 pt.struPoint.y 4000; bool ret NET_DVR_SetDVRConfig( userId, NET_DVR_SET_THERMAL_POINT, channel, ref pt, (uint)Marshal.SizeOf(pt)); if (!ret) { int error NET_DVR_GetLastError(); }每次配置完都应该检查返回值失败时用NET_DVR_GetLastError()拿错误码别蒙着眼往下走。规则坐标如果落在热像视野之外或超出相机可测温区域设备往往静默失败但返回码会有提示。3.4 拿到实时温度的两种路线轮询和回调解析测温数据拿回来业界主要有两条路线。第一是轮询定时器每隔 0.5 到 1 秒调一次NET_DVR_GetDVRConfig把点位、区域结构体读回来温度字段直接可用。这个方案简单、稳定、调试方便工业监控场景 1 秒的刷新率完全够用本项目用的就是这一种。第二是解析实时流里的原始热像数据帧从预览回调里拿到 16 位的温度原始数据再结合设备下发的标定信息换算成温度矩阵。这种做法的好处是可以自己渲染热像图、任意画区域做分析缺点是工作量翻倍要处理数据帧分割、内存拷贝、色标映射和标定参数换算而且不同固件的数据格式还有差异。如果只是做监测报警我真心建议先走轮询路线把业务跑通再考虑要不要做热像图渲染。4. 超温报警与温度数据落库别让测温功能只停留在界面上温度显示在界面上只是第一步现场真正关心的是“超温了怎么办”。我把报警做成了软件侧判定没有依赖设备本身的报警联动原因是软件侧逻辑可视化、可配置客户换一个温度阈值不用进设备网页改配置。报警判定我加了回差和消抖比如母线排报警阈值 75℃回差设置 3℃也就是温度上到 75℃ 触发报警掉到 72℃ 才算恢复。如果没有回差温度在阈值附近波动时报警会反复抖动现场很烦人。报警事件不能每次轮询都往数据库写一条。我维护了一个报警状态机只有状态翻转的时候才记录事件比如“正常 - 超温报警”写一条“超温报警 - 恢复”写一条。这样数据库里留下的都是有效事件后续追溯问题非常清爽。报警级别也可以分预报警和报警两档55℃ 提醒、65℃ 告警不同档位走不同的通知渠道。数据落库我选的是 SQLite单机版现场部署最省事一个文件搞定不用装数据库服务。温度表结构很简单设备ID、规则ID、当前温度、最高温度、最低温度、平均温度、时间戳。这里有个细节要注意如果每个规则每秒钟存一条3 台设备 4 个规则一天就超过 100 万行量不小。我实际做的时候降低了采样频率每 5 秒存一条同时只存区域里的最高温和平均温数据量降了一个数量级趋势分析完全够用。历史曲线用 WinForms 自带的 Chart 控件本文还有配套的精品资源点击获取

相关新闻