欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

javacv 实现目标轨迹框叠加

程序员文章站 2022-03-26 15:14:37
javacv 实现视频中物体目标坠落轨迹框叠加添加javacv依赖包: org.bytedeco javacv-platform 1.5.2...

javacv 实现视频中物体目标坠落轨迹框叠加
添加javacv依赖包:

		<!-- Java CV依赖 -->
		<dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.2</version>
        </dependency>

事先准备要执行叠加的视频和算法生成的视频帧数据 gaopao.json:

{
  "track": [
    {
      "x": 1162,
      "y": 338,
      "width": 11,
      "height": 12,
      "pts": 182475634947
    },
    {
      "x": 1161,
      "y": 320,
      "width": 14,
      "height": 14,
      "pts": 182475714922
    },
    {
      "x": 1163,
      "y": 301,
      "width": 12,
      "height": 13,
      "pts": 182475794909
    },
    {
      "x": 1164,
      "y": 287,
      "width": 10,
      "height": 16,
      "pts": 182475874977
    },
    {
      "x": 1165,
      "y": 283,
      "width": 10,
      "height": 11,
      "pts": 182475954924
    }
  ],
  "Info": [
    {
      "channel": 100,
      "frame_pts": 182473081868,
      "pts_sys": 182472626937,
      "size": 399091,
      "width": 1080,
      "height": 1920,
      "format": 265,
      "frame_type": 0,
      "offset": 0
    },
    {
      "channel": 100,
      "frame_pts": 182473281868,
      "pts_sys": 182472825672,
      "size": 95054,
      "width": 1080,
      "height": 1920,
      "format": 265,
      "frame_type": 1,
      "offset": 399091
    },
    {
      "channel": 100,
      "frame_pts": 182473481868,
      "pts_sys": 182473025489,
      "size": 85004,
      "width": 1080,
      "height": 1920,
      "format": 265,
      "frame_type": 1,
      "offset": 494145
    },
    {
      "channel": 100,
      "frame_pts": 182473681867,
      "pts_sys": 182473225433,
      "size": 72923,
      "width": 1080,
      "height": 1920,
      "format": 265,
      "frame_type": 1,
      "offset": 579149
    },
    {
      "channel": 100,
      "frame_pts": 182473881868,
      "pts_sys": 182473425287,
      "size": 78356,
      "width": 1080,
      "height": 1920,
      "format": 265,
      "frame_type": 1,
      "offset": 652072
    }
  ]
}

Info对象集合是帧数据,帧数都上往下,track对象集合是目标轨迹框坐标,与帧数据是一一对应。
代码执行部分:

package com.demo.common.testall;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.FrameGrabber.Exception;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import sun.font.FontDesignMetrics;

/** 
* @author 作者 weidaoru: 
* @version 创建时间:2020年12月30日 下午4:12:44 
* 类说明 
*/

public class JavaCVTest {
	private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static void main(String[] args) throws Exception, org.bytedeco.javacv.FrameRecorder.Exception, InterruptedException, ExecutionException{
		// 读取视频帧数相关数据文件
		String filePath = "D:\\project\\test\\gaopao.json";
		String dataStr = readJsonFile(filePath);
		JSONObject dataJson = JSONObject.fromObject(dataStr);
        // 设置源视频、目标框叠加的视频文件路径
        FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault("D:\\project\\test\\gaopao.mp4");
        grabber.start();
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("D:\\project\\test\\javacv-2.mp4",1920, 1080, 2);
        // 视频相关配置,取原视频配置
        recorder.setFrameRate(grabber.getFrameRate());
        recorder.setVideoCodec(grabber.getVideoCodec());
        recorder.setVideoBitrate(grabber.getVideoBitrate());
        
        recorder.start();
        Java2DFrameConverter converter = new Java2DFrameConverter();
        Frame frame;
        System.out.println("视频帧数:" + grabber.getLengthInFrames());
        int i = 0;
        while ((frame = grabber.grab()) != null) {
            // 从视频帧中获取图片
            if (frame.image != null) {
                BufferedImage bufferedImage = converter.getBufferedImage(frame);
                bufferedImage = imageToOSD(bufferedImage,dataJson,i);
                // 视频帧赋值,写入输出流
                frame.image = converter.getFrame(bufferedImage).image;
                recorder.record(frame);
            }
            i++;
        }
        grabber.stop();
        recorder.stop();
	}
	private static BufferedImage imageToOSD(BufferedImage bufImg, JSONObject dataJson,int i) {
		if (!dataJson.isEmpty()) {
			Font font = new Font("微软雅黑", Font.BOLD, 25);
			JSONArray infoArray = dataJson.getJSONArray("Info");
			JSONArray trackArray = dataJson.getJSONArray("track");
			JSONObject info = infoArray.getJSONObject(i);
			long pts_sys = info.getLong("pts_sys");
			for (int j=0,lens=trackArray.size();j<lens;j++) {
				JSONObject track = trackArray.getJSONObject(j);
				long pts = track.getLong("pts");
				if (pts < pts_sys) {
					int x1 = track.getInt("x");
			        int y1 = track.getInt("y");
			        int x2 = track.getInt("width");
			        int y2 = track.getInt("height");
			        Graphics2D graphics = bufImg.createGraphics();
					graphics.setColor(Color.red);
			        graphics.setFont(font);
			        // 画矩形框(原点x坐标,原点y坐标,矩形的长,矩形的宽)
			        graphics.drawRect(x1, y1,x2, y2); 
			        graphics.dispose();
				}
			}
		}
		return bufImg;
	}
	private static String readJsonFile(String filePath) {
		String jsonStr = "";
        try {
            File jsonFile = new File(filePath);
            FileReader fileReader = new FileReader(jsonFile);
            Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
            int ch = 0;
            StringBuffer sb = new StringBuffer();
            while ((ch = reader.read()) != -1) {
                sb.append((char) ch);
            }
            fileReader.close();
            reader.close();
            jsonStr = sb.toString();
            return jsonStr;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
	}
}

生成视频效果图:

javacv 实现目标轨迹框叠加这和在视频上添加字幕类似

本文地址:https://blog.csdn.net/m0_37715184/article/details/112019916

相关标签: java ffmpeg