我想做的是:
ffmpeg -i udp://224.10.10.10:15004 -qscale:v 2 sttest%04d.jpg
然后将此输出图像路径传递给python脚本,当ffmpeg
正在运行时,它会单独接收图像并对其进行操作(最终我将使用ffmpy
来调用{{1而不是使用命令行工具,但为了现在的测试目的,我从这里开始。)
我想有一种方法可以在每次处理图像时查看ffmpeg输出的目录,看看是否有新图像,然后将其加载到python中(使用OpenCV) - 如果没有要处理的新图像,则等待一定的时间间隔。
但是有更好的方法吗,比如将图像的路径直接发送到某种队列,然后python脚本可以逐个处理?
答案 0 :(得分:1)
由于FFmpeg没有输出“我生成的文件名”,您唯一的选择是使用您拥有的文件系统。
根据您的操作系统,可能有一种方法可以在目录中触摸新文件时收到通知。我不知道这是否适用于linux,windows,os x,但它值得研究。
事实上,这看起来很简单,你不会通过外部调用ffmpeg来拥有来实现它。 ffmpeg基本上是libavcodec
的用户前端,这是一个用于解码和编码视频,音频等的库。
因此,您可能只想在应用程序中使用libavcodec
。我实际上认为,如果使用实际的媒体流体系结构,那么你想要做的事情会容易得多。 GStreamer可能是你选择的工具,你可以直接使用python进行处理,但我没有多少经验。
你的目标应该是直接在你的python程序中获取帧,而不必绕过将它们写入磁盘。
简单的MJPEG(Motion JPEG)转换器,如果您不想使用stdin
或libav*
,只需通过管道传输到程序的gstreamer
可能是最简单的方式。
答案 1 :(得分:0)
对于任何好奇的人,这是我的解决方案。它正在使用OpenCV
。我在问这个问题时并没有意识到这一点,但是OpenCV
具有在幕后使用ffmpeg
的某些功能。而且由于我的程序已经使用OpenCV
,我只是在提问中提到(因为我认为它不重要),使用OpenCV
中内置的功能并不是很困难。做我想做的事。这是代码:
cap = cv2.VideoCapture("video.mpg")
count = 0
frame_q = queue.Queue()
while cap.grab():
success, frame = cap.read()
if count % 5 == 0 and success:
frame_alpha = np.insert(frame, 3, 255, axis=2)
frame_q.put(frame_alpha)
count += 1
正如您所看到的,我只是将每个第五帧放入Queue
个帧中。其核心是这三条线:
cap = cv2.VideoCapture("video.mpg")
while cap.grab():
success, frame = cap.read()
第一行打开捕获,while子句使用cap.grab()
检查是否还有帧(如果有下一帧则返回True
)然后我将该帧读入{{ 1}}数组使用numpy
。 cap.read()
是一个布尔值,表示操作是否成功。之后,我向success
添加了一个Alpha通道,并将其放入frame
。
然后,程序frame_q
的另一个线程框出get
。这样,我根本不需要处理文件系统 - 就像Marcus说的那样,我将它们直接送到程序中。
注意: Queue
工作cv2.VideoCapture()
需要位于系统路径或您opencv_ffmpeg.dll
的任何Python
安装的根目录中使用。您可能需要将其重命名为opencv_ffmpegXYZ.dll
,其中XYZ是OpenCV
版本号减去小数点。所以对我来说,它是opencv_ffmpeg330.dll
因为我有版本3.3.0
。它也可能在x64系统上被称为opencv_ffmpeg330_64.dll
。
opencv_ffmpeg.dll
的位置取决于您安装OpenCV
的方式,我只需在OpenCV
目录中搜索opencv_ffmpeg
并查看其出现位置。在将其复制到Python
目录之前,请务必检查它是否已存在。它可能是,取决于您安装OpenCV
的方式。