【问题标题】:Extract image frames from an MJPG file从 MJPG 文件中提取图像帧
【发布时间】:2012-12-13 13:07:58
【问题描述】:

我正在尝试从 IP 摄像头的短片中提取图像帧。特别是这个剪辑。

http://db.tt/GQwu0nZ8

所以,我正在尝试用 ffmpeg 提取那些帧。

ffmpeg -i M00001.jpg -vcodec mjpeg -f image2 image%03d.jpg

我只得到剪辑的第一帧。我怎样才能得到其余的帧?我可以使用其他工具来获取这些图像吗?

谢谢

【问题讨论】:

  • 您可以使用我的库,这可能比 HTTP 出于各种原因抓取帧更好...如果 cam 支持 RTP 或 RTSP net7mma.codeplex.com

标签: image ffmpeg mjpeg


【解决方案1】:

这可能太多了,但这里有一个用于 Node.js https://nodejs.org/ 的简短 javascript 程序,它将删除所有可读帧并将它们保存为当前目录中单独的顺序编号的 jpg 文件。请注意,即使是简短的视频剪辑也可以生成数千帧,并且 Node 使用的 V8 javascript 引擎非常快,因此我建议关闭文件浏览器,因为它会占用资源来跟上。

如果视频文件太大而无法为其创建缓冲区,Node 将发出错误并退出。
在这种情况下,最简单的做法是使用您的 shell 实用程序或 HexEdit 之类的程序将文件拆分为多个块。 http://www.hexedit.com/

重写此代码以异步处理文件将解决该问题,但编写异步代码仍然让我感到焦虑。

var orgFile=process.cwd()+"/"+process.argv[2]; //Grab the video filename from the command line
var fs = require("fs"); //Load the filesystem module
var stats = fs.statSync(orgFile);//Get stats of video file
var fileSizeInBytes = stats["size"];//Get video file size from stats
var fdata=new Buffer(fileSizeInBytes);//Create a new buffer to hold the video data
var i=0;
var fStart=0;
var fStop=0;
var fCount=0;
fdata=fs.readFileSync(orgFile);//Read the video file into the buffer
//This section looks for the markers at the begining and end of each jpg image
//records their positions and then writes them as separate files.
while (i<fileSizeInBytes){

if (fdata[i]==0xFF){
    //console.log("Found FF at "+i.toString);
    if (fdata[i+1]==0xD8){
        //console.log("Found D8 at "+(i+1).toString);

        if (fdata[i+2]==0xFF){
            //console.log("Found FF at "+(i+2).toString);
            fStart=i;
            }
        }
    }
if (fStart>0){
    if (fdata[i]==0xFF){
        if(fdata[i+1]==0xD9){
            fStop=i+1;

        }
    }
if (fStart>0){
    if (fStop>0){
    fCount++;
    fs.writeFileSync(orgFile+"."+fCount.toString()+".jpg",fdata.slice(fStart,fStop));   
    console.log (orgFile+"."+fCount.toString()+".jpg");
    fStart=0;
    fStop=0;
    }
}
}

i++;
}

console.log ("Wrote "+fCount.toString()+" frames.");

如果您将上述代码保存为 mjpeg_parse.js,则调用示例将是:

节点 mjepeg_parse.js videofile.avi

【讨论】:

    【解决方案2】:

    带有ffmpeg 的命令可以正常工作,但是您需要将 mjpeg 视频指定为输入文件。如果M00001.jpg 是单个 jpg 图像,那么您将只得到一个(相同的)输出图像。

    【讨论】:

    • 事实上,IP cam 将“图像”返回为 mjpg 视频。使用厂商的软件,可以看到生成的图片是视频。
    • @edsonlp1 如我所见,它是 Mobotix 相机生成的 MxPEG 格式。你是怎么得到这个图像的?您可以通过 url http://&lt;CAMERA_IP&gt;/cgi-bin/faststream.jpg 访问 mjpeg 流吗?如果是这样,您可以尝试将此 url 作为输入传递给 ffmpeg。不幸的是,我无法使用 ffmpeg 解码实时 MxPEG 流。但它可以轻松解码流的下载部分(例如使用wget 'http://&lt;CAMERA_IP&gt;/cgi-bin/faststream.jpg' 下载)。
    • 我从相机的存储中提取了该图像。您如何提取信息并且您知道它是 MxPEG 格式?通过 url 的流对我不起作用,因为我需要图像的最高质量和分辨率。谢谢
    • 您上传的jpeg图片有一些data in the comment,从中我们可以看到它是Mobotix相机和MxPEG格式。您可以通过HTTP API 访问该流并选择适合您需要的streaming parameters
    • @edsonlp1 例如,我用谷歌搜索了a random camera,我可以通过 HTTP API 看到它的help page。我使用wget -O vid.mjpg 'http://58.93.69.127/cgi-bin/faststream.jpg' 下载了部分流,现在我可以使用您问题中的ffmpeg 命令从vid.mjpg 中提取图像帧。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2019-02-24
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多