如何降低海康、大华等网络摄像头调用的高延迟问题(一):海康威视网络摄像头的python sdk使用(opencv读取sdk流)

目录

1.python sdk使用

1.海康SDK下载

 2.opencv读取sdk流


 先说效果,我是用的AI推理的实时流,延迟从高达7秒降到小于1秒

如果觉得这个延迟还不能接受,下一章,给大家介绍点上不得台面的小方法

SDK(Software Development Kit)是软件开发工具包的缩写,它是一组用于开发特定软件或应用程序的工具、库和文档的集合。SDK提供了开发所需的资源和接口,帮助开发者更高效地构建应用程序。

SDK通常包含以下内容:

  1. 工具:SDK提供了一系列开发工具,如编译器、调试器、IDE(集成开发环境)等,用于编写、调试和测试代码。
  2. 库:SDK中的库是预先编译好的可重用代码模块,包含常见的功能和算法,开发者可以直接调用这些库来简化开发过程。
  3. 示例代码:SDK通常附带一些示例代码,展示如何使用SDK提供的功能和接口,帮助开发者快速上手并理解开发流程。
  4. 文档:SDK提供详细的文档,包括API参考、开发指南、示例代码解释等,帮助开发者了解SDK的功能和使用方法。
  5. 依赖项:SDK可能需要依赖其他软件或库,例如操作系统、第三方库等,开发者需要满足这些依赖关系才能使用SDK。

SDK的作用是简化开发过程,提供开发所需的资源和接口,节省开发者的时间和精力。通过使用SDK,开发者可以快速构建功能丰富、高效的应用程序,而无需从头开始编写所有的代码和功能。

1.python sdk使用

之前常常采用python来读取usb摄像头,因为其语言风格易读且上手快。起先,使用rtsp流来读海康的网络相机,视频画面出现延迟卡顿的现象,如果对于实时性要求较高(起码得和网页预览效果相当的帧率)的话,用rtsp流读取的方式显得不可取,本文采用在python中调用HikVision的SDK读取IP相机的方式实现,帧率的话和网络预览效果相当

1.海康SDK下载

 

下载好解压后

进入以下路径

海康威视-HCNetSDKV6.1.9.48_build20230410_win64---Demo示例---5- Python开发示例---1-预览取流解码Demo

1.找到这个lib路径,里面应该是空的

看需要选择win或者linux

2.返回主目录,选择库文件,复制全部文件(实际按官方文档只需要部分库文件,不过可以傻瓜式全部打包),粘贴到上面的lib文件夹的win文件中

下面是官方文档的操作说明

1. 更新设备网络SDK时,SDK开发包【库文件】里的HCNetSDK.dll、HCCore.dll、HCNetSDKCom文件夹、libssl-1_1.dll、libcrypto-1_1.dll、hlog.dll、hpr.dll、zlib1.dll、PlayCtrl.dll、SuperRender.dll、AudioRender.dll等文件均要加载到程序里面,【HCNetSDKCom文件夹】(包含里面的功能组件dll库文件)需要和HCNetSDK.dll、HCCore.dll一起加载,放在同一个目录下,且HCNetSDKCom文件夹名不能修改。

2. 如果自行开发软件不能正常实现相应功能,而且程序没有指定加载的dll库路径,请在程序运行的情况下尝试删除HCNetSDK.dll。如果可以删除,说明程序可能调用到系统盘Windows->System32目录下的dll文件,建议删除或者更新该目录下的相关dll文件;如果不能删除,dll文件右键选择属性确认SDK库版本。

3. 如按上述步骤操作后还是不能实现相应功能,请根据NET_DVR_GetLastError返回的错误号判断原因。

3.运行test_main.py

获取实时画面

 2.opencv读取sdk流

将下面代码贴到test_main.py的同级目录下

运行即可

有问题的朋友欢迎评论区留言

# coding=utf-8
import os
import platform
from HCNetSDK import *
from PlayCtrl import *
import numpy as np
import time
import cv2class HKCam(object):def __init__(self,camIP,username,password,devport=8000):# 登录的设备信息self.DEV_IP = create_string_buffer(camIP.encode())self.DEV_PORT =devportself.DEV_USER_NAME = create_string_buffer(username.encode())self.DEV_PASSWORD = create_string_buffer(password.encode())self.WINDOWS_FLAG = False if platform.system() != "Windows" else Trueself.funcRealDataCallBack_V30 = Noneself.recent_img = None #最新帧self.n_stamp = None #帧时间戳self.last_stamp = None #上次时间戳# 加载库,先加载依赖库                                                                   # 1 根据操作系统,加载对应的dll文件if self.WINDOWS_FLAG:            os.chdir(r'./lib/win')self.Objdll = ctypes.CDLL(r'./HCNetSDK.dll')  # 加载网络库self.Playctrldll = ctypes.CDLL(r'./PlayCtrl.dll')  # 加载播放库else:os.chdir(r'./lib/linux')self.Objdll = cdll.LoadLibrary(r'./libhcnetsdk.so')self.Playctrldll = cdll.LoadLibrary(r'./libPlayCtrl.so')# 设置组件库和SSL库加载路径                                                              # 2 设置组件库和SSL库加载路径self.SetSDKInitCfg()# 初始化DLLself.Objdll.NET_DVR_Init()                                                               # 3 相机初始化# 启用SDK写日志self.Objdll.NET_DVR_SetLogToFile(3, bytes('./SdkLog_Python/', encoding="utf-8"), False)os.chdir(r'../../') # 切换工作路径到../../# 登录(self.lUserId, self.device_info) = self.LoginDev()                                       # 4 登录相机self.Playctrldll.PlayM4_ResetBuffer(self.lUserId,1)#清空指定缓冲区的剩余数据。这个地方传进来的是self.lUserId,为什么呢?print(self.lUserId)if self.lUserId < 0:#登录失败err = self.Objdll.NET_DVR_GetLastError()print('Login device fail, error code is: %d' % self.Objdll.NET_DVR_GetLastError())# 释放资源self.Objdll.NET_DVR_Cleanup()exit()else:print(f'摄像头[{camIP}]登录成功!!')self.start_play()                                                                         # 5 开始播放time.sleep(1)def start_play(self,):#global funcRealDataCallBack_V30                                                                        self.PlayCtrl_Port = c_long(-1)  # 播放句柄# 获取一个播放句柄 #wuzh获取未使用的通道号if not self.Playctrldll.PlayM4_GetPort(byref(self.PlayCtrl_Port)):print(u'获取播放库句柄失败')# 定义码流回调函数       self.funcRealDataCallBack_V30 = REALDATACALLBACK(self.RealDataCallBack_V30)# 开启预览self.preview_info = NET_DVR_PREVIEWINFO()self.preview_info.hPlayWnd = 0self.preview_info.lChannel = 1  # 通道号self.preview_info.dwStreamType = 0  # 主码流self.preview_info.dwLinkMode = 0  # TCPself.preview_info.bBlocked = 1  # 阻塞取流# 开始预览并且设置回调函数回调获取实时流数据self.lRealPlayHandle = self.Objdll.NET_DVR_RealPlay_V40(self.lUserId, byref(self.preview_info), self.funcRealDataCallBack_V30, None)if self.lRealPlayHandle < 0:print ('Open preview fail, error code is: %d' %self. Objdll.NET_DVR_GetLastError())# 登出设备self.Objdll.NET_DVR_Logout(self.lUserId)# 释放资源self.Objdll.NET_DVR_Cleanup()exit()def SetSDKInitCfg(self,):# 设置SDK初始化依赖库路径# 设置HCNetSDKCom组件库和SSL库加载路径# print(os.getcwd())if self.WINDOWS_FLAG:strPath = os.getcwd().encode('gbk')sdk_ComPath = NET_DVR_LOCAL_SDK_PATH()sdk_ComPath.sPath = strPathself.Objdll.NET_DVR_SetSDKInitCfg(2, byref(sdk_ComPath))self.Objdll.NET_DVR_SetSDKInitCfg(3, create_string_buffer(strPath + b'\libcrypto-1_1-x64.dll'))self.Objdll.NET_DVR_SetSDKInitCfg(4, create_string_buffer(strPath + b'\libssl-1_1-x64.dll'))else:strPath = os.getcwd().encode('utf-8')sdk_ComPath = NET_DVR_LOCAL_SDK_PATH()sdk_ComPath.sPath = strPathself.Objdll.NET_DVR_SetSDKInitCfg(2, byref(sdk_ComPath))self.Objdll.NET_DVR_SetSDKInitCfg(3, create_string_buffer(strPath + b'/libcrypto.so.1.1'))self.Objdll.NET_DVR_SetSDKInitCfg(4, create_string_buffer(strPath + b'/libssl.so.1.1'))def LoginDev(self,):# 登录注册设备device_info = NET_DVR_DEVICEINFO_V30()lUserId = self.Objdll.NET_DVR_Login_V30(self.DEV_IP, self.DEV_PORT, self.DEV_USER_NAME, self.DEV_PASSWORD, byref(device_info))return (lUserId, device_info)def read(self,):while self.n_stamp==self.last_stamp:continueself.last_stamp=self.n_stampreturn self.n_stamp,self.recent_imgdef DecCBFun(self,nPort, pBuf, nSize, pFrameInfo, nUser, nReserved2):if pFrameInfo.contents.nType == 3:t0 = time.time()# 解码返回视频YUV数据,将YUV数据转成jpg图片保存到本地# 如果有耗时处理,需要将解码数据拷贝到回调函数外面的其他线程里面处理,避免阻塞回调导致解码丢帧nWidth = pFrameInfo.contents.nWidthnHeight = pFrameInfo.contents.nHeight#nType = pFrameInfo.contents.nTypedwFrameNum = pFrameInfo.contents.dwFrameNumnStamp = pFrameInfo.contents.nStamp#print(nWidth, nHeight, nType, dwFrameNum, nStamp, sFileName)YUV = np.frombuffer(pBuf[:nSize],dtype=np.uint8)YUV = np.reshape(YUV,[nHeight+nHeight//2,nWidth])img_rgb = cv2.cvtColor(YUV,cv2.COLOR_YUV2BGR_YV12)self.recent_img,self.n_stamp = img_rgb,nStampdef RealDataCallBack_V30(self,lPlayHandle, dwDataType, pBuffer, dwBufSize, pUser):# 码流回调函数if dwDataType == NET_DVR_SYSHEAD:# 设置流播放模式self.Playctrldll.PlayM4_SetStreamOpenMode(self.PlayCtrl_Port, 0)# 打开码流,送入40字节系统头数据if self.Playctrldll.PlayM4_OpenStream(self.PlayCtrl_Port, pBuffer, dwBufSize, 1024*1024):# 设置解码回调,可以返回解码后YUV视频数据#global FuncDecCBself.FuncDecCB = DECCBFUNWIN(self.DecCBFun)self.Playctrldll.PlayM4_SetDecCallBackExMend(self.PlayCtrl_Port, self.FuncDecCB, None, 0, None)# 开始解码播放if self.Playctrldll.PlayM4_Play(self.PlayCtrl_Port, None):print(u'播放库播放成功')else:print(u'播放库播放失败')else:print(u'播放库打开流失败')elif dwDataType == NET_DVR_STREAMDATA:self.Playctrldll.PlayM4_InputData(self.PlayCtrl_Port, pBuffer, dwBufSize)else:print (u'其他数据,长度:', dwBufSize)def release(self):self.Objdll.NET_DVR_StopRealPlay(self.lRealPlayHandle)if self.PlayCtrl_Port.value > -1:self.Playctrldll.PlayM4_Stop(self.PlayCtrl_Port)self.Playctrldll.PlayM4_CloseStream( self.PlayCtrl_Port)self.Playctrldll.PlayM4_FreePort( self.PlayCtrl_Port)PlayCtrl_Port = c_long(-1)self.Objdll.NET_DVR_Logout(self.lUserId)self.Objdll.NET_DVR_Cleanup()print('释放资源结束')def __enter__(self):return selfdef __exit__(self, exc_type, exc_val, exc_tb):self.release()if __name__=="__main__":camIP ='192.168.1.122'#camIP ='192.168.3.157'DEV_PORT = 8000username ='admin'password = 'admin'HIK= HKCam(camIP,username,password)last_stamp = 0while True:t0 =time.time()n_stamp,img = HIK.read()last_stamp=n_stamp'''TODO'''kkk = cv2.waitKey(1)if kkk ==ord('q'):breakHIK.release()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/158921.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《3D 数学基础》几何检测-最近点

目录 1. 直线上的最近点 2. 射线上的最近点 3. 点到平面的距离 4. 圆或球上的最近点 5. AABB上的最近点 1. 直线上的最近点 q是距离q的最近点&#xff0c;也就是q在直线上的投影。 其中p是直线上的点&#xff08;向量表示&#xff09;&#xff0c;n是直线的法向量&#x…

【苍穹外卖 | 项目日记】第四天

前言&#xff1a; 今天状态还可以&#xff0c;既有自己实战独立写接口&#xff0c;又听了课&#xff0c;学习了新的知识 目录 前言&#xff1a; 今日完结任务&#xff1a; 今日收获&#xff1a; 实现店铺状态接口 杂项知识点&#xff1a; 总结&#xff1a; 今日完结任务…

2023.10.14 培训总结

培训内容 数字模型联合仿真及集成测试技术 MBSE(Model-Based-System-Engiaeering&#xff09; 参数化建模参数化仿真 产生的疑问 支持面向对象支持CAE CFD工具优化工具 飞机的业务功能 开发分布式架构 新技术 WSDL协议DDS 发布/订阅SAOPCORBA 明显开发者 Chris Garrett 美…

【基于Kmeans、Kmeans++和二分K均值算法的图像分割】数据挖掘实验三

文章目录 Ⅰ、项目任务要求任务描述&#xff1a;主要任务要求&#xff1a; II、实现过程数据集描述实现描述具体实现过程 III、完整代码代码①代码② Ⅰ、项目任务要求 任务描述&#xff1a; 图像分割是图像处理和计算机视觉中重要的一环&#xff0c;在实际生活中得到了广泛的…

P1433 吃奶酪

#include <iostream> #include <cmath> using namespace std; #define M 15 #define S(n) ((n) * (n)) double indx[M 5], indy[M 5], ans 0, sum 0;//坐标数组&#xff0c;从下标为1开始记录 int n, vis[M 5] { 0 };//vis数组&#xff0c;选过的数字标记为1…

openssl学习——消息认证码原理

消息认证码原理 消息认证码&#xff08;Message Authentication Code, MAC&#xff09;是一种技术&#xff0c;它的原理是通过对消息和密钥进行特定的处理&#xff0c;生成一个固定长度的数据&#xff0c;这个数据就是消息认证码&#xff08;MAC&#xff09;。这个过程可以看作…

openGauss学习笔记-99 openGauss 数据库管理-管理数据库安全-客户端接入认证之配置文件参考

文章目录 openGauss学习笔记-99 openGauss 数据库管理-管理数据库安全-客户端接入认证之配置文件参考99.1 参数说明99.2 认证方式 openGauss学习笔记-99 openGauss 数据库管理-管理数据库安全-客户端接入认证之配置文件参考 99.1 参数说明 表 1 参数说明 参数名称描述取值范…

SQL及数据库基础知识点总结

一. SQL&#xff08;Structured Query Language&#xff09;&#xff1a; 结构化查询语言。SQL语法不区分关键字的大小写&#xff0c;多条SQL语句必须以&#xff1b;分隔。 二. SQL的作用&#xff1a; SQL可以访问和处理数据库&#xff0c;包括数据的增删改查&#xff08;插…

SpringCloud-Config

一、介绍 &#xff08;1&#xff09;服务注册中心 &#xff08;2&#xff09;管理各个服务上的application.yml&#xff0c;支持动态修改&#xff0c;但不会影响客户端配置 &#xff08;3&#xff09;一般将application.yml文件放在git上&#xff0c;客户端通过http/https方式…

Maika 与越南童模们受邀请参加中国上海时装周 hanakimi 品牌开幕

金风送爽&#xff0c;秋高气和。2024中国上海时装周以“活力互链”为主题&#xff0c;于10月8日正式启幕。 魅力四射的越南童模身着著名时尚品牌MLB、Hana Kami、Jacadi的精美设计&#xff0c;迈着有力、专业但又不失优雅的步伐走上时尚舞台上海大型现场。无论是拍摄造型照还是…

windows TBB的使用

windows TBB的使用 1. Install with GUI 1. Install with GUI To install oneTBB using GUI, complete the following steps: Go to the Download page.Select the preferred installer Online installer has a smaller file size but requires a permanent Internet connec…

MFF论文笔记

论文名称&#xff1a;Improving Pixel-based MIM by Reducing Wasted Modeling Capability_发表时间&#xff1a;ICCV2023 作者及组织&#xff1a;上海人工智能实验室&#xff0c;西门菲沙大学&#xff0c;香港中文大学 问题与贡献 MIM(Model Maksed Model)方法可以分为两部分…

C语言-贪吃蛇 1.输入控制ncurse

一、为什么要用nurse C语言中的gets()、scanf()、getchar()等函数是在用户输入后需要按下Enter键才能执行代码&#xff0c;而贪吃蛇要求按下按键后立即对蛇的方向进行操作&#xff0c;所以根据贪吃蛇功能的需求引入ncurse&#xff0c;让用户输入后就能让蛇进行对应的行动。 二、…

Spring Boot中的异步编程:解决的问题与应用场景

Spring Boot中的异步编程&#xff1a;解决的问题与应用场景 在现代Web应用程序中&#xff0c;高并发和性能是至关重要的。为了处理大量的请求和任务&#xff0c;异步编程成为了不可或缺的一部分。Spring Boot提供了强大的异步编程支持&#xff0c;可以显著提高应用程序的吞吐量…

Spring MVC 和Spring JDBC

目录 Spring MVC MVC模式 核心组件 工作流程 Spring JDBC Spring JDBC功能和优势 Spring JDBC的关键组件 Spring MVC Spring MVC&#xff08;Model-View-Controller&#xff09;是Spring框架的一个模块&#xff0c;用于构建Web应用程序。它的主要目标是将Web应用程序的不…

比较和同步数据库架构和数据:MssqlMerge Pro Crack

比较和同步数据库架构和数据 适用于Oracle、MySQL 和 MariaDB、SQL Server、PostgreSQL、SQLite、MS Access和跨 DBMS 场景 业界领先的文本比较工具中常用的两面板 UI 快速过滤器显示所有/新/更改/新更改 合并两个方向的更改 轻量级&#xff1a;跨 DBMS 工具小于 20 MB&#xf…

【大数据Hive】hive select 语法使用详解

目录 一、前言 二、Hive select 完整语法树 三、Hive select 操作演示 3.1 数据准备 3.1.1 创建一张表 3.1.2 将数据load加载到t_usa_covid19表 3.1.3 再创建一张分区表 3.1.4 使用动态分区插入数据 3.2 select 常用语法 3.2.1 查询所有字段或者指定字段 3.2.2 查询…

计算机视觉:池化层的作用是什么?

本文重点 在深度学习中,卷积神经网络(CNN)是一种非常强大的模型,广泛应用于图像识别、目标检测、自然语言处理等领域。而池化层作为CNN中的一个关键步骤,扮演着优化神经网络、提升深度学习性能的重要角色。本文将深入探讨池化层的作用及其重要性,帮助读者更好地理解和应…

如何使用JMeter测试导入接口/导出接口

今天一上班&#xff0c;被开发问了一个问题&#xff1a;JMeter调试接口&#xff0c;文件导入接口怎么老是不通&#xff1f;还有导出文件接口&#xff0c;不知道文件导到哪里去了&#xff1f; 我一听&#xff0c;这不是JMeter做接口测试经常遇到的嘛&#xff0c;但是一时半会又…

nodejs+vue考研信息查询系统-计算机毕业设计

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…