python篇—python读取rtsp流,并消耗(多种方式)

1.python读取rtsp流,并消耗(用线程)

import os
import cv2
import gc
import time
import threading
import numpy as np
from PIL import Image

top = 100

stack = []


# 向共享缓冲栈中写入数据:
def write(stack, cam, top: int) -> None:
    """
    :param cam: 摄像头参数
    :param stack: list对象
    :param top: 缓冲栈容量
    :return: None
    """
    print('Process to write: %s' % os.getpid())
    cap = cv2.VideoCapture(cam)
    while True:
        _, img = cap.read()
        if _:
            stack.append(img)
            print(stack)
            # 每到一定容量清空一次缓冲栈
            # 利用gc库,手动清理内存垃圾,防止内存溢出

            if len(stack) >= top:
                del stack[:]
                gc.collect()


# 在缓冲栈中读取数据:
def read(stack) -> None:
    print('Process to read: %s' % os.getpid())
    # 开始时间
    t1 = time.time()
    # 图片计数
    count = 0

    while True:
        if len(stack) != 0:
            # 开始图片消耗
            print("stack的长度", len(stack))
            if len(stack) != 100 and len(stack) != 0:
                value = stack.pop()
            else:
                pass

            if len(stack) >= top:
                del stack[:]
                gc.collect()

            # 格式转变,BGRtoRGB
            frame = cv2.cvtColor(value, cv2.COLOR_BGR2RGB)
            # # 转变成Image
            frame = Image.fromarray(np.uint8(frame))

            print("*" * 100)

            count += 1
            print("数量为:", count)

            t2 = time.time()
            print("时间差:", int(t2 - t1))

            if int(t2 - t1) == 600:
                # 记录 消耗的图片数量
                with open('count.txt', 'ab') as f:
                    f.write(str(count).encode() + "\n".encode())
                    f.flush()

                # count = 0  # 不要置零,计算总数
                t1 = t2


if __name__ == '__main__':
    for i in range(1):
        thread_pro = threading.Thread(target=write, args=(stack, "rtsp://admin:xxxx@123@192.168.0.65:554/Streaming/Channels/1 ", top,))
        thread_pro.start()

    for j in range(3):
        thread_con = threading.Thread(target=read, args=(stack,))
        thread_con.start()

2.python读取rtsp流,并消耗(用进程)

注:该代码适合在本机跑,不适合在jetson的小盒子上运行

import os
import cv2
import gc
import time
import numpy as np
from PIL import Image

import multiprocessing
from multiprocessing import Process, Manager


top = 100

# 向共享缓冲栈中写入数据:
def write(stack, cam, top: int) -> None:
    """
    :param cam: 摄像头参数
    :param stack: Manager.list对象
    :param top: 缓冲栈容量
    :return: None
    """
    print('Process to write: %s' % os.getpid())
    cap = cv2.VideoCapture(cam)
    while True:
        _, img = cap.read()
        if _:
            stack.append(img)
            # 每到一定容量清空一次缓冲栈
            # 利用gc库,手动清理内存垃圾,防止内存溢出
            if len(stack) >= top:
                del stack[:]
                gc.collect()


# 在缓冲栈中读取数据:
def read(stack) -> None:
    print('Process to read: %s' % os.getpid())
    # 开始时间
    t1 = time.time()
    # 图片计数
    count = 0

    while True:
        if len(stack) != 0:
            # 开始图片消耗
            print("stack的长度", len(stack))
            if len(stack) != 100 and len(stack) != 0:
                value = stack.pop()
            else:
                pass

            if len(stack) >= top:
                del stack[:]
                gc.collect()

            # 格式转变,BGRtoRGB
            frame = cv2.cvtColor(value, cv2.COLOR_BGR2RGB)
            # # 转变成Image
            frame = Image.fromarray(np.uint8(frame))

            print("*" * 100)

            count += 1
            print("数量为:", count)

            t2 = time.time()
            print("时间差:", int(t2 - t1))

            if int(t2 - t1) == 600:
                # 记录 消耗的图片数量
                with open('count.txt', 'ab') as f:
                    f.write(str(count).encode() + "\n".encode())
                    f.flush()

                # count = 0  # 不要置零,计算总数
                t1 = t2


if __name__ == '__main__':
    multiprocessing.set_start_method('forkserver', force=True)
    # 父进程创建缓冲栈,并传给各个子进程:
    q = Manager().list()
    pw = Process(target=write, args=(q, "rtsp://admin:xxxx@123@192.168.0.65:554/Streaming/Channels/1", top))
    pr = Process(target=read, args=(q,))
    # 启动子进程pw,写入:
    pw.start()
    # 启动子进程pr,读取:
    pr.start()

    # 等待pr结束:
    pr.join()

    # pw进程里是死循环,无法等待其结束,只能强行终止:
    pw.terminate()

3.python读取rtsp流,并消耗(普通)

import os
import cv2
import gc
import time
import numpy as np
from PIL import Image


top = 100

stack = []

# 向共享缓冲栈中写入数据:
def write(stack, cam, top: int) -> None:
    """
    :param cam: 摄像头参数
    :param stack: list对象
    :param top: 缓冲栈容量
    :return: None
    """
    print('Process to write: %s' % os.getpid())
    cap = cv2.VideoCapture(cam)

    # 开始时间
    t1 = time.time()
    # 图片计数
    count = 0

    while True:
        _, img = cap.read()
        if _:
            stack.append(img)
            # print(stack)

            # 在缓冲栈中读取数据:
            if len(stack) != 0:
                # 开始图片消耗
                print("stack的长度", len(stack))
                if len(stack) != 100 and len(stack) != 0:
                    value = stack.pop()
                else:
                    pass

                # 格式转变,BGRtoRGB
                frame = cv2.cvtColor(value, cv2.COLOR_BGR2RGB)
                # # 转变成Image
                frame = Image.fromarray(np.uint8(frame))

                print("*" * 100)

                count += 1
                print("数量为:", count)

                t2 = time.time()
                print("时间差:", int(t2 - t1))

                if int(t2 - t1) == 600:
                    # 记录 消耗的图片数量
                    with open('count.txt', 'ab') as f:
                        f.write(str(count).encode() + "\n".encode())
                        f.flush()

                    t1 = t2

            # 每到一定容量清空一次缓冲栈
            # 利用gc库,手动清理内存垃圾,防止内存溢出

            if len(stack) >= top:
                del stack[:]
                gc.collect()


if __name__ == '__main__':
    write(stack, "rtsp://admin:xxxx@123@192.168.0.65:554/Streaming/Channels/1", top)

4. 验证 本机 是否支持python rtsp 的GPU 加速

安装以下命令

pip install opencv-contrib-python
print(cv2.getBuildInformation())

在这里插入图片描述
在这里插入图片描述

5. 代码:python rtsp 的GPU加速

该代码还有问题,后续继续更新

import cv2
pipeline = "rtspsrc location=\"rtsp://login:password@host:port/\" ! rtph264depay ! h264parse ! omxh264dec ! nvvidconv ! video/x-raw, format=(string)BGRx! videoconvert ! appsink"
capture = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)

while capture.isOpened():
    res, frame = capture.read()
    cv2.imshow("Video", frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break
capture.release()
cv2.destroyAllWindows()
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐