草庐IT

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

啷个半呢 2023-08-06 原文

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

文章目录


前言

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

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

  1. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  2. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  3. [Vuforia]二.3D物体识别 - 2

    之前说过10之后的版本没有3dScan了,所以还是9.8的版本或者之前更早的版本。 3d物体扫描需要先下载扫描的APK进行扫面。首先要在手机上装一个扫描程序,扫描现实中的三维物体,然后上传高通官网,在下载成UnityPackage类型让Unity能够使用这个扫描程序可以从高通官网上进行下载,是一个安卓程序。点到Tools往下滑,找到VuforiaObjectScanner下载后解压数据线连接手机,将apk文件拷入手机安装然后刚才解压文件中的Media文件夹打开,两个PDF图打印第一张A4-ObjectScanningTarget.pdf,主要是用来辅助扫描的。好了,接下来就是扫描三维物体。将瓶

  4. ruby-on-rails - 在 heroku 的 .fonts 文件夹中包含自定义字体,似乎无法识别它们 - 2

    Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在

  5. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  6. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  7. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  8. ruby-on-rails - 没有这样的文件或目录 - 用 Mini Magick 识别 - 2

    在我让另一个人重做我的前端UI之前,我的Rails应用程序运行平稳。我已经尝试解决此错误3天了。这是错误:Nosuchfileordirectory-identifyExtractedsource(aroundline#59):575859606162@post=Post.find(params[:id])authorize@postif@post.update_attributes(post_params)flash[:notice]="Postwasupdated."redirect_to[@topic,@post]else{"utf8"=>"✓","_method"=>"patc

  9. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

  10. ruby-on-rails - Rails 3.2 防止使用错误保存对象 - 2

    我有一个ActiveRecord对象,我想在不对模型进行永久验证的情况下阻止它被保存。您过去可以使用errors.add执行类似的操作,但它看起来不再有效了。user=User.lastuser.errors.add:name,"namedoesn'trhymewithorange"user.valid?#=>trueuser.save#=>true或user=User.lastuser.errors.add:base,"myuniqueerror"user.valid?#=>trueuser.save#=>true如何在不修改用户对象模型的情况下防止将用户对象保存在Rails3.2中

随机推荐