我在Process1中捕获了一个h264实时视频流(我称之为“流”)。我的目标是在流中提取流中的每个帧,并使用Process2使用OpenCV对其进行分析。 (Process1是nodejs,Process2是Python)
我成功地将Process1中的流引导到了管道中。但是,在Process2(Python)中,我无法(a)从流中提取单个帧,并且(b)将来自h264的任何提取数据转换为OpenCV格式(例如JPEG,numpy数组)。
我曾希望使用OpenCV的VideoCapture()方法,但它不允许您将FIFO管道作为输入传递。我可以通过将h264流保存为.h264文件,然后将其作为文件路径传递来使用VideoCapture。这对我没有帮助,因为我需要实时进行分析(即我在将数据流读入OpenCV之前无法将其保存到文件中)。
我使用命令尝试了这个:
cat pipeFromProcess1.fifo | ffmpeg -i pipe:0 -f h264 -f mjpeg pipe:1 |猫> pipeToProcess2.fifo
这种方法的最大问题是FFMPEG从Process1获取输入,直到Process1被终止,然后Process2才开始接收数据。
此外,在Process2方面,我仍然不了解如何从管道上的数据中提取单个帧。我打开管道进行读取(如“f”),然后执行data = f.readline()。数据的大小变化很大(一些读取的长度大约为100,其他读取长度大约为1,000)。当我使用f.read()而不是f.readline()时,长度要大得多,大约为100,000。
如果我知道我正在获取正确大小的数据块,我仍然不知道如何将其转换为OpenCV兼容的数组,因为我不理解它的格式。它是一个字符串,但是当我把它打印出来时,它看起来像这样:
_M~0A0 tQ,\% e f / H #Y p f# Kus }F ʳa G + $x %V } [ Wo 1'̶A c * &amp; = Z ^ o' Ͽ SX-ԁ涶V&amp; ; H | $ 〜 &lt; E &gt; u 7 cR f = 9 fs q ڄߧ 9v ] Ӷ &安培; GR] NIRܜ台 + I w } 9 o w M m IJ IJ m = So} S &gt; j , ƙ ' tad=i WY FeC֓z 2 g ;EXX S Ҁ*, w _| &amp; y H = < em> ) 3@ h Ѻ Ɋ ZzR` ) y c . v !u S I# $9R Ԯ0pyz 8# A q ͕ ͕ c bp= 9cSqH
从base64转换似乎没有帮助。我也尝试过:
array = np.fromstring(data, dtype=np.uint8)
确实转换为数组,但不是基于我正在尝试解码的帧的640x368x3维度而有意义的大小之一。
这些似乎专注于流式传输到网站,而且我没有成功尝试将它们重新用于我的目标。
我发现了许多关于将h264视频流式传输到网站的相关问题。这是一个已解决的问题,但没有一个解决方案可以帮助我提取单个帧并将它们置于OpenCV兼容格式中。
另外,我需要在不断的基础上实时使用提取的帧。因此将每个帧保存为.jpg是没有用的。
Raspberry Pi 3运行Raspian Jessie
我试图概括我在问题中遇到的问题。如果知道有用,Process1正在使用node-bebop包来从Parrot Bebop 2.0下拉h264流(使用drone.getVideoStream())。我尝试使用node-bebop(getMjpegStream())提供的其他视频流。这有效,但几乎不是实时的;我得到了非常间歇性的数据流。我已将此特定问题作为node-bebop存储库中的问题输入。
感谢阅读;我真的很感激任何人都可以给予帮助!
答案 0 :(得分:0)
您有没有找到解决方案?
网上有一些建议可以使用以下标准将h264流传输到opencv程序中:
some-h264-stream | ./opencv-program
其中opencv-program包含类似的内容:
VideoCapture cap("/dev/stdin");
答案 1 :(得分:0)
通过设置以下环境变量,我能够使用Python中的OpenCV(使用FFMPEG构建)打开Parrot Anafi流:
export OPENCV_FFMPEG_CAPTURE_OPTIONS="rtsp_transport;udp"
FFMPEG默认为TCP传输,但无人机的提要是UDP,因此这为FFMPEG设置了正确的模式。
然后使用:
cv2.VideoCapture(<stream URI>, cv2.CAP_FFMPEG)
ret, frame = cap.read()
while ret:
cv2.imshow('frame', frame)
# do other processing on frame...
ret, frame = cap.read()
if (cv2.waitKey(1) & 0xFF == ord('q')):
break
cap.release()
cv2.destroyAllWindows()
照常。
这也可以与鹦鹉Bebop一起使用,但我没有人对其进行测试。