Java集成opencv,将视频进行图片拆帧处理

851 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

项目需求需要将视频按帧进行拆分,并通过获取每帧的当前时间与视频文件名中的时间进行计算,最终结果命名为抽帧图片的文件名。案例中只有部分代码,不影响集成使用。

1、window10 系统 安装opencv 4.52版本

下载地址:Find out more about OpenCV | SourceForge.net

下载之后自定义安装目录,进行下一步安装操作即可。

2、将Opencv库添加到项目中

在IDEA 中的 Project Structure => Modules => Dependencies 中添加 opencv 安装目录下的的jar包 D:\opencv\build\java\opencv-452.jar

同时将D:\opencv\build\java\x64\opencv_java452.dll,添加为Native Libary

image.png

3、直接上代码实现视频图片拆帧

//加载本地的OpenCV库,这样就可以用它来调用Java API
 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

视频拆帧代码:

   // 创建VideoCapture对象 
VideoCapture cap = new VideoCapture(videoPath);
                    //判断视频是否打开
       if (cap.isOpened()) {
                        //总帧数
         int frameCount = new Double(cap.get((Videoio.CAP_PROP_FRAME_COUNT))).intValue();
 
         logger.info("{}视频一共{}帧", file_name, frameCount);
                        // 创建mat
         Mat frame = new Mat();
         for (int i = 0; i < frameCount; i++) {
               // 读取下一帧的数据
              if (cap.read(frame)) {
                  // 获取当前帧的时间戳
            int video_mesc = new Double(cap.get(Videoio.CAP_PROP_POS_MSEC)).intValue();
//          cap.set(Videoio.CAP_PROP_POS_MSEC,2 * 1000);
            //  file_date通过视频名字获取时间,然后根据帧的视频戳进行相加计算
            String curTime = simpleDateFormat.format(new Date(file_date.getTime() + video_mesc));
            String outFileName = out_directory + File.separator + file_name + "@" + curTime + ".jpg";
            // 写出图片
            Imgcodecs.imwrite(outFileName, frame);
    }
}

4、集成过程中遇见的问题

1)VideoCapture的isOpened()方法一直返回false。

将opencv安装目录D:\opencv\build\x64\vc14\bin中的opencv_videoio_ffmpeg452_64.dll复制到生成 java的安装目录 C:\Program Files\Java\jdk1.8.0_191\bin 中去。

2) 读取帧 提示:[NULL @ 0000022362197940] non-existing PPS 0 referenced

当根据时间获取相应的帧数据时,会出现ffmpeg解析问题,不知道如何解决。暂时没用,给注掉了。

 cap.set(Videoio.CAP_PROP_POS_MSEC,2 * 1000);