最近新项目中要把一套现有的系统移植到华为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()
几个方法的流程都是一样的,都是获取服务,传参调用。其他的接口也没有测试,等用到的时候再测吧。