最近新项目中要把一套现有的系统移植到华为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()



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

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐