在我的系统中,我有一个摄像头,我从摄像头得到了一个图像序列,但是每张图像之间的时间间隔是不一样的。见下文:
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│ │ │ │ │ │ │ │
│image├─►│image├─►│image├─►│image├─►
│ │ │ │ │ │ │ │
└─────┘ └─────┘ └─────┘ └─────┘
t0 t1 t2 t3
基本上,
t1-t0 != t2-t1
,和t3-t2 != t2-t1
.
一个简单的方法可以将这些图像作为单独的文件,例如
09-39-001.png
,09-39-058.png
,文件名包含图像的分秒毫秒时间戳。使用这种方法,我得到了很多文件,如果我得到很多图像,它运行很慢。我猜的原因是磁盘有两个文件创建选项。
我知道有很多方法可以将它们存储在一个文件中,例如,将它们保存到一个
mp4
文件中,例如OpenCV
库有一种方法可以通过 mp4
对象写入 cv::VideoWriter
文件。但是使用这种方法,mp4
文件以恒定速率(例如30fps)存储图像,并且我的时间戳信息丢失了。当我尝试重播 mp4 文件时,每个图像(帧)都以固定时间间隔的方式播放。唯一的好处是 mp4 是压缩的,因此它的文件大小小于单独图像文件的总数。
我听说
ROS
系统可以捕获图像并将其保存在bag
或bag2
文件中,我认为使用ROS
对于我的简单项目来说有点复杂。在我的简单项目中,我需要从其他来源捕获相机图像和一个或多个传感器数据,因此我确实需要一种方法来保存这些数据,以便我以后可以及时准确地回复它们。
作为结论,我需要一种方法来在一个简单的文件中使用它们的时间戳相同的数据,然后再次播放。希望文件可以像
mp4
文件一样压缩,但我认为文件大小是次要因素。
有什么建议吗?谢谢。
我想我可以自己回答这个问题,有几种方法可以解决这个问题:
方法一,使用
FFmpeg
库(支持变帧率录制)
这是在我对自己的问题的回答中完成的:save a serial of images(cv::Mat) to a mp4 file in Variable Frame Rate mode by using
ffmpeg
library, how to set the pts?
在这个答案(附源代码)中,我可以正确设置每一帧的
PTS
值,结果mp4文件将尊重图像的每个时间戳。
源代码:
保存到 mp4 文件:opencv-image-to-mp4.cpp
读取 mp4 文件并通过 opencv 显示它们:read_image_from_mp4_imshow.cpp
方法二,使用原来的
OpenCV
方法cv::VideoWriter
,只支持恒帧率录制,但时间戳可以保存在另一个文件中
使用这种方法,我必须添加一个单独的文件,例如“timestamp.txt”文件以及 mp4 文件,该文件应包含视频文件中每个保存图像的时间戳,如@fana 的讨论建议,我在 github gist 中有一个测试代码:save image sequence to mp4 file, and read them back