【javaCV基于虹软人脸识别demo添加电脑摄像头人脸识别(图片保存,视频保存,摄像头显示等 )(附源码)】

javaCV基于虹软人脸识别demo添加电脑摄像头人脸识别(图片保存,视频保存,摄像头显示等 )(附源码)


前言

最近领导让做一个人脸识别项目,在网上找了一个虹软的人脸识别demo,留意了一下,然后再将人脸识别搞完之后,重新下了一个人脸识别服务端完整demo,配置好app_idsdk_key之后,(没有虹软app_id和不会配置的同学请点击),项目正常运行,demo原有的功能如下:
人脸识别服务端完整demo功能图


提示:今天我主要的目的是说一下开启本地摄像头进行人脸识别,有兴趣的同学自己试一下上面的功能。
(注意视频流识别可能需要在手机或者电脑上旋转保存再播放、或者在代码读到某一帧图片的时候,进行旋转,才能识别出来,因为目前只能识别正脸)
项目源码在文章最下方。
保存图片比较简单,在images文件夹下保存自己的照片,再在FaceController的 如下代码下加入自己的数据就可以了,比如我是小明,我就加一个我的图片,在重启一下项目,照片就加载到内存缓存中了。

fileMap.put(“xiaoming”, “小明”);

一、摄像头部分代码块

1.controller层



    /**
     * 打开摄像头进行人脸识别/保存人脸图片/保存人脸视频
     * @param response
     * @throws Exception
     */
    @GetMapping(value = "/streamCamera")
    public void streamCamera(HttpServletResponse response) throws Exception {
    
    

        videoPlayerService.servletStreamPlayer(response);
    }

2.service层(service层分三层讲,第一层:保存图片;第二层:保存视频;第三层:打开摄像头)

2.1保存图片

public void servletStreamPlayer(HttpServletResponse response) throws Exception {
    
    

        //启动人脸处理引擎
        FacePreview faceProcessEngine = new FacePreview(appId, sdkKey);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
        OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);//新建opencv抓取器,一般的电脑和移动端设备中摄像头默认序号是0,不排除其他情况
        grabber.setImageWidth(600);
        grabber.setImageHeight(400);
        grabber.start();//开始获取摄像头数据
        
        int i = 1;
        for (; ; ) {
    
    
            Frame frame = grabber.grab();
            if (frame == null) {
    
    
                continue;
            }
            IplImage iplImage = converter.convert(frame);//抓取一帧视频并将其转换为图像,至于用这个图像用来做什么?加水印,人脸识别等等自行添加
            if (iplImage != null) {
    
    
                // 一帧图片插入人脸图框
                faceProcessEngine.preview(iplImage);
                frame = converter.convert(iplImage);
            }
            // ======================================保存为图片(开始)============================================
            File imgFile = new File("想要保存的路径\\picture\\" + i + ".jpg");
           //判断保存的文件的文件夹是否存在,不存在创建。
            if (!imgFile.getParentFile().exists()) {
    
    
                System.out.println("保存文件的文件夹不存在,创建。");
                imgFile.getParentFile().mkdirs();
            }
            RenderedImage renderedImage = VideoProcessing.frameToBufferedImage(frame);
            ImageIO.write(renderedImage, "jpg", imgFile);
            // ======================================保存为图片(结束)============================================
            // 添加i++就是按照休眠时间保存图片,注释掉就只保存最后一帧图片,转换一下思路,假设休眠200ms, 那一秒保存五次图片,那么打开这张图片,过滤掉加载的白屏,就是5帧的视频
//            i++;
            if (outputStream.size() > 0) {
    
    
                byte[] bytes = outputStream.toByteArray();
                response.getOutputStream().write(bytes);
                outputStream.reset();
            }
            Thread.sleep(200);
            System.out.println("休眠200ms!!!");
        }
    }

2.2保存视频

public void servletStreamPlayer(HttpServletResponse response) throws Exception {
    
    

        //启动人脸处理引擎
        FacePreview faceProcessEngine = new FacePreview(appId, sdkKey);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
        OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);//新建opencv抓取器,一般的电脑和移动端设备中摄像头默认序号是0,不排除其他情况
        grabber.setImageWidth(600);
        grabber.setImageHeight(400);
        grabber.start();//开始获取摄像头数据
        // ======================================保存为视频(开始)============================================
// 流媒体输出地址,分辨率(长,高),是否录制音频(0:不录制/1:录制) ?overrun_nonfatal=1&fifo_size=50000000
        //这里udp地址增加参数扩大udp缓存
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("想要保存的路径\\picture\\" + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ".flv", grabber.getImageWidth(), grabber.getImageHeight(), 0);
        // 直播流格式
        // 转码
        recorder.setFormat("flv");
        recorder.setInterleaved(false);
        recorder.setVideoOption("tune", "zerolatency");
        recorder.setVideoOption("preset", "ultrafast");
        recorder.setVideoOption("crf", "26");
        recorder.setVideoOption("threads", "1");
        double frameRate = grabber.getFrameRate();
        recorder.setFrameRate(frameRate);// 设置帧率
        recorder.setGopSize(25);// 设置gop,关键帧
        int videoBitrate = grabber.getVideoBitrate();
        recorder.setVideoBitrate(videoBitrate);// 设置码率500kb/s,画质
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.setTrellis(1);
        recorder.setMaxDelay(0);// 设置延迟
        recorder.setAudioChannels(grabber.getAudioChannels());
        recorder.start();
        // ======================================保存为视频(开始)============================================

        long startTime = 0;
        long videoTS = 0;
        for (; ; ) {
    
    
            Frame frame = grabber.grab();
            if (frame == null) {
    
    
                continue;
            }
            IplImage iplImage = converter.convert(frame);//抓取一帧视频并将其转换为图像,至于用这个图像用来做什么?加水印,人脸识别等等自行添加
            if (iplImage != null) {
    
    
                // 一帧图片插入人脸图框
                faceProcessEngine.preview(iplImage);
                frame = converter.convert(iplImage);
            }
            if (startTime == 0) {
    
    
                startTime = System.currentTimeMillis();
            }
            videoTS = 1000 * (System.currentTimeMillis() - startTime);
//             判断时间偏移
            if (videoTS > recorder.getTimestamp()) {
    
    
                recorder.setTimestamp((videoTS));
            }
            recorder.record(frame);
            if (outputStream.size() > 0) {
    
    
                byte[] bytes = outputStream.toByteArray();
                response.getOutputStream().write(bytes);

                outputStream.reset();

            }
            Thread.sleep(100);
            System.out.println("休眠100ms!!!");
        }
    }

2.3页面打开摄像头

首先介绍一下四个参数的作用

DO_NOTHING_ON_CLOSE,(在你点击关闭按钮的时候,不会被关闭,)不执行任何操作。
HIDE_ON_CLOSE,(当你点击关闭按钮的时候,不会释放内存,只是隐藏该界面,没有真正的关闭,还占有资源)只隐藏界面,setVisible(false)。
DISPOSE_ON_CLOSE,点击关闭按钮的时候,隐藏并释放窗体,dispose(),当最后一个窗口被释放后,则程序也随之运行结束。
EXIT_ON_CLOSE,直接关闭应用程序,System.exit(0)。一个main函数对应一整个程序。**

CanvasFrame canvas = new CanvasFrame(“摄像头预览”);//新建一个预览窗口
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

public void servletStreamPlayer(HttpServletResponse response) throws Exception {
    
    

        //启动人脸处理引擎
        FacePreview faceProcessEngine = new FacePreview(appId, sdkKey);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
        OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);//新建opencv抓取器,一般的电脑和移动端设备中摄像头默认序号是0,不排除其他情况
        grabber.setImageWidth(600);
        grabber.setImageHeight(400);
        grabber.start();//开始获取摄像头数据

        CanvasFrame canvas = new CanvasFrame("摄像头预览");//新建一个预览窗口
        canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        canvas.setVisible(true);
        canvas.setFocusable(true);

        // 窗口置顶
        if (canvas.isAlwaysOnTopSupported()) {
    
    
            canvas.setAlwaysOnTop(true);
        }
        for (; ; ) {
    
    
            Frame frame = grabber.grab();
            if (frame == null) {
    
    
                continue;
            }
            IplImage iplImage = converter.convert(frame);//抓取一帧视频并将其转换为图像,至于用这个图像用来做什么?加水印,人脸识别等等自行添加
            if (iplImage != null) {
    
    
                // 一帧图片插入人脸图框
                faceProcessEngine.preview(iplImage);
                frame = converter.convert(iplImage);
            }
            // 获取摄像头图像并放到窗口上显示,frame是一帧图像
            canvas.showImage(frame);
            if (outputStream.size() > 0) {
    
    
                byte[] bytes = outputStream.toByteArray();
                response.getOutputStream().write(bytes);

                outputStream.reset();

            }
            Thread.sleep(100);
            System.out.println("休眠100ms!!!");
        }
    }

其中主要是这一步:把在2.1得到的每一帧图片按照设定的休眠时间放在打开的窗口上展示,展示出来的就是一个视频
// 获取摄像头图像并放到窗口上显示,frame是一帧图像
canvas.showImage(frame);

二、运行结果

在这里插入图片描述

总结

经历了CV的捶打,结果终于出来了,人脸识别成功之后下节做人脸识别登录。
本项目git地址:https://gitee.com/table-tennis-king/faceForCamera.git

猜你喜欢

转载自blog.csdn.net/qq_42900934/article/details/127427279