python-onvif库基本使用

最近新项目中要把一套现有的系统移植到华为Atlas终端上,因为现在这套系统里关于摄像头预置位跳转,抓图等功能是调用海康SDK实现的;但是Atlas终端是ARM平台的,海康的SDK是x86平台的,并没有提供ARM版本的,所以考虑使用onvif协议实现预置位跳转和抓图功能,这样就不用考虑平台差异了。

onvif接口说白了就是webservice接口的调用,各个语言也都提供了相关的类库,大致看了一下C++和python的。对比看来,不得不承认在易用性方面python高出了C++不止一个量级。下面就介绍一下,如何通过python-onvif实现摄像头坐标跳转,预置位跳转以及抓图功能。

首先是开发环境,这里使用的是python3

然后安装python-onvif:

pip3 install --upgrade onvif_zeep

下面介绍一下使用的使用python-onvif基本流程:

1.创建ONVIFCamera对象,我们可以理解为支持onvif协议的设备。

2.调用ONVIFCamera对象的create_xxx_service()方法来获取相应服务。

3.一般我们首先会调用create_media_service()方法来获取media_service()服务,然后调用这个服务提供的GetProfiles()来获取配置信息,可以从配置信息里取到Token。

4.接下来就是通过给onvif接口传递参数,来调用相关接口了。至于如何传参,及调用文档里写的很清楚


    There are two ways to pass parameter to services methods
    1. Dict
        params = {'Name': 'NewHostName'}
        device_service.SetHostname(params)
    2. Type Instance
        params = device_service.create_type('SetHostname')
        params.Hostname = 'NewHostName'
        device_service.SetHostname(params)
    '''

还是要多看官方文档,废话少说,先上代码,下面的测试Demo里实现了项目里可能用到的几个方法:坐标跳转,预置位跳转,抓图以及获取当前坐标:

import time
from onvif import ONVIFCamera
import zeep
import requests
from requests.auth import HTTPDigestAuth


def zeep_pythonvalue(self, xmlvalue):
    return xmlvalue


#坐标跳转
def absolute_move():
    pan = 0
    pan_speed = 1
    tilt = 0
    tilt_speed = 1
    zoom = 1
    zoom_speed = 1

    mycam = ONVIFCamera('192.168.1.100', 80, 'admin', 'pass')
    # Create media service object
    media = mycam.create_media_service()
    # Create ptz service object
    ptz = mycam.create_ptz_service()

    # Get target profile
    zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
    media_profile = media.GetProfiles()[0]

    request = ptz.create_type('AbsoluteMove')
    request.ProfileToken = media_profile.token
    ptz.Stop({'ProfileToken': media_profile.token})

    if request.Position is None:
        request.Position = ptz.GetStatus({'ProfileToken': media_profile.token}).Position
    if request.Speed is None:
        request.Speed = ptz.GetStatus({'ProfileToken': media_profile.token}).Position

    request.Position.PanTilt.x = pan
    request.Speed.PanTilt.x = pan_speed

    request.Position.PanTilt.y = tilt
    request.Speed.PanTilt.y = tilt_speed

    request.Position.Zoom = zoom
    request.Speed.Zoom = zoom_speed

    ptz.AbsoluteMove(request)
    print('finish')


#抓图
def snap():
    # Get target profile
    zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
    mycam = ONVIFCamera("192.168.1.100", 80, "admin", "pass")
    media = mycam.create_media_service()  # 创建媒体服务
    media_profile = media.GetProfiles()[0]  # 获取配置信息
    res = media.GetSnapshotUri({'ProfileToken': media_profile.token})
    response = requests.get(res.Uri, auth=HTTPDigestAuth("admin", "pass"))
    res = "{_time}.png".format(_time=time.strftime('%Y_%m_%d_%H_%M_%S', time.localtime(time.time())))
    with open(res, 'wb') as f:  # 保存截图
        f.write(response.content)


#预置位跳转
def gotoPreset():
    zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
    mycam = ONVIFCamera("192.168.1.100", 80, "admin", "pass")
    media = mycam.create_media_service()
    ptz = mycam.create_ptz_service()
    params = ptz.create_type('GotoPreset')
    media_profile = media.GetProfiles()[0]  # 获取配置信息
    print(media_profile.token)
    params.ProfileToken = media_profile.token
    params.PresetToken = 1
    re = ptz.GotoPreset(params)
    print(re)


#获取当前位置信息
def getStatus():
    zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue
    mycam = ONVIFCamera("192.168.1.100", 80, "admin", "pass")
    media = mycam.create_media_service()
    ptz = mycam.create_ptz_service()
    params = ptz.create_type('GetStatus')
    media_profile = media.GetProfiles()[0]  # 获取配置信息
    print(media_profile.token)
    params.ProfileToken = media_profile.token
    res = ptz.GetStatus(params)
    print(res)


if __name__ == '__main__':
    absolute_move()
    snap()
    gotoPreset()
    getStatus()



几个方法的流程都是一样的,都是获取服务,传参调用。其他的接口也没有测试,等用到的时候再测吧。

### ONVIF PTZ 开发教程 #### 了解ONVIF PTZ协议基础 为了成功开发支持ONVIF PTZ控制的应用程序,理解PTZ(Pan-Tilt-Zoom)操作的基础至关重要。这涉及到熟悉ONVIF设备管理规范中的特定部分,特别是那些描述如何通过网络接口远程操控摄像头移动和变焦的部分[^1]。 #### 准备工作环境 在开始编码之前,确保拥有适当的工作环境设置对于项目的顺利进展非常重要。通常情况下,这意味着安装并配置好GSOAP工具包以及必要的插件和支持。例如,在`gsoap-2.8/gsoap`目录下执行一系列命令来准备所需的源文件副本: ```bash $ cd gsoap-2.8/gsoap $ cp stdsoap2.c stdsoap2.h dom.c plugin/wsaapi.c plugin/wsaapi.h \ plugin/wsseapi.c plugin/wsseapi.h plugin/mecevp.c plugin/mecevp.h \ plugin/smdevp.c plugin/smdevp.h plugin/threads.c plugin/threads.h \ custom/duration.c custom/duration.h bin/onvif/ ``` 此过程会将必需的支持文件复制到项目中以便于后续使用[^4]。 #### 修改命名空间映射 为了让应用程序能够识别和服务端交换数据时所使用的XML命名空间,需要调整`samples\onvif\wsdd.nsmap`内的定义,并相应地更新`samples\onvif\stdsoap2.c`头部包含路径以反映新的命名空间信息[^3]。 #### 编写核心逻辑代码 一旦准备工作完成,就可以着手编写实际处理PTZ请求的核心业务逻辑了。下面给出了一段简单的Python伪代码片段作为参考,展示了怎样利用已有的API发起基本的云台转动指令: ```python import onvif_client as oc def move_camera(pan_speed, tilt_speed): client = oc.Client('http://camera_ip_address') try: ptz_service = client.create_ptz_service() request = { 'ProfileToken': profile_token, 'Velocity': {'PanTilt': (pan_speed, tilt_speed)} } response = ptz_service.ContinuousMove(request) print(f'Move command sent successfully: {response}') except Exception as e: print(e) move_camera(-0.5, 0.5) # 向左上方缓慢平移相机镜头 ``` 这段示例假设存在一个名为`onvif_client.py`模块提供了创建客户端实例的方法以及其他辅助函数;具体实现细节可能因选用的不同SDK而有所差异。
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值