python控制监控摄像头学习笔记(onvif,附代码)

2025-05-08 14:50:06

摄像头用的是海康(DS系列)的智能球型摄像头,摄像头是已经激活的。a.实现电脑浏览器访问摄像头 1.先用网线把摄像头和电脑直连(也可以摄像头和路由器直连)。 2.接下来确认摄像头的ip地址 可以用海康官方提供的软件:https://www.hikvision.com/cn/support/tools/hitools/clea8b3e4ea7da90a9/

3.修改电脑的ip和摄像头ip到同频 以下是海康官方给的操作方案:

→ 电脑IP:192.168.0.5 ,摄像机IP:192.168.1.64 则表示不在同一网段

→ 电脑IP:192.168.1.5 ,摄像机IP:192.168.1.64则表示在同一网段

4.浏览器登录 直接在浏览器输入摄像头的ip,进入登录页面,输入账号密码

5.下载插件并安装 插件下载在登录后页面处

安装完成后就可以成功看到

b.python控制摄像头(用的onvif协议)

1.先安装好cv和onvif

conda activate xxx

pip install onvif_zeep

pip install opencv-python

2.确认端口

3.在浏览器配置摄像头 4.运行代码 效果是实时监控的同时,每三秒在预置点1和预置点2中转换 修改自己的ip地址,端口,账号,密码就可以使用了

import time

import requests

import threading

import zeep

from onvif import ONVIFCamera

from requests.auth import HTTPDigestAuth

import cv2

def zeep_pythonvalue(self, xmlvalue):

return xmlvalue

class Onvif_hik(object):

def __init__(self, ip: str, username: str, password: str):

self.ip = ip

self.username = username

self.password = password

self.save_path = "./{}T{}.jpg".format(self.ip, str(time.time())) # 截图保存路径

self.content_cam()

self.exit_flag = False # 用于退出视频流显示的标志

def content_cam(self):

"""

链接相机地址

:return:

"""

try:

self.mycam = ONVIFCamera(self.ip, 80, self.username, self.password)

self.media = self.mycam.create_media_service() # 创建媒体服务

# 得到目标概要文件

zeep.xsd.simple.AnySimpleType.pythonvalue = zeep_pythonvalue

self.media_profile = self.media.GetProfiles()[0] # 获取配置信息

self.ptz = self.mycam.create_ptz_service() # 创建控制台服务

return True

except Exception as e:

return False

def Snapshot(self):

"""

截图

:return:

"""

res = self.media.GetSnapshotUri({'ProfileToken': self.media_profile.token})

response = requests.get(res.Uri, auth=HTTPDigestAuth(self.username, self.password))

with open(self.save_path, 'wb') as f: # 保存截图

f.write(response.content)

def get_presets(self):

"""

获取预置点列表

:return:预置点列表--所有的预置点

"""

presets = self.ptz.GetPresets({'ProfileToken': self.media_profile.token}) # 获取所有预置点,返回值:list

return presets

def goto_preset(self, presets_token: int):

"""

移动到指定预置点

:param presets_token: 目的位置的token,获取预置点返回值中

:return:

"""

try:

params = self.ptz.create_type('GotoPreset')

params.ProfileToken = self.media_profile.token

params.PresetToken = presets_token

self.ptz.GotoPreset(params)

except Exception as e:

print(e)

def zoom(self, zoom: str, timeout: int = 1):

"""

变焦

:param zoom: 1为拉近或-1为远离

:param timeout: 生效时间

:return:

"""

request = self.ptz.create_type('ContinuousMove')

request.ProfileToken = self.media_profile.token

request.Velocity = {"Zoom": zoom}

self.ptz.ContinuousMove(request)

time.sleep(timeout)

self.ptz.Stop({'ProfileToken': request.ProfileToken})

def get_status(self):

"""

获取当前预置点的信息

:return:

"""

params = self.ptz.create_type('GetStatus')

params.ProfileToken = self.media_profile.token

res = self.ptz.GetStatus(params)

return res

def show_video(self):

"""

获取并展示摄像头的实时视频流

:return:

"""

# 获取视频流的 RTSP URL

video_url = self.media.GetStreamUri({'StreamSetup': {'Stream': 'RTP-Unicast', 'Transport': {'Protocol': 'RTSP'}}, 'ProfileToken': self.media_profile.token})

# 将用户名和密码嵌入 RTSP URL 中

rtsp_url_with_credentials = f"rtsp://{self.username}:{self.password}@{self.ip}:554{video_url.Uri[video_url.Uri.find('/'):]}"

# 打开视频流

cap = cv2.VideoCapture(rtsp_url_with_credentials)

if not cap.isOpened():

print("无法打开视频流")

return

# 持续显示视频流

while not self.exit_flag:

ret, frame = cap.read()

if not ret:

print("无法获取视频帧")

break

cv2.imshow("Camera Stream", frame)

# 按 'q' 键退出

if cv2.waitKey(1) & 0xFF == ord(' '):

self.exit_flag = True # 设置退出标志

break

# 释放资源

cap.release()

cv2.destroyAllWindows()

def move_between_presets(self, time_interval_1=10, time_interval_2=10):

"""

在指定时间间隔内移动到预置点1和预置点2

:param time_interval_1: 移动到预置点1的时间(秒)

:param time_interval_2: 移动到预置点2的时间(秒)

:return:

"""

while True:

# 移动到预置点1

print("移动到预置点1...")

self.goto_preset(1) # 假设预置点1的 token 是 1

time.sleep(time_interval_1)

# 移动到预置点2

print("移动到预置点2...")

self.goto_preset(2) # 假设预置点2的 token 是 2

time.sleep(time_interval_2)

if self.exit_flag:

break

if __name__ == '__main__':

o = Onvif_hik(ip="ip地址", username="账号", password="密码")

#o.show_video() # 展示实时视频流

#o.move_between_presets(time_interval_1=3, time_interval_2=3) # 每个预置点停留 10 秒

video_thread = threading.Thread(target=o.show_video) # 展示视频流的线程

preset_thread = threading.Thread(target=o.move_between_presets, args=(3, 3)) # 切换预置点的线程

# 启动线程

video_thread.start()

preset_thread.start()

# 等待线程完成

video_thread.join()

preset_thread.join()

print("程序已退出")

相关参考资料:实测python-onvif协议控制摄像头[梧桐凰]_onvif python-CSDN博客