python - 如何减少获取帧时的CPU使用率

标签 python opencv

我正在一个项目中,我需要使用20个摄像机来执行操作。我的问题是,当我使用opencv拍摄多于4个摄像机时,cpu使用率超过90%。
如何增加摄像机数量,以降低CPU使用率?
例如,我正在考虑使用vlc读取框架,但不知道如何实现它们。
我的系统信息是:cpu 9700k core i7,gpu nvidia 1080 ti,32gb ram。

     import cv2
     Cap = cv2.VideoCapture("rtsp example...")
     while True:
              ret,frame=cap.read()
              cv2.imshow("frame",frame)

这是捕获一台摄像机的示例,并且我将另一实例用于其他摄像机。
实际上,我正在使用IP摄像机检索rtsp流(opencv库)并将我的深度学习算法应用于这些帧的面部识别系统。我上面列出的服务器系统只能有4个摄像机,并且不能超过cpu的使用情况允许添加摄像机。
我的第一个问题是如何以合理的fps有效地增加摄像机数量
第二个问题是如何为这些类型的项目选择合适的硬件?

最佳答案

我通过直接使用FFmpeg读取帧来使其更快。可能会有更好的方法来做到这一点,但这是一个批准。我假设您已经以不同的方式启动了视频捕获,对吗?否则,这也是明智的一步。

import numpy
from multiprocessing import Process
from subprocess import Popen, PIPE
import cv2

class ffmpeg_videocapture:
    def __init__(self, stream, width=640, height=360, scale=1, fps=15):
        self.command = 'ffmpeg -rtsp_transport udp -i {i} -pix_fmt bgr24 -s {w}x{h} -vcodec rawvideo ' \
                       '-an -sn -r {fps} -f image2pipe pipe:1'

        self.stream = stream
        self.width = width
        self.height = height
        self.scale = scale
        self.fps = fps

        self.errors = []
        self.start()

    def start(self):
        width = int(self.width * self.scale)
        height = int(self.height * self.scale)
        command = self.command.format(i=self.stream, w=width, h=height, fps=self.fps)
        self.capture = Popen(command.split(' '), stdout=PIPE, stderr=PIPE, bufsize=10 ** 8)

    def read(self):
        width = int(self.width * self.scale)
        height = int(self.height * self.scale)
        raw_image = self.capture.stdout.read(width * height * 3)

        frame = numpy.fromstring(raw_image, dtype='uint8')
        frame = frame.reshape((height, width, 3))

        self.capture.stdout.flush()

        return frame is not None, frame

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.capture.terminate()


def single_camera(rtsp_stream):
    cap = ffmpeg_videocapture(rtsp_stream)
    while True:
        ret, frame = cap.read()
        cv2.imshow("frame", frame)

if __name__ == "__main__":
    rtsp_stream_list = [
        "rtsp_stream_1",
        "rtsp_stream_2",
        "etc...",
    ]

    for rtsp_stream in rtsp_stream_list:
        t = Process(target=single_camera, args=(rtsp_stream,))
        t.start()

关于python - 如何减少获取帧时的CPU使用率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58298601/

相关文章:

Python脚本长执行函数

python - 在已知坐标的图像上应用轻微透明的蒙版

c++ - 精明的边缘检测

c++ - Point Grey Research Triclops 只读取 1 帧

c++ - 从 Kmeans 中找到每个集群的分布

c++ - OpenCV 在不同线程上运行来自网络摄像头的视频

c++ - 如何旋转图像中的特定部分?

python - 验证架构并将其应用于 python 中的列表

python - 如何查看 Flask 应用程序是否正在本地主机上运行?

python - 列表中第一个元素乱序