JavaCV调用摄像头

安装Javacv

  • 简介:javacv是使用java的视觉库,包含了Opencv、FFmpeg等接口

  • github-javacv

  • 若是Intellij IEDA可直接新建Maven项目,在pom.mxl中添加依赖,IDEA将自动下载依赖库

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>Camera</groupId>
    <artifactId>cTest</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--添加如下依赖-->
    <dependencies>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5</version>
        </dependency>
    </dependencies>
    
</project>

调用实例

import org.bytedeco.javacv.*;
import javax.swing.*;

public class test {
    public void testCamera(){
        try {
            //VideoInputFrameGrabber grabber = VideoInputFrameGrabber.createDefault(0);
            OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
            grabber.start();//开始获取摄像头数据
            CanvasFrame canvas = new CanvasFrame("摄像头");//新建一个窗口
            canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            canvas.setAlwaysOnTop(true);
            while (true) {
                if (!canvas.isDisplayable()) {//窗口是否关闭
                    grabber.stop();//停止抓取
                    System.exit(-1);//退出
                }

                Frame frame = grabber.grab();
                canvas.showImage(frame);//获取摄像头图像并放到窗口上显示,frame是一帧视频图像
                Thread.sleep(30);//50毫秒刷新一次图像
            }
        }catch (FrameGrabber.Exception e){
            e.printStackTrace();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

录制视频

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point;
import org.bytedeco.opencv.opencv_core.Scalar;

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Date;

public class VideoRecorder implements Runnable{

    private static final int FRAME_RATE = 30;
    private static final int MOTION_FACTOR = 1;

    private CanvasFrame canvas = null;
    private FFmpegFrameRecorder recorder = null;
    private VideoInputFrameGrabber grabber = null;
    private OpenCVFrameConverter.ToIplImage converter =  null;

    private Window win = null;

    private Point point = null;
    private Scalar scalar = null;
    private SimpleDateFormat sdf = null;

    private void configVideo(String strFileName){
        try {
            grabber = VideoInputFrameGrabber.createDefault(0);
            grabber.start();
        }catch (FrameGrabber.Exception e){
            e.printStackTrace();
        }
        int imgWidth = grabber.getImageWidth();
        int imgHeight = grabber.getImageHeight();
        System.out.printf("W:%d H:%d\n",imgWidth,imgHeight);

        recorder = new FFmpegFrameRecorder(strFileName,imgWidth,imgHeight);
        recorder.setFormat("flv");
        recorder.setFrameRate(FRAME_RATE);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setVideoBitrate((int)((imgWidth*imgHeight*FRAME_RATE)*MOTION_FACTOR*0.07));
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);

        converter = new OpenCVFrameConverter.ToIplImage();

        point = new Point(10, 50);
        scalar = new Scalar(255, 0, 0, 0);
        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try{
            recorder.start();//start开始就开始保存数据
        }catch (FrameRecorder.Exception e){
            e.printStackTrace();
        }
    }

    private void configWindow(){
        canvas = new CanvasFrame("Video");
        canvas.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        canvas.setAlwaysOnTop(true);
    }

    private void encodeFrame(Frame frame,long timestamp){
        try{
            long t = timestamp * 1000L;
            if (t > recorder.getTimestamp()) {
                recorder.setTimestamp(t);
            }
            recorder.record(frame);
        }catch (FrameRecorder.Exception e){
            e.printStackTrace();
        }
    }

    private void stopRecorder(){
        if(recorder!=null){
            try{
                recorder.stop();
                recorder.release();
            }catch (FrameRecorder.Exception e){
                e.printStackTrace();
            }
        }
    }

    public void run(){
        configWindow();
        configVideo("test.flv");
        try {
            while (true) {
                if (!canvas.isDisplayable()) {
                    grabber.stop();
                    System.exit(-1);
                }

                Mat mat = converter.convertToMat(grabber.grab());
                Date date = new Date();

                opencv_imgproc.putText(mat,
                        sdf.format(date),
                        point,
                        opencv_imgproc.CV_FONT_VECTOR0,
                        1.0, scalar, 1, 0,false);

                canvas.showImage(converter.convert(mat));
			   encodeFrame(converter.convert(mat),System.currentTimeMillis());
                //Thread.sleep(30);
            }
        }catch (FrameGrabber.Exception e){
            e.printStackTrace();
        }
    }
}

参考链接


版权声明:本文为robothj原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。