opencv javacv

原创
2018/08/22 19:40
阅读数 1.5K

javacv 依赖

implementation 'org.bytedeco:javacv:1.4.2'
implementation 'org.bytedeco.javacpp-presets:opencv:3.4.0-1.4.2:android-arm'
implementation 'org.bytedeco.javacpp-presets:ffmpeg:3.4.0-1.4.2:android-arm'

mat 转图片

Utils.matToBitmap(myMat, myBitmap);

默认VideoWirter 只支持 MJPG 以及后缀.avi 文件

VideoWriter
('M','J','P','G') is the only supported by android while using .avi ext.

图片录制成mp4 api >= 18

https://developer.android.google.cn/reference/android/media/MediaMuxer https://stackoverflow.com/questions/17096726/how-to-encode-bitmaps-into-a-video-using-mediacodec

javacv

https://stackoverflow.com/questions/32988843/android-ffmpegframerecorder-javacv-unsatisfiedlinkerror

jcodec (纯java 慢)

https://stackoverflow.com/questions/21546906/how-to-open-cvvideowriter-in-android

openh264

https://github.com/cisco/openh264

使用javacv 中的FFmpegFrameRecorder 将bitmap 录制成mp4。(快)opencv 还是使用官网的opencv4android

//由于现在的javacv 只有armeabi-v7a架构的arm。我就把opencv的so放到armeabi-v7a里去
    AndroidFrameConverter converter = new AndroidFrameConverter();
    public long currentTs = 0;
    public long startTs = 0;
    int imageWidth = 0;
    int imageHeight = 0;
    private int fps = 10;
    private FFmpegFrameRecorder recorder;
    private boolean isStart = false;
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

void startRecord(){
        try {

            startTs = 0;
            recorder = new FFmpegFrameRecorder(Environment.getExternalStorageDirectory().getAbsolutePath() + "/A_Test/test.mp4", imageWidth, imageHeight);
            recorder.setVideoCodec(2);
            recorder.setFrameRate(fps);
            recorder.setFormat("mp4");
            recorder.start();
            isStart = true;
        }catch (FrameRecorder.Exception e){
            e.printStackTrace();
        }
    }
    void record(Mat rgba){
        long now = System.currentTimeMillis();
        if(!isStart||recorder==null){
           return;
        }

        if((now-currentTs)>=(1000/fps)) {


            if(bmp==null){
                bmp = Bitmap.createBitmap(imageWidth,imageHeight, Bitmap.Config.ARGB_8888);
            }

            Utils.matToBitmap(rgba, bmp);
            try {
                Frame frame = converter.convert(bmp);
                synchronized (recorder) {
                    if(startTs==0){
                        startTs = now;
                    }
                    if((now-startTs)*1000>recorder.getTimestamp()) {
                        recorder.setTimestamp((now-startTs)*1000);
                    }
                    recorder.record(frame);
                }

            }catch (FrameRecorder.Exception e){
                e.printStackTrace();
            }
            currentTs = now;

        }
    }


    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {

        mRgba = inputFrame.rgba();
        mGray = inputFrame.gray();
        //时间戳水印
        //Imgproc.putText(mRgba, dateFormat.format(Calendar.getInstance().getTime()), new Point(40,40), Core.FONT_ITALIC,1.0f,new Scalar(255,255,255), 2);
        record(mRgba);
        return mRgba;
    }


展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部