Opencv学习笔记(十):同步和异步(多线程)操作打开海康摄像头

简介: 如何使用OpenCV进行同步和异步操作来打开海康摄像头,并提供了相关的代码示例。

1.激活海康摄像头

通过SADP可看到下面这个信息
在这里插入图片描述
输入你想设置的密码即可

若忘记密码可看下面这篇博主的博客
https://blog.csdn.net/gao_summer_cola/article/details/72621766

2.关键信息

rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream

说明:
username: 用户名。例如admin。
password: 密码。例如123456。
ip: 为设备IP。例如 192.168.0.224。
port: 端口号默认为554,若为默认可不填写。
codec:有h264、MPEG-4、mpeg4这几种。
channel: 通道号,起始为1。例如通道1,则为ch1。
subtype: 码流类型,主码流为main,子码流为sub。

用户名默认为admin 密码开始为admin,后可以设置为自己想要的,先通过使用SADP工具可以识别摄像头,然后配置IP与电脑(IPV4地址)在同一个网段。
在这里插入图片描述
然后通过IE浏览器打开对应的IP地址,输入账号和密码进入界面
,知道了用户名和密码和IP地址过后,在找到端口号(默认为554)即可
在这里插入图片描述

3.同步操作

#!/usr/bin/env python
#
# 这个代码注意点 设置好正确的用户名、密码、ip、端口,端口目前是554,
# 启动这个代码之后,会持续查看摄像头工作情况,非常好用,这个可以作为一个测试工具使用
#
import cv2
# UserName = "admin"
# PassW = "a12345678"
# IpAddr = "10.16.97.150"
# Port = "554"
url = 'rtsp://admin:a12345678@10.16.97.150:554/h264/ch1/main/av_stream'
ur2 = 'rtsp://admin:a12345678@10.16.97.149:555/h264/ch1/sub/av_stream'
# cap = cv2.VideoCapture("rtsp://" + UserName + ":" + PassW + "@" + IpAddr + ":" + Port + "/Streaming/Channels/1")
# 摄像头是否处于打开状态可以通过isOpened()方法进行判断
cap = cv2.VideoCapture(url)
cap1 = cv2.VideoCapture(ur2)
ret, frame = cap.read()
ret1, frame = cap1.read()
while ret:
    ret, frame = cap.read()
    ret, frame1 = cap1.read()
    cv2.imshow("frame",frame)
    cv2.imshow("frame1",frame1)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cv2.destroyAllWindows()
cap.release()
cap1.release()
print('done')

2.1效果图

在这里插入图片描述

4.异步操作

python可以使用multiprocessing多进程读取多个摄像头,但是multiprocessing自带的队列在交换数据时内存不会释放

4.1代码1

  • 数字0,代表计算机的默认摄像头(例如上面提及的笔记本前置摄像头)
  • video.avi 视频文件的路径,支持其他格式的视频文件
  • rtsp路径(不同品牌的路径一般是不同的,如下面举出的海康与大华)
user, pwd, ip, channel = "admin", "admin123456", "192.168.35.121", 1

video_stream_path = 0  # local camera (e.g. the front camera of laptop)
video_stream_path = 'video.avi'  # the path of video file
video_stream_path = "rtsp://%s:%s@%s/h265/ch%s/main/av_stream" % (user, pwd, ip, channel)  # HIKIVISION old version 2015
video_stream_path = "rtsp://%s:%s@%s//Streaming/Channels/%d" % (user, pwd, ip, channel)  # HIKIVISION new version 2017
video_stream_path = "rtsp://%s:%s@%s/cam/realmonitor?channel=%d&subtype=0" % (user, pwd, ip, channel)  # dahua

cap = cv2.VideoCapture(video_stream_path)
# 代码描述:利用多进程方法,利用两个海康威视摄像头,同时录取视频并保存本地
import cv2
import time
import numpy as np
import multiprocessing as mp

# 抓取图片,确认视频流的读入
def image_put(q, name, pwd, ip, channel):
    cap = cv2.VideoCapture("rtsp://%s:%s@%s:%s//Streaming/Channels/1" \
                           % (name, pwd, ip, channel))
    # 获取视频帧率
    fps = cap.get(cv2.CAP_PROP_FPS)
    print('fps: ', fps)
    if cap.isOpened():
        print('HIKVISION1')
        print('camera ' + ip + " connected.")

    while True:
        q.put(cap.read()[1])
        q.get() if q.qsize() > 1 else time.sleep(0.01)

# 获得视频流帧数图片,保存读入的视频
def image_get(q, window_name):
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    # 视频保存路径
    path = "F:/pycharm/practice/vedio/" + window_name + ".avi"
    out = cv2.VideoWriter(path, fourcc, 20.0, (1280, 720), True)
    while True:
        frame = q.get()
        print(frame.shape)
        out.write(frame)

def image_collect(queue_list, camera_ip_l):

    """show in single opencv-imshow window"""
    #window_name = "%s_and_so_no" % camera_ip_l[0]
    # cv2.namedWindow(window_name, flags=cv2.WINDOW_FREERATIO)
    # while True:
    #     imgs = [q.get() for q in queue_list]
    #     imgs = np.concatenate(imgs, axis=1)
    #     cv2.imshow(window_name, imgs)
    #     cv2.waitKey(1)
    """show in multiple opencv-imshow windows"""
    [cv2.namedWindow(window_name, flags=cv2.WINDOW_FREERATIO)
     for window_name in camera_ip_l]
    while True:
        for window_name, q in zip(camera_ip_l, queue_list):
            cv2.imshow(window_name, q.get())
            cv2.waitKey(1)
# 解决进程问题
def run_multi_camera():
    # user_name, user_pwd = "admin", "password"
    user_name, user_pwd = "admin", "a12345678"
    # 摄像头的账户密码改成自己摄像头注册的信息
    camera_ip_l = [
        "10.16.55.149",  # ipv4
        "10.16.55.150",
        # 把你的摄像头的地址放到这里,如果是ipv6,那么需要加一个中括号
    ]
    ports=['554','555']

    mp.set_start_method(method='spawn')  # init
    queues = [mp.Queue(maxsize=2) for _ in camera_ip_l]
    processes = [mp.Process(target=image_collect, args=(queues, camera_ip_l))]
    #processes = []
    for queue, camera_ip,port in zip(queues, camera_ip_l,ports):
        processes.append(mp.Process(target=image_put, args=(queue, user_name, user_pwd, camera_ip,port)))
        processes.append(mp.Process(target=image_get, args=(queue, camera_ip)))
    for process in processes:
        process.daemon = True  # setattr(process, 'deamon', True)
        process.start()
    for process in processes:
        process.join()

if __name__ == '__main__':
    run_multi_camera()           # 调用主函数

效果图:
在这里插入图片描述

4.2代码2

把两个摄像头收集到的实时画面传给同一个进程:

# 代码描述:利用多进程方法,利用两个海康威视摄像头,同时录取视频并保存本地
import cv2
import time
import multiprocessing as mp

# 抓取图片,确认视频流的读入
def image_put(q, name, pwd, ip, channel):
    cap = cv2.VideoCapture("rtsp://%s:%s@%s:%s//Streaming/Channels/1" \
                           % (name, pwd, ip, channel))
    # 获取视频帧率
    fps = cap.get(cv2.CAP_PROP_FPS)
    print('fps: ', fps)
    if cap.isOpened():
        print('HIKVISION1')
        print('camera ' + ip + " connected.")

    while True:
        q.put(cap.read()[1])
        q.get() if q.qsize() > 1 else time.sleep(0.01)

def image_collect(queue_list, camera_ip_l):
    import numpy as np

    """show in single opencv-imshow window"""
    window_name = "%s_and_so_no" % camera_ip_l[0]
    cv2.namedWindow(window_name, flags=cv2.WINDOW_FREERATIO)
    while True:
        imgs = [q.get() for q in queue_list]
        imgs = np.concatenate(imgs, axis=1)
        cv2.imshow(window_name, imgs)
        cv2.waitKey(1)
# 解决进程问题
def run_multi_camera():
    # user_name, user_pwd = "admin", "password"
    user_name, user_pwd = "admin", "a12345678"
    # 摄像头的账户密码改成自己摄像头注册的信息
    camera_ip_l = [
        "10.16.55.149",  # ipv4
        "10.16.55.150",
        # 把你的摄像头的地址放到这里,如果是ipv6,那么需要加一个中括号
    ]
    ports=['554','555']

    mp.set_start_method(method='spawn')  # init
    queues = [mp.Queue(maxsize=2) for _ in camera_ip_l]
    processes = [mp.Process(target=image_collect, args=(queues, camera_ip_l))]
    #processes = []
    for queue, camera_ip,port in zip(queues, camera_ip_l,ports):
        processes.append(mp.Process(target=image_put, args=(queue, user_name, user_pwd, camera_ip,port)))

    for process in processes:
        process.daemon = True  # setattr(process, 'deamon', True)
        process.start()
    for process in processes:
        process.join()

if __name__ == '__main__':
    run_multi_camera()           # 调用主函数

效果图:
在这里插入图片描述

目录
相关文章
|
1天前
|
计算机视觉
Opencv学习笔记(八):如何通过cv2读取视频和摄像头来进行人脸检测(jetson nano)
如何使用OpenCV库通过cv2模块读取视频和摄像头进行人脸检测,并提供了相应的代码示例。
14 1
|
1天前
FFmpeg学习笔记(二):多线程rtsp推流和ffplay拉流操作,并储存为多路avi格式的视频
这篇博客主要介绍了如何使用FFmpeg进行多线程RTSP推流和ffplay拉流操作,以及如何将视频流保存为多路AVI格式的视频文件。
16 0
|
1天前
|
编解码 计算机视觉 Python
Opencv学习笔记(九):通过CV2将摄像头视频流保存为视频文件
使用OpenCV库通过CV2将摄像头视频流保存为视频文件,包括定义视频编码格式、设置保存路径、通过write写入视频文件,并提供了相应的Python代码示例。
8 0
|
1月前
|
设计模式 缓存 Java
谷粒商城笔记+踩坑(14)——异步和线程池
初始化线程的4种方式、线程池详解、异步编排 CompletableFuture
谷粒商城笔记+踩坑(14)——异步和线程池
|
2月前
|
Java 程序员
从0到1,手把手教你玩转Java多线程同步!
从0到1,手把手教你玩转Java多线程同步!
27 3
|
2月前
|
Java 测试技术
Java多线程同步实战:从synchronized到Lock的进化之路!
Java多线程同步实战:从synchronized到Lock的进化之路!
91 1
|
4天前
|
存储 消息中间件 资源调度
C++ 多线程之初识多线程
这篇文章介绍了C++多线程的基本概念,包括进程和线程的定义、并发的实现方式,以及如何在C++中创建和管理线程,包括使用`std::thread`库、线程的join和detach方法,并通过示例代码展示了如何创建和使用多线程。
17 1
C++ 多线程之初识多线程
|
19天前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
4天前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
22 6
|
1天前
|
存储 运维 NoSQL
Redis为什么最开始被设计成单线程而不是多线程
总之,Redis采用单线程设计是基于对系统特性的深刻洞察和权衡的结果。这种设计不仅保持了Redis的高性能,还确保了其代码的简洁性、可维护性以及部署的便捷性,使之成为众多应用场景下的首选数据存储解决方案。
5 1