我在试着做一个mjpeg拖缆。帧前面的前5个字节表示它的大小。然后我可以提取帧。我需要检查一下我的相框是否正确。我试图将帧写入.jpeg文件;但这不起作用。 我做得对吗?在
import os
from array import array
class VideoStream:
def __init__(self,filename):
self.fis = open(filename,'r')
self.frame_nb = 0
def getnextframe(self):
length = 0
frame_length = bytearray(5)
frame_length = self.fis.read(5)
fm = array('B',frame_length[:5])
length = fm[4]+((fm[3]<<8)&0xFF)+((fm[2]<<16)&0xFF)+((fm[1]<<24)&0xFF)+((fm[0]<<32)&0xFF)
frame = self.fis.read(length)
print 'len=',length
test = open("test.jpeg",'w')
test.write(frame)
test.close()
print 'frame=',frame
if __name__=='__main__':
vs = VideoStream("Movie.mjpeg")
vs.getnextframe()
代码中的长度实际上就是第五个字节的值。将所有其他求和数至少向左移动8位,然后屏蔽除最低8位之外的所有位。由于前面的移位操作,这些位都是零。在
一个简单的附加测试可以实现的是,如果帧数据以JPEG开始的图像标记(
FF D8
)开始,并以图像结束标记(DD D9
)结束。在下面的函数应该迭代JPEG图像,这些图像由5个ascii字符长的帧长度计数分隔,就像您要移植到Python的VideoStream.java:
它检查字节计数值和JPEG数据是否完整,以及JPEG开始和结束标记是否存在。在
比你想象的要简单得多。但是有一个问题:这种格式很可能是由Java类的作者编写的。在
MJPEG只是一个视频编解码器,基本上只是JPEG图像的拼接。但它很少以“原始”格式出现,而是嵌入到包含元数据的容器格式中,比如MJPEG数据、帧速率、音频等等。在
其中一种格式是AVI,如您在注释中引用的example MJPEG avi。在
从这样一个文件中提取帧到单个JPEG图像要比读取以简单长度信息为前缀的JPEG图像并将其连接到一个文件中的工作量要大一些。我们需要实现一个AVI读取器,它对AVI格式有足够的了解,以获取帧数据。然后是一个JPEG读取器,它能读懂JPEG格式的全部帧,因为它们是背靠背保存的,没有任何长度信息。在
下一个问题是并非所有的mjpeg都包含可用作独立JPEG图像的帧。有些缺少解压缩图像数据所需的数据表(huffman表)。在MJPEG编解码器的AVI规范中有一个固定的表。软件使用该表进行解码,当保存为JPEG文件时,必须将其注入帧中。在
最后一件事:有一些交错的视频不包含完整的图像,但是两个连续的图像需要合并成一个。每个图像包含其他行。你给出的example MJPEG avi就是这样一个视频。在不解码、去隔行和重编码的情况下提取帧时,每个图像的高度只有视频高度的一半。在
为了更好地了解单个图像的外观,
^{pr2}$ffmpeg
命令行提取帧数据并注入缺失的数据表,以便获得独立的JPEG图像:相关问题 更多 >
编程相关推荐