【问题标题】:How to capture video by video from one rtsp Url using Opencv?如何使用 Opencv 从一个 rtsp Url 逐个视频捕获视频?
【发布时间】:2021-09-01 02:40:46
【问题描述】:

服务器正在使用相同的 RTSP URL(rtsp://192.168.0.2:8554/) 逐个视频发送视频 我可以使用 opencv 捕获和显示视频。

import numpy as np
import cv2 as cv
os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp"

cap = cv.VideoCapture('rtsp://192.168.0.2:8554/')
while cap.isOpened():
    ret, frame = cap.read()
    # if frame is read correctly ret is True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    cv.imshow('frame', frame)
    if cv.waitKey(1) == ord('q'):
        break
cap.release()
cv.destroyAllWindows()

该程序在播放下一个视频时返回错误。 我试过了,但是没有用。

import cv2 as cv
import os
import time

os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp"

cap = cv.VideoCapture('rtsp://192.168.0.26:8554/')
if not cap.isOpened():
    print("Cannot open camera")
    exit()
while True:
    try:
        time.sleep(2)
        # Capture frame-by-frame
        ret, frame = cap.read()
        # if frame is read correctly ret is True
        # Our operations on the frame come here
        # Display the resulting frame
        cv.imshow('frame',frame)
        if cv.waitKey(1) == ord('q'):
            break
    except:
        print("Exception!!")
        # When everything done, release the capture
        cap.release()
        cv.destroyAllWindows()

我能得到一些帮助吗? 提前致谢!

【问题讨论】:

    标签: python opencv rtsp


    【解决方案1】:

    我通过使用多线程程序解决了这个问题。

    主文件

    from datasets import LoadStreams
    
    import threading
    import os
    import logging
    import cv2
    import torch
    import time
    logger = logging.getLogger(__name__)
    
    
    def select_device(device='', batch_size=None):
        # device = 'cpu' or '0' or '0,1,2,3'
        cpu_request = device.lower() == 'cpu'
        if device and not cpu_request:  # if device requested other than 'cpu'
            os.environ['CUDA_VISIBLE_DEVICES'] = device  # set environment variable
            assert torch.cuda.is_available(), f'CUDA unavailable, invalid device {device} requested'  # check availablity
    
        cuda = False if cpu_request else torch.cuda.is_available()
        if cuda:
            c = 1024 ** 2  # bytes to MB
            ng = torch.cuda.device_count()
            if ng > 1 and batch_size:  # check that batch_size is compatible with device_count
                assert batch_size % ng == 0, f'batch-size {batch_size} not multiple of GPU count {ng}'
            x = [torch.cuda.get_device_properties(i) for i in range(ng)]
            s = f'Using torch {torch.__version__} '
            for i, d in enumerate((device or '0').split(',')):
                if i == 1:
                    s = ' ' * len(s)
                logger.info(f"{s}CUDA:{d} ({x[i].name}, {x[i].total_memory / c}MB)")
        else:
            logger.info(f'Using torch {torch.__version__} CPU')
    
        logger.info('')  # skip a line
        return torch.device('cuda:0' if cuda else 'cpu')
    
    
    def detect(rtsp_url):
        dataset = LoadStreams(rtsp_url)
        device = select_device('')
        count = 0
        view_img = True
        # img = torch.zeros((1, 3, imgsz, imgsz), device=device)  # init img
    
        try:
            for frame_idx, (path, img, im0s, vid_cap) in enumerate(dataset):  # for every frame
                count += 1
                im0 = im0s[0].copy()
                if view_img:
                    cv2.imshow(str(path), im0)
                    # if cv2.waitKey(1) == ord('q'):  # q to quit
                    #     raise StopIteration
        except:
            print("finish execption")
            dataset.stop()
        return "good"
    
    if __name__ == '__main__':
        rtsp_url = "rtsp://192.168.0.26:8554/"
        while True:
            for thread in threading.enumerate():
                print(thread.name)
            print(detect(rtsp_url))
    

    数据集类文件

    import glob
    import logging
    import math
    import os
    import random
    import shutil
    import time
    import re
    from itertools import repeat
    from multiprocessing.pool import ThreadPool
    from pathlib import Path
    from threading import Thread
    
    import cv2
    import numpy as np
    import torch
    
    class LoadStreams:  # multiple IP or RTSP cameras
        def __init__(self, sources='streams.txt', img_size=640):
            self.mode = 'stream'
            self.img_size = img_size
            self.capture = None
            self.my_thread = None
            self.stopFlag = False
    
            if os.path.isfile(sources):
                with open(sources, 'r') as f:
                    sources = [x.strip() for x in f.read().strip().splitlines() if len(x.strip())]
            else:
                sources = [sources]
    
            n = len(sources)
            self.imgs = [None] * n
            self.sources = [clean_str(x) for x in sources]  # clean source names for later
            s = sources[0]
            # for i, s in enumerate(sources):
            # Start the thread to read frames from the video stream
            # print('%g/%g: %s... ' % (i + 1, n, s), end='')
            cap = cv2.VideoCapture(eval(s) if s.isnumeric() else s)
            assert cap.isOpened(), 'Failed to open %s' % s
            w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            fps = cap.get(cv2.CAP_PROP_FPS) % 100
            self.ret, self.imgs[0] = cap.read()  # guarantee first frame
            thread = Thread(target=self.update, args=([0, cap]), daemon=True)
            print(' success (%gx%g at %.2f FPS).' % (w, h, fps))
            thread.start()
            self.capture = cap
            self.my_thread = thread
            print('')  # newline
    
            # check for common shapes
            s = np.stack([letterbox(x, new_shape=self.img_size)[0].shape for x in self.imgs], 0)  # inference shapes
            self.rect = np.unique(s, axis=0).shape[0] == 1  # rect inference if all shapes equal
            if not self.rect:
                print('WARNING: Different stream shapes detected. For optimal performance supply similarly-shaped streams.')
    
        def update(self, index, cap):
            # Read next stream frame in a daemon thread
            n = 0
            while cap.isOpened() and not self.stopFlag:
                n += 1
                # _, self.imgs[index] = cap.read()
                cap.grab()
                if n == 4:  # read every 4th frame
                    _, self.imgs[index] = cap.retrieve()
                    n = 0
                time.sleep(0.01)  # wait time
    
        def stop(self):
            self.stopFlag = True
            try:
                # self.capture.release()
                # self.my_thrsead.join()
                print("stop thread!!")
            except:
                print("ERROR stopping thread!!")
    
        def __iter__(self):
            self.count = -1
            return self
    
        def __next__(self):
            self.count += 1
            img0 = self.imgs.copy()
            if cv2.waitKey(1) == ord('q'):  # q to quit
                cv2.destroyAllWindows()
                raise StopIteration
    
            if not self.ret:
                print("error!!!")
                self.stop()
    
            # Letterbox
            img = [letterbox(x, new_shape=self.img_size, auto=self.rect)[0] for x in img0]
    
            # Stack
            img = np.stack(img, 0)
    
            # Convert
            img = img[:, :, :, ::-1].transpose(0, 3, 1, 2)  # BGR to RGB, to bsx3x416x416
            img = np.ascontiguousarray(img)
    
            return self.sources, img, img0, None
    
        def __len__(self):
            return 0  # 1E12 frames = 32 streams at 30 FPS for 30 years
    
        # def stop(self):
    
    
    
    def clean_str(s):
        # Cleans a string by replacing special characters with underscore _
        return re.sub(pattern="[|@#!¡·$€%&()=?¿^*;:,¨´><+]", repl="_", string=s)
    
    
    def letterbox(img, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False, scaleup=True):
        # Resize image to a 32-pixel-multiple rectangle https://github.com/ultralytics/yolov3/issues/232
        shape = img.shape[:2]  # current shape [height, width]
        if isinstance(new_shape, int):
            new_shape = (new_shape, new_shape)
    
        # Scale ratio (new / old)
        r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
        if not scaleup:  # only scale down, do not scale up (for better test mAP)
            r = min(r, 1.0)
    
        # Compute padding
        ratio = r, r  # width, height ratios
        new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
        dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]  # wh padding
        if auto:  # minimum rectangle
            dw, dh = np.mod(dw, 32), np.mod(dh, 32)  # wh padding
        elif scaleFill:  # stretch
            dw, dh = 0.0, 0.0
            new_unpad = (new_shape[1], new_shape[0])
            ratio = new_shape[1] / shape[1], new_shape[0] / shape[0]  # width, height ratios
    
        dw /= 2  # divide padding into 2 sides
        dh /= 2
    
        if shape[::-1] != new_unpad:  # resize
            img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
        top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
        left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
        img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)  # add border
        return img, ratio, (dw, dh)
    
            while cap.isOpened() and not self.stopFlag:
    

    这一行特别重要,因为 没有这条线,线程将被堆叠并会出现内存错误 随着堆栈的堆积。

    【讨论】:

      猜你喜欢
      • 2014-01-29
      • 1970-01-01
      • 2013-11-27
      • 2016-01-09
      • 2021-04-18
      • 1970-01-01
      • 2018-07-26
      • 2018-07-30
      • 2020-05-05
      相关资源
      最近更新 更多