Java借助OpenCV实现人脸识别登录完整示例

本文详细介绍了如何使用Java和OpenCV进行人脸识别,包括OpenCV的下载安装、基本使用、项目集成、Spring Boot集成步骤,以及在集成过程中可能遇到的异常处理。通过创建接口、配置应用和自定义窗口,实现人脸识别登录的功能。
摘要由CSDN通过智能技术生成

OpenCV

效果预览

在这里插入图片描述

概述

OpenCV(开源计算机视觉库)是在BSD(开源协议)许可下发布的。它是一个高度优化的库,专注于实时应用程序。它具有C ++,Python和Java接口,支持Windows,Linux,Mac OS,iOS和Android。

下载与安装

下载地址:https://opencv.org/releases/

在这里插入图片描述

下载到本地后,双击进行安装即可

在这里插入图片描述

目录说明

安装目录如下

在这里插入图片描述

build :基于window构建

sources:开源,提供源码

build目录说明

在这里插入图片描述

这里是Java开发关注java目录即可

在这里插入图片描述

x64与x86代表给不同的系统使用

opencv-460.jar给java操作openvc的程序包

由于是64位系统,所以关注x64目录

在这里插入图片描述

DLL(Dynamic Link Library)文件为动态链接库文件,又称“应用程序拓展”,是软件文件类型。DLL文件,放置于系统中。当执行某一个程序时,相应的DLL文件就会被调用

OpenCV的基本使用

官网文档地址:https://docs.opencv.org/4.6.0/df/d65/tutorial_table_of_content_introduction.html

中文文档:http://wiki.opencv.org.cn/index.php

教程参考:https://www.w3cschool.cn/opencv/

教程参考:https://www.yiibai.com/opencv/opencv_adding_text.html

项目集成

方式1:

这里使用IDEA进行开发,导入opencv-460.jar库

使用快捷键 Ctrl+Shift+Alt+S打开
在这里插入图片描述
选择库项,导入Java库。
在这里插入图片描述
在这里插入图片描述

方式2:

除了上述方式,还可以将opencv-460.jar安装到本地仓库或私有仓库,然后在pom.xml中引入依赖。

在项目根目录创建lib目录,将上述提及的opencv-460.jaropencv_java460.dll放到该目录

在这里插入图片描述
pom.xml文件中,通过坐标的形式引入

        <!-- 加载lib目录下的opencv包 -->
        <dependency>
            <groupId>org.opencv</groupId>
            <artifactId>opencv</artifactId>
            <version>4.6.0</version>
            <scope>system</scope>
            <systemPath>${
   basedir}/lib/opencv-460.jar</systemPath>
        </dependency>

图片人脸检测

    public static void main(String[] args) {
   
        imageFaceDetection();
    }


    /**
     * 图片人脸检测
     */
    public static void imageFaceDetection() {
   
        // 加载OpenCV本地库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,文件位于opencv安装目录中
        CascadeClassifier faceDetector = new CascadeClassifier("D:\\Development\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
        // 读取测试图片
        String imgPath = "D:\\user\\test.png";
        Mat image = Imgcodecs.imread(imgPath);
        if (image.empty()) {
   
            throw new RuntimeException("图片内存为空");
        }

        // 检测脸部
        MatOfRect face = new MatOfRect();
        // 检测图像中的人脸
        faceDetector.detectMultiScale(image, face);
        // 匹配Rect矩阵
        Rect[] rects = face.toArray();
        System.out.println("识别人脸个数: " + rects.length);
        
        // 识别图片中的所以人脸并分别保存
        int i = 1;
        for (Rect rect : face.toArray()) {
   
            Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0), 3);
            // 进行图片裁剪
            imageCut(imgPath, "D:\\user\\" + i + ".jpg", rect.x, rect.y, rect.width, rect.height);
            i++;
        }
        // 图片中人脸画框保存到本地
        Imgcodecs.imwrite("D:\\user\\test1.png", image);

        // 展示图片
        HighGui.imshow("人脸识别", image);
        HighGui.waitKey(0);
    }

    /**
     * 裁剪人脸
     *
     * @param readPath 读取文件路径
     * @param outPath  写出文件路径
     * @param x        坐标X
     * @param y        坐标Y
     * @param width    截图宽度
     * @param height   截图长度
     */
    public static void imageCut(String readPath, String outPath, int x, int y, int width, int height) {
   
        // 原始图像
        Mat image = Imgcodecs.imread(readPath);
        // 截取的区域
        Rect rect = new Rect(x, y, width, height);
        // Mat sub = new Mat(image,rect);
        Mat sub = image.submat(rect);
        Mat mat = new Mat();
        Size size = new Size(width, height);
        // 人脸进行截图并保存
        Imgproc.resize(sub, mat, size);
        Imgcodecs.imwrite(outPath, mat);
    }

在这里插入图片描述

人脸对比相似度

对比1.jpg与1-1.jpg

对比1.jpg与3.jpg

在这里插入图片描述

    // 初始化人脸探测器
    static CascadeClassifier faceDetector;

    static {
   
        // 加载OpenCV本地库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,文件位于opencv安装目录中
        faceDetector = new CascadeClassifier("D:\\Development\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
    }
    
    public static void main(String[] args) {
   
        double comparison = faceRecognitionComparison("D:\\user\\1.jpg", "D:\\user\\1-1.jpg");
        System.out.println("对比结果:" + comparison);
        if (comparison > 0.85) {
   
            System.out.println("人脸匹配成功");
        } else {
   
            System.out.println("人脸不匹配识别");
        }

        double comparison2 = faceRecognitionComparison("D:\\user\\1.jpg", "D:\\user\\3.jpg");
        System.out.println("对比结果:" + comparison2);
        if (comparison2 > 0.85) {
   
            System.out.println("人脸匹配成功");
        } else {
   
            System.out.println("人脸不匹配识别");
        }
        // 终止当前运行的 Java 虚拟机。
        System.exit(0);
    }


    /**
     * 人脸识别比对
     */
    public static double faceRecognitionComparison(String image1, String image2) {
   
        Mat mat1 = conv_Mat(image1);
        Mat mat2 = conv_Mat(image2);
        Mat mat3 = new Mat();
        Mat mat4 = new Mat();
        // 颜色范围
        MatOfFloat ranges = new MatOfFloat(0f, 256f);
        // 直方图大小, 越大匹配越精确 (越慢)
        MatOfInt histSize = new MatOfInt(1000);

        Imgproc.calcHist(Arrays.asList(mat1), new MatOfInt(0), new Mat(), mat3, histSize, ranges);
        Imgproc.calcHist(Arrays.asList(mat2), new MatOfInt(0), new Mat(), mat4, histSize, ranges);

        // 比较两个密集或两个稀疏直方图
        return Imgproc.compareHist(mat3, mat4, Imgproc.CV_COMP_CORREL);
    }

    /**
     * 灰度化人脸
     */
    public static Mat conv_Mat(String img) {
   
        // 读取图像
        Mat mat1 = Imgcodecs.imread(img);
        Mat mat2 = new Mat();
        // 灰度化:将图像从一种颜色空间转换为另一种颜色空间
        Imgproc.cvtColor(mat1, mat2, Imgproc.COLOR_BGR2GRAY);
        // 探测人脸:检测到的对象作为矩形列表返回
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(mat1, faceDetections);
        // rect中人脸图片的范围
        for (Rect rect : faceDetections.toArray()) {
   
            Mat face = new Mat(mat1, rect);
            return face;
        }
        return null;
    }

对比结果如下

对比结果:1.0
人脸匹配成功
对比结果:0.2501351968792374
人脸不匹配识别

识别视频中的人脸

    // 初始化人脸探测器
    static CascadeClassifier faceDetector;

    static {
   
        // 加载OpenCV本地库
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,文件位于opencv安装目录中
        faceDetector = new CascadeClassifier("D:\\Development\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
    }

    public static void main(String[] args) {
   
        videoFaceRecognition();
        // 终止当前运行的 Java 虚拟机。
        System.exit(0);
    }

    /**
     * 从视频中识别人脸
     */
    public static void videoFaceRecognition() {
   
        // 读取视频文件
        VideoCapture capture = new VideoCapture();
        capture.open("D:\\user\\test.mp4");
        if (!capture.isOpened()) {
   
            throw new RuntimeException("读取视频文件失败");
        }

        Mat video = new Mat();
        int index = 0;
        while (capture.isOpened()) {
   
            // 抓取、解码并返回下一个视频帧写入Mat对象中
            capture.read(video);
            // 显示从视频中识别的人脸图像
            HighGui.imshow("视频识别人脸", getFace(video));
            // 获取键盘输入
            index = HighGui.waitKey(100);
            // 如果是 Esc 则退出
            if (index == 27) {
   
                capture.release();
                return;
            }
        }
    }

    /**
     * 从视频帧中识别人脸
     *
     * @param image 待处理Mat图片,即视频中的某一帧
     * @return 处理后的图片
     */
    public static 
Java OpenCV 人脸识别考勤是一种利用Java语言和OpenCV库进行人脸识别的考勤系统。 首先,我们需要在Java中配置OpenCV库并加载相应的依赖。OpenCV库提供了很多用于人脸识别的功能和算法,如人脸检测、人脸特征提取等。 其次,我们需要采集员工的人脸图像作为模型数据。可以使用摄像头或从已有的照片中获取人脸图像。对于每个员工,我们可以将其人脸图像与其对应的ID进行关联,并将其存储在数据库或文件中。 接下来,我们可以使用OpenCV的人脸检测算法对新采集到的人脸图像进行检测。这一步可以通过调用OpenCV库中的人脸检测函数实现。一旦检测到人脸,我们可以通过人脸识别算法提取人脸图像的特征,如提取的特征向量。 在考勤过程中,我们可以使用摄像头从员工的每张人脸图像中提取特征,并与模型数据中存储的员工人脸特征进行比对。通过比对,我们可以确定这张人脸图像是否属于已注册的员工。 最后,我们可以根据比对结果判断员工是否已打卡。如果识别到的人脸与已注册员工的人脸匹配成功,则记录员工的出勤时间等信息。否则,说明该人脸不属于已注册的员工,可以进行相应的处理。例如,可以拒绝进入或记录异常情况等。 总之,Java OpenCV 人脸识别考勤系统可以帮助企业实现面部识别考勤功能,提高考勤的准确性和效率。
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeDevMaster

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值