如何解决如何使用 Opencv 从一个 rtsp Url 捕获一个视频?
服务器正在使用相同的 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()
我能得到一些帮助吗? 提前致谢!
解决方法
我通过使用多线程程序解决了这个问题。
主文件
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,2) # BGR to RGB,to bsx3x416x416
img = np.ascontiguousarray(img)
return self.sources,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:
这一行特别重要,因为 如果没有这一行,线程将被堆叠并出现内存错误 随着堆栈的堆积。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。