Video record from an IP camera with variable frame rate with opencv and python(用OpenCV和PYTHON实现可变帧速率的IP摄像机录像)
问题描述
首先,我想对我正在尝试做的事情发表评论。 我有一台IP摄像机通过带有以太网线的路由器连接到我的网络(FOSCAM 9800p),我正尝试从它录制使用RTSP协议的视频。我未来的打算是在中间添加一个OpenCV的小视频处理功能,但目前我想做一些测试,以便简单地录制它。
主要问题是摄像机每秒传输的帧速率是可变的,也就是说,有时它会传输到18帧,其他时候会传输到22帧,以此类推。当以每秒固定的帧速率录制视频时,最终会出现视频播放速度过快
奇怪的是,当我使用OpenCV GET(CAP_PROP_FPS)运行时,它返回一个很大的值,如180000.0
要尝试解决此问题,我们要做的是读取帧并将它们放入队列。从计时器控制的另一个进程。Event()我们读取它们,并尝试以固定的时间间隔写入视频,以获得固定的帧速率。
代码如下:
video_capture = cv2.VideoCapture("rtsp://"+user+":"+password+"@"+ip+":"+str(port)+"/videoMain")
if (video_capture.isOpened() == False):
print("Unable to read camera feed")
sys.exit()
frame_width = int(video_capture.get(3))
frame_height = int(video_capture.get(4))
video_writer =cv2.VideoWriter(output_filename,cv2.VideoWriter_fourcc(*'MP4V'), fps_to_save, (frame_width,frame_height))
input_buffer = queue.Queue(20)
finished = False
read_frames = 0
def readFile():
global finished
global read_frames
while not finished:
ret, frame = video_capture.read()
if not ret:
finished = True
while not finished:
try:
input_buffer.put_nowait(frame)
read_frames+=1
break
except queue.Full:
print("queue.Full")
pass
def processingFile():
global finished
written_frames = 0
repeated_frames = 0
time_per_frame_elapsed = 0.0
start_time=time.time()
ticker = threading.Event()
while True:
ticker.wait(time_per_frame-time_per_frame_elapsed)
time_per_frame_start=time.time()
try:
frame = input_buffer.get_nowait()
video_writer.write(frame)
writing_time = time.time()
if written_frames is 0:
start_time = writing_time
written_frames += 1
except queue.Empty:
if written_frames is not 0:
video_writer.write(frame)
writing_time = time.time()
written_frames += 1
repeated_frames += 1
except:
pass
total_elapsed_time = time.time() - start_time
print("total_elapsed_time:{:f}".format(total_elapsed_time))
if total_elapsed_time>time_to_save_seconds:
finished = True
ticker.clear()
print ("Playback terminated.")
break
time_per_frame_elapsed=time.time()-time_per_frame_start
print("Total readed frames:{:f}".format(read_frames))
print("Total frames repated:{:f}".format(repeated_frames))
print("Total frames writed:{:f}".format(written_frames))
tReadFile = threading.Thread(target=readFile)
tProcessingFile = threading.Thread(target=processingFile)
tReadFile.start()
tProcessingFile.start()
tProcessingFile.join()
tReadFile.join()
结果接近我们想要的,但有时我们在时代上会有重大差异。我们正在用大约10秒的短视频进行测试,我们得到了9.8秒的记录。
起初,这似乎不是一个严重的问题,但错误是累积的,也就是说,如果我们增加时间增加,那么录制时间更长的视频就会有更严重的问题。
我们想知道如何使用以不同速率传送帧的相机来解决这种类型的视频录制问题。这样做好吗?
是什么原因导致时间累积误差?
从已经开始非常感谢!
大家好!
推荐答案
我只能说一件事。在我个人的经验中,OpenCV视频捕获类在在线模式下与FFMPEG(OpenCV使用它来解码视频)的工作非常糟糕。有很多图像伪像和ffmpeg内部错误。但VideoCapture与USB摄像头配合使用效果非常好。我用XSplit广播器解决了IP摄像机的在线捕捉问题。这个包能够通过物理IP摄像头模拟USB摄像头。唯一的限制是将相机帧的大小调整为640*480大小。XSplit广播公司的基本许可证是完全免费的
这篇关于用OpenCV和PYTHON实现可变帧速率的IP摄像机录像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:用OpenCV和PYTHON实现可变帧速率的IP摄像机录像
- 将文件从Azure文件加载到Azure数据库 2022-09-21
- 为什么切换屏幕在Kivy中不起作用? 2022-09-21
- 如何命名HDF5数据集中的列? 2022-09-21
- H5py:如何在HDF5组和数据集上使用key()循环 2022-09-21
- 合并具有多个索引和列值的数据帧 2022-09-22
- 获取多索引中某个级别的最后一个元素 2022-09-22
- 如何防止Groupby超越指数? 2022-09-22
- 如何将属性添加到作为组存储在HDF5文件中的 pa 2022-09-21
- 基于多个一级列的子集多索引DataFrame 2022-09-22
- 使用带有CROSS_VAL_SCORE的自定义估计器失败 2022-09-21