python-onvif实现客户端控制相机云台

参考:GitHub - quatanium/python-onvif: ONVIF Client Implementation in Python

在《海康相机之onvif测试工具使用》这篇文章中,介绍了利用onvif测试工具来调试海康相机,并且介绍了如何配置海康相机。

本文将介绍如何调用onvif协议的接口,来实现代码控制海康相机云台转动,查询的大多数代码是使用C++来实现,感觉有点复杂,本文直接采用python接口来实现。C版本的请查看《ONVIF协议开发之网络摄像头云台控制(C版)

1 安装python-onvif

1.1 pip安装

python官方已经提供了onvif包的安装,因此可直接通过pip来安装,如下

pip2 install onvif

要注意这里pip必须对应python2,如果对应是python3可能会有问题,因此为了避免这种问题,建议采用如下的源码安装

1.2 源码安装

git clone https://github.com/quatanium/python-onvif
cd python-onvif
python2 setup.py install

1.3 安装测试

安装成功后,运行python2,输入以下语句,不报错即安装成功

from onvif import ONVIFCamera

2 连续运动(python2版本)

在python-onvif安装包中,有examples文件夹,其中有个continuous_move.py文件,代码如下

from time import sleep

from onvif import ONVIFCamera

XMAX = 1
XMIN = -1
YMAX = 1
YMIN = -1

def perform_move(ptz, request, timeout):
    # Start continuous move
    ptz.ContinuousMove(request)
    # Wait a certain time
    sleep(timeout)
    # Stop continuous move
    ptz.Stop({'ProfileToken': request.ProfileToken})

def move_up(ptz, request, timeout=1):
    print 'move up...'
    request.Velocity.PanTilt._x = 0
    request.Velocity.PanTilt._y = YMAX
    perform_move(ptz, request, timeout)

def move_down(ptz, request, timeout=1):
    print 'move down...'
    request.Velocity.PanTilt._x = 0
    request.Velocity.PanTilt._y = YMIN
    perform_move(ptz, request, timeout)

def move_right(ptz, request, timeout=1):
    print 'move right...'
    request.Velocity.PanTilt._x = XMAX
    request.Velocity.PanTilt._y = 0
    perform_move(ptz, request, timeout)

def move_left(ptz, request, timeout=1):
    print 'move left...'
    request.Velocity.PanTilt._x = XMIN
    request.Velocity.PanTilt._y = 0
    perform_move(ptz, request, timeout)

def continuous_move():
    mycam = ONVIFCamera('192.168.0.112', 80, 'admin', '12345')
    # Create media service object
    media = mycam.create_media_service()
    # Create ptz service object
    ptz = mycam.create_ptz_service()

    # Get target profile
    media_profile = media.GetProfiles()[0]

    # Get PTZ configuration options for getting continuous move range
    request = ptz.create_type('GetConfigurationOptions')
    request.ConfigurationToken = media_profile.PTZConfiguration._token
    ptz_configuration_options = ptz.GetConfigurationOptions(request)

    request = ptz.create_type('ContinuousMove')
    request.ProfileToken = media_profile._token

    ptz.Stop({'ProfileToken': media_profile._token})

    # Get range of pan and tilt
    # NOTE: X and Y are velocity vector
    global XMAX, XMIN, YMAX, YMIN
    XMAX = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].XRange.Max
    XMIN = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].XRange.Min
    YMAX = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].YRange.Max
    YMIN = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].YRange.Min

    # move right
    move_right(ptz, request)

    # move left
    move_left(ptz, request)

    # Move up
    move_up(ptz, request)

    # move down
    move_down(ptz, request)

if __name__ == '__main__':
    continuous_move()

将第43行函数里的IP、用户名、密码修改为自己相机的参数,比如我的相机参数如下

mycam = ONVIFCamera('192.168.170.*', 80, 'admin', '**')

然后运行python2 continuous_move.py,相机云台即可分别实现右左上下运动,参考此代码我们便可以编写我们自己的运动控制程序

============2019.8.15更新=============

3 连续运动(python3版本)

前端时间经过测试,把Python3版本的调通了,安装方法如下

git clone https://github.com/FalkTannhaeuser/python-onvif-zeep.git
cd python-onvif-zeep
python setup.py install
pip3 install --upgrade onvif_zeep

连续运动代码

from time import sleep

from onvif import ONVIFCamera
import zeep

XMAX = 1
XMIN = -1
YMAX = 1
YMIN = -1

def zeep_pythonvalue(self, xmlvalue):
    return xmlvalue

def perform_move(ptz, request, timeout):
    # Start continuous move
    ptz.ContinuousMove(request)
    # Wait a certain time
    sleep(timeout)
    # Stop continuous move
    ptz.Stop({'ProfileToken': request.ProfileToken})

def move_up(ptz, request, timeout=1):
    print('move up...') 
    request.Velocity.PanTilt.x = 0
    request.Velocity.PanTilt.y = YMAX
    perform_move(ptz, request, timeout)

def move_down(ptz, request, timeout=1):
    print('move down...') 
    request.Velocity.PanTilt.x = 0
    request.Velocity.PanTilt.y = YMIN
    perform_move(ptz, request, timeout)

def move_right(ptz, request, timeout=1):
    print('move right...') 
    request.Velocity.PanTilt.x = XMAX
    request.Velocity.PanTilt.y = 0
    perform_move(ptz, request, timeout)

def move_left(ptz, request, timeout=1):
    print('move left...') 
    request.Velocity.PanTilt.x = XMIN
    request.Velocity.PanTilt.y = 0
    perform_move(ptz, request, timeout)

def continuous_move():
    mycam = ONVIFCamera('192.168.170.**', 80, 'admin', '**')
    # 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]

    # Get PTZ configuration options for getting continuous move range
    request = ptz.create_type('GetConfigurationOptions')
    request.ConfigurationToken = media_profile.PTZConfiguration.token
    ptz_configuration_options = ptz.GetConfigurationOptions(request)

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

    if request.Velocity is None:
        request.Velocity = ptz.GetStatus({'ProfileToken': media_profile.token}).Position
        request.Velocity = ptz.GetStatus({'ProfileToken': media_profile.token}).Position
        request.Velocity.PanTilt.space = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].URI
        request.Velocity.Zoom.space = ptz_configuration_options.Spaces.ContinuousZoomVelocitySpace[0].URI
   
    # Get range of pan and tilt
    # NOTE: X and Y are velocity vector
    global XMAX, XMIN, YMAX, YMIN
    XMAX = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].XRange.Max
    XMIN = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].XRange.Min
    YMAX = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].YRange.Max
    YMIN = ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].YRange.Min

    # move right
    move_right(ptz, request)

    # move left
    move_left(ptz, request)

    # Move up
    move_up(ptz, request)

    # move down
    move_down(ptz, request)

if __name__ == '__main__':
    continuous_move()

4 绝对运动(python3版本)

仿照连续运动的实例,结合onvif协议,可以写绝对运动的控制程序

from time import sleep

from onvif import ONVIFCamera
import zeep

XMAX = 1
XMIN = -1
YMAX = 1
YMIN = -1

def zeep_pythonvalue(self, xmlvalue):
    return xmlvalue

def perform_move(ptz, request, timeout):
    # Start continuous move
    ptz.ContinuousMove(request)
    # Wait a certain time
    sleep(timeout)
    # Stop continuous move
    ptz.Stop({'ProfileToken': request.ProfileToken})


def absolute_move():
    pan = 0
    pan_speed = 1
    tilt = 0
    tilt_speed = 1
    zoom = 1
    zoom_speed = 1

    mycam = ONVIFCamera('192.168.170.**', 80, 'admin', '**')
    # 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]

    # Get PTZ configuration options for getting absolute move range
    request = ptz.create_type('GetConfigurationOptions')
    request.ConfigurationToken = media_profile.PTZConfiguration.token
    # ptz_configuration_options = ptz.GetConfigurationOptions(request)

    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')


if __name__ == '__main__':
    absolute_move()

  • 10
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 53
    评论
很抱歉,我作为AI语言模型无法提供完整的Python代码,但我可以给你一些实现按键控制摄像机云台的思路和指导: 1. 首先需要使用PythonONVIF库来实现与摄像机的通信。可以使用第三方库如`python-onvif-zeep`或`onvif-py3`。 2. 使用ONVIF库中的函数,获取摄像机的云台控制对象。例如,在`python-onvif-zeep`中,可以使用以下代码获取: ``` from onvif import ONVIFCamera camera = ONVIFCamera('192.168.1.10', 80, 'admin', 'password') ptz_service = camera.create_ptz_service() ``` 3. 使用云台控制对象,调用相应的函数实现云台控制。例如,可以使用`ContinuousMove`函数来控制云台的运动: ``` # 向上移动 ptz_service.ContinuousMove({'ProfileToken': 'profile_token', 'Velocity': {'PanTilt': {'x': 0, 'y': 1}, 'Zoom': {'x': 0}}}) # 向下移动 ptz_service.ContinuousMove({'ProfileToken': 'profile_token', 'Velocity': {'PanTilt': {'x': 0, 'y': -1}, 'Zoom': {'x': 0}}}) # 向左移动 ptz_service.ContinuousMove({'ProfileToken': 'profile_token', 'Velocity': {'PanTilt': {'x': -1, 'y': 0}, 'Zoom': {'x': 0}}}) # 向右移动 ptz_service.ContinuousMove({'ProfileToken': 'profile_token', 'Velocity': {'PanTilt': {'x': 1, 'y': 0}, 'Zoom': {'x': 0}}}) ``` 4. 使用Python的`keyboard`库或`pynput`库来实现按键监听。例如,使用`pynput`库可以使用以下代码监听键盘输入: ``` from pynput import keyboard def on_press(key): try: if key.char == 'w': # 向上移动 ptz_service.ContinuousMove({'ProfileToken': 'profile_token', 'Velocity': {'PanTilt': {'x': 0, 'y': 1}, 'Zoom': {'x': 0}}}) elif key.char == 's': # 向下移动 ptz_service.ContinuousMove({'ProfileToken': 'profile_token', 'Velocity': {'PanTilt': {'x': 0, 'y': -1}, 'Zoom': {'x': 0}}}) elif key.char == 'a': # 向左移动 ptz_service.ContinuousMove({'ProfileToken': 'profile_token', 'Velocity': {'PanTilt': {'x': -1, 'y': 0}, 'Zoom': {'x': 0}}}) elif key.char == 'd': # 向右移动 ptz_service.ContinuousMove({'ProfileToken': 'profile_token', 'Velocity': {'PanTilt': {'x': 1, 'y': 0}, 'Zoom': {'x': 0}}}) except AttributeError: pass def on_release(key): pass with keyboard.Listener(on_press=on_press, on_release=on_release) as listener: listener.join() ``` 注意,这只是一个简单的示例代码,实际使用中需要根据具体情况进行适当的修改和优化。同时,需要注意安全问题,如使用HTTPS协议进行通信、使用加密认证等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 53
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宗而研之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值