将h264字节字符串转换为OpenCV图像

2024-09-26 22:42:50 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中,如何将一个h264字节的字符串转换成OpenCV可以读取的图像,只保留最新的图像?在

长版:

大家好。在

在Python中工作时,我试图以管道方式从adb screenrecord获取输出,以便在需要时捕捉帧并与OpenCV一起使用。据我所知,我需要不断地阅读流,因为它是h264。在

我尝试了很多方法来让它工作,并得出结论,我需要寻求具体的帮助。在

以下是我需要的流,当我打印时效果很好stream.stdout.read(n) 一。在

import subprocess as sp

adbCmd = ['adb', 'exec-out', 'screenrecord', '--output-format=h264', '-']
stream = sp.Popen(adbCmd, stdout = sp.PIPE, universal_newlines = True)

通用换行符是使它在Windows上运行所必需的。在

正在做:

^{pr2}$

有效。在

问题是我现在尝试使用ffmpeg获取输入的h264流并输出尽可能多的帧,如果需要,覆盖最后一帧。在

ffmpegCmd = ['ffmpeg', '-f', 'image2pipe', '-pix_fmt', 'bgr24', '-vcodec', 'h264', 'fps=30', '-']
ffmpeg = sp.Popen(ffmpegCmd, stdin = stream.stdout, stdout = sp.PIPE, universal_newlines = True)

这是我认为应该使用的,但是我总是得到错误“输出文件0不包含任何流”。在

编辑:

最终答案

原来,universal\u newlines选项正在破坏行结尾并逐渐损坏输出。另外,ffmpeg命令是错误的,请看洛德内克比尔德的回答。在

下面是正确的ffmpeg命令以实现所使用的功能:

ffmpegCmd = ['ffmpeg', '-i', '-', '-f', 'rawvideo', '-vcodec', 'bmp', '-vf', 'fps=5', '-']
ffmpeg = sp.Popen(ffmpegCmd, stdin = stream.stdout, stdout = sp.PIPE)

然后,要将结果转换为OpenCV图像,请执行以下操作:

fileSizeBytes = ffmpeg.stdout.read(6)
fileSize = 0
for i in xrange(4):
    fileSize += fileSizeBytes[i + 2] * 256 ** i
bmpData = fileSizeBytes + ffmpeg.stdout.read(fileSize - 6)
image = cv2.imdecode(np.fromstring(bmpData, dtype = np.uint8), 1)

这将获得流的每一帧作为OpenCV图像。在


Tags: 图像readstreamstdoutopencvspffmpeguniversal
2条回答

使用以下任一选项:

ffmpeg -i - -pix_fmt bgr24 -f rawvideo -
ffmpeg -i pipe: -pix_fmt bgr24 -f rawvideo pipe:
ffmpeg -i pipe:0 -pix_fmt bgr24 -f rawvideo pipe:1
  • 您没有提供有关输入的太多信息,因此可能需要添加其他输入选项。

  • 您没有指定所需的输出格式,所以我选择了rawvideo。您可以使用ffmpeg -muxers(或者如果您的ffmpeg过期,ffmpeg -formats)查看受支持的输出格式(muxer)列表。不是所有的都适合管道,例如MP4。

  • FFmpeg Protocols: pipe

只需稍作改动即可正常工作: 这将在循环中读取流并每次显示最后一个图像

adbCmd = ['adb', 'exec-out', 'screenrecord', ' output-format=h264', '-']
stream = sp.Popen(adbCmd, stdout = sp.PIPE)

ffmpegCmd =['ffmpeg', '-i', '-', '-f', 'rawvideo', '-vf', 'scale=324:576', 
'-vcodec', 'bmp',  '-']
ffmpeg = sp.Popen(ffmpegCmd, stdin = stream.stdout, stdout = sp.PIPE)

while True:
    fileSizeBytes = ffmpeg.stdout.read(6)
    fileSize = 0
    for i in xrange(4):
        fileSize += array.array('B',fileSizeBytes[i + 2])[0] * 256 ** i
    bmpData = fileSizeBytes + ffmpeg.stdout.read(fileSize - 6)
    image = cv2.imdecode(np.fromstring(bmpData, dtype = np.uint8), 1)
    cv2.imshow("im",image) 
    cv2.waitKey(25)

相关问题 更多 >

    热门问题