Java基于OpenCV+Hog+SVM实现微笑检测

该博客介绍了如何在Java中结合OpenCV库和HOG特征以及支持向量机(SVM)来实现微笑检测。首先,详细讲解了如何配置Java的OpenCV开发环境,然后逐步阐述了训练过程,包括读取图片、数据分组、计算梯度、提取HOG特征、训练SVM模型以及评估结果。最后,讨论了预测阶段的相关内容。
摘要由CSDN通过智能技术生成

1、配置Java的OpenCV环境

参考
Java开发Opencv之(一)开发环境安装与配置

2.进行训练

1.读取所有的图

public static void getFace(String filePath) {
   
        System.out.println("读取人脸......");
        //人脸检测模型
        CascadeClassifier faceDetector = new CascadeClassifier("C:\\OpenCV\\opencv\\sources\\data\\lbpcascades\\lbpcascade_frontalface.xml");
        //定义人脸检测
        MatOfRect faceDetections = new MatOfRect();
        //获取图像所在的文件夹
        File file = new File(filePath);
        //遍历文件夹中的所有图片
        for (File f : file.listFiles()) {
   
            //读取图片
            Mat image = Imgcodecs.imread(f.getAbsolutePath());
            //对图像进行人脸检测
            faceDetector.detectMultiScale(image, faceDetections);
            //获取人脸区域
            Rect[] rects = faceDetections.toArray();

            //存在人脸
            if (faceDetections.toArray().length > 0) {
   
                //获得人脸区域
                for (Rect rect : rects) {
   
                    Mat mat = new Mat(rect.width, rect.width, CvType.CV_8UC3);
                    for (int i = rect.x; i < rect.x + rect.width; i++) {
   
                        for (int j = rect.y; j < rect.y + rect.height; j++) {
   
                            mat.put(j - rect.y, i - rect.x, image.get(j, i));
                        }
                    }
                    //截取人脸区域
                    Imgproc.resize(mat, mat, new Size(64, 64), 0, 0, 0);
                    //保存图像
                    Imgcodecs.imwrite("./genki4k/files1/" + f.getName(), mat);
                }
            }
        }
        System.out.println("读取人脸完毕");
    }

2.随机分组

public static void getRandomFile(String filePath) {
   
        System.out.println("图片随机分组......");
        File file = new File(filePath);
        File listFile[] = file.listFiles();
        Random random = new Random();
        //初始化标签
        //前2162为笑脸
        for (int i = 0; i < 3670; i++) {
   
            String no = listFile[i].getName().substring(4, 8);
            if (Integer.parseInt(no) <= 2162)
                flags[Integer.parseInt(no)] = 1;
            else
                flags[(Integer.parseInt(no))] = 0;
        }
        //随机排列,连同标签一起排列
        for (int i = 0; i < 3670; i++) {
   
            int r = random.nextInt(i + 1);
            File tmp = listFile[i];
            listFile[i] = listFile[r];
            listFile[r] = tmp;
            int t = flags[i];
            flags[i] = flags[r];
            flags[r] = t;
        }
        //分组
        for (int i = 0; i < 10; i++) {
   
            for (int j = 0; j < 367; j++) {
   
                randomFiles[i][j] = listFile[i * 367 + j];
            }
        }
        System.out.println("图片随机分组完毕");
    }

3.计算梯度值

public static Mat getGradient(Mat src) {
   
        Mat grayMat = new Mat();
        // 灰度
        Imgproc.cvtColor(src, grayMat, Imgproc.COLOR_BGR2GRAY, 0);
        //梯度计算
        Mat x = new Mat(); //X 方向梯度值矩阵
        Mat y = new Mat(); //Y 方向梯度值矩阵
        //计算 X,Y 方向绝对梯度
        Imgproc.Sobel(grayMat, x, -1, 1, 0, 3, 1, 0);
        Core.convertScaleAbs(x, x);
        Imgproc.Sobel(grayMat, y, -1, 0, 1, 3, 1, 0);
        Core.convertScaleAbs(y, y);
        //XY 综合梯度
        Core.addWeighted(x, 0.5, y, 0.5, 0, grayMat);

        return grayMat;
    }

4.提取Hog值

public static float[] getHOG(Mat src) {
   
        //灰度以及梯度处理
        src = getGradient(src);
        //图像缩放
        Imgproc.resize(src, src, new Size(64, 128), 0, 0, Imgproc.INTER_AREA);
        HOGDescriptor hogDescriptor = new HOGDescriptor();
        MatOfFloat descriptorsValues = new MatOfFloat();
        MatOfPoint locations = new MatOfPoint();
        //计算 Hog 特征值
        hogDescriptor.compute(src, descriptorsValues, new Size(0, 0), new Size(0, 0), locations);
        //特征值维数
        int size = (int) (descriptorsValues.total() * descriptorsValues.channels());
        float[] temp = new float[size];
        descriptorsValues.get(0, 0, temp);
        //特征数组
        float[] resArrays = descriptorsValues.toArray();
        return resArrays;
    }

5.训练模型

public static void train(int t) {
   
        System.out.println("开始训练第" + (t + 1) + "组");
        //定义 SVM 对象
        SVM svm = SVM.create();
        //训练数据 Hog 特征值
        Mat dataMat = new Mat();
        //标签数据
        Mat labelMat = new Mat();
        //SVM类型
        svm.setType(SVM.C_SVC);
        //线性
        svm.setKernel(SVM.LINEAR);
        //迭代终止条件
        svm.setTermCriteria(new TermCriteria(TermCriteria.MAX_ITER, 20000, 1e-6));

        //数据大小
        int size = inputArr[0].length;

        //创建数据和标签对象,训练九组
        dataMat.create(3303, size, CvType.CV_32FC1);
        labelMat.create(3303, 1, CvType.CV_32SC1);

        //加载数据以及标签
        for (int i = 0;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值