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协议中,控制摄像头移动的速度主要依赖于`Velocity`参数。这个参数用于定义平移(Pan)、俯仰(Tilt)以及变焦(Zoom)操作的速度[^2]。 对于每一个动作维度(Pan, Tilt, Zoom),都有对应的`X`, `Y`, 或者缩放因子来表示其运动速率。这些值通常被标准化为浮点数范围[-1.0, 1.0]之间,其中: - `-1.0` 表示最慢向左/下或缩小; - `0.0` 表示停止不动; - `+1.0` 表示最快向右/上或放大; 具体来说,在发送连续移动请求时可以通过设置`Move`方法里的`Velocity`属性来进行调整。下面给出Python代码片段展示如何使用`zeep`调用ONVIF服务并设定速度: ```python from zeep import Client import requests from requests.auth import HTTPDigestAuth def set_ptz_velocity(camera_ip, username, password, pan_speed=0.5, tilt_speed=0.5): wsdl_url = f"http://{camera_ip}/onvif-ptz?wsdl" session = requests.Session() session.auth = HTTPDigestAuth(username, password) client = Client(wsdl=wsdl_url, transport=session) media_service = client.create_service( '{http://www.onvif.org/ver10/media/wsdl}MediaBinding', 'http://' + camera_ip + '/onvif/Media' ) ptz_service = client.create_service( '{http://www.onvif.org/ver20/ptz/wsdl}PTZBinding', 'http://' + camera_ip + '/onvif/PTZ' ) profiles = media_service.GetProfiles() profile_token = profiles[0]._token velocity = { "Space": None, "x": float(pan_speed), "y": float(tilt_speed), "z": 0.0 # Assuming no zoom change here. } try: ptz_service.ContinuousMove({ "_this": profile_token, "Velocity": velocity }) print("Continuous move command sent successfully.") except Exception as e: print(f"Failed to send continuous move command: {e}") ``` 上述脚本展示了怎样构建一个简单的函数去改变给定IP地址的网络摄像机的PTZ速度。需要注意的是实际部署前应当替换掉默认的服务URL路径以匹配目标设备的要求[^3]。
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值