下面是一个简单的Java人脸识别程序,使用OpenCV和JavaCV库。请确保你已经安装了这些库,并且将相应的 .jar 文件添加到你的项目中。

在生成的 pom.xml 文件中,添加以下依赖项:

<!-- Add OpenCV dependency -->
<dependency>
    <groupId>org.openpnp</groupId>
    <artifactId>opencv</artifactId>
    <version>4.5.3-1</version>
</dependency>

<!-- Add JavaCV dependency -->
<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv</artifactId>
    <version>1.5.5</version>
</dependency>

在 src/main/java/com/example/ 目录下创建 FaceRecognitionApp .java 文件,并将以下代码添加到该文件:

import org.bytedeco.opencv.opencv_core.*;
import org.bytedeco.opencv.opencv_objdetect.CascadeClassifier;
import org.bytedeco.opencv.opencv_face.Face;
import org.bytedeco.opencv.opencv_face.FaceRecognizer;
import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.global.opencv_imgcodecs;
import org.bytedeco.opencv.global.opencv_imgproc;
import org.bytedeco.opencv.global.opencv_objdetect;
import org.bytedeco.javacpp.indexer.FloatIndexer;
import org.bytedeco.javacv.*;

import javax.swing.*;

/**
 * 一个简单的人脸识别示例
 */
public class FaceRecognitionApp {

    public static void main(String[] args) {
        // 初始化摄像头
        OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
        try {
            grabber.start();

            // 加载人脸检测器
            CascadeClassifier faceDetector = new CascadeClassifier();
            faceDetector.load("haarcascade_frontalface_default.xml");

            // 存储训练图像和标签的向量
            MatVector images = new MatVector();
            Mat labels = new Mat();

            // 添加训练数据(替换为实际路径)
            addTrainingData("path_to_person1", 1, images, labels);
            addTrainingData("path_to_person2", 2, images, labels);

            // 创建人脸识别器
            FaceRecognizer faceRecognizer = Face.createLBPHFaceRecognizer();
            faceRecognizer.setThreshold(40.0);  // 调整阈值

            // 训练模型
            faceRecognizer.train(images, labels);

            // 创建窗口
            CanvasFrame canvasFrame = new CanvasFrame("Face Recognition", CanvasFrame.getDefaultGamma() / grabber.getGamma());

            while (true) {
                // 读取摄像头图像
                Frame frame = grabber.grab();
                Mat image = converterToMat(frame);

                // 转换为灰度图像
                Mat grayImage = new Mat();
                opencv_imgproc.cvtColor(image, grayImage, opencv_imgproc.COLOR_BGR2GRAY);

                // 在图像中检测人脸
                RectVector faces = new RectVector();
                faceDetector.detectMultiScale(grayImage, faces);

                for (int i = 0; i < faces.size(); i++) {
                    Rect face = faces.get(i);
                    Mat faceROI = grayImage.apply(face);

                    // 进行人脸识别
                    int[] label = new int[1];
                    double[] confidence = new double[1];
                    faceRecognizer.predict(faceROI, label, confidence);

                    // 如果置信度较高,认为识别成功
                    if (confidence[0] < 40) {
                        System.out.println("Person " + label[0]);
                    }

                    // 在人脸周围画矩形框
                    rectangle(image, face, Scalar.RED, 2, 8, 0);
                }

                // 显示图像
                canvasFrame.showImage(converterToFrame(image));

                // 按'q'键退出
                if (canvasFrame.isResizable() && canvasFrame.isVisible() && canvasFrame.waitKey(30) == 113) {
                    break;
                }
            }

            canvasFrame.dispose();
            grabber.stop();
        } catch (FrameGrabber.Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加训练数据
     *
     * @param path   训练图像的路径
     * @param label  图像对应的标签
     * @param images 存储图像的向量
     * @param labels 存储标签的矩阵
     */
    private static void addTrainingData(String path, int label, MatVector images, Mat labels) {
        // 读取图像
        Mat img = opencv_imgcodecs.imread(path);

        // 转换为灰度图像
        Mat grayImg = new Mat();
        opencv_imgproc.cvtColor(img, grayImg, opencv_imgproc.COLOR_BGR2GRAY);

        // 添加到训练集
        images.push_back(grayImg);
        labels.push_back(new Mat(1, 1, opencv_core.CV_32SC1, new int[]{label}));
    }

    /**
     * 将 Frame 转换为 Mat
     *
     * @param frame 待转换的 Frame 对象
     * @return 转换后的 Mat 对象
     */
    private static Mat converterToMat(Frame frame) {
        OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
        return converter.convert(frame);
    }

    /**
     * 将 Mat 转换为 Frame
     *
     * @param mat 待转换的 Mat 对象
     * @return 转换后的 Frame 对象
     */
    private static Frame converterToFrame(Mat mat) {
        OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
        return converter.convert(mat);
    }
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐