java使用opencv框架实现人脸捕捉

公司最近开发一款定制化的人脸识别小程序,我也是第一次用分享在这里,分享给大家:

下面这段是实现人脸捕捉的关键代码:

    public static String openCapture() {
        String responseResult = null;
        try {
            // 加载本地的OpenCV库,这样就可以用它来调用Java API
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

            // 读取视频文件
            VideoCapture capture = new VideoCapture(0);
            int height = (int) capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
            int width = (int) capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
            if (height == 0 || width == 0) {
                throw new Exception("camera not found!");
            }

            JFrame frame = new JFrame("camera");
            frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            FaceCollection panel = new FaceCollection();
            frame.setContentPane(panel);
            frame.setVisible(true);
            frame.setSize(width + frame.getInsets().left + frame.getInsets().right,
                    height + frame.getInsets().top + frame.getInsets().bottom);

            Mat capImg = new Mat();
            Mat temp = new Mat();
            while (frame.isShowing()) {
                capture.read(capImg);
                // 图像灰度化
                Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_BGRA2BGR);// 彩色COLOR_BGRA2BGR 灰色COLOR_RGB2GRAY
                // 捕捉人脸
                FaceDetectDto faceDetectDto = panel.detectFace(capImg);
                // 图像显示
                panel.setmImg(panel.mat2BI(faceDetectDto.getMat()));
                // 清除重绘
                panel.repaint();
                // 捕捉到人脸退出捕捉
                if (faceDetectDto.isFaceFlag()) {
                    break;
                }
            }

            // 写入本地文件
            String fileName = ConfigUtil.getPropValue("path") + DateUtils.getDate("yyyyMMdd") + System.currentTimeMillis() + ".jpg";
            File file = new File(fileName);
            if (!file.getParentFile().exists()) {
                boolean result = file.getParentFile().mkdirs();
                if (!result) {
                    System.out.println("创建下载文件路径失败!");
                }
            }
            Imgcodecs.imwrite(fileName, temp);
            
            MatOfByte mob = new MatOfByte();//Mat类型转换为二进制数组
            Imgcodecs.imencode(".jpg", temp, mob);//这里可以指定  图片的格式
            byte[] byteArray = mob.toArray();
             //这里使用了base64,很多第三方的人脸识别的接口都用的Base64处理后的
            String encode = Base64Util.encode(byteArray); 
            //这里的敏感信息我就处理掉了
            String userInfo = getUserInfo(encode, "敏感信息", "敏感信息", 1, 80);
            //后面是一些业务处理逻辑
            Map result = (Map) JSON.parse(userInfo);
            Map map=new HashMap();
            String userInfoList = String.valueOf(result.get("userInfoList"));
            if (!userInfoList.equals("[]")) {
                Map partonInfo= (Map) JSON.parseArray(userInfoList).get(0);
                BigDecimal scope = (BigDecimal) partonInfo.get("scope");
                if (scope.doubleValue()<80.00){
                    responseResult=JSON.toJSONString(ResponseUtil.responseFail(0,"未查询到此人,请确认"));
                }else{
                    map.put("partonNum",partonInfo.get("partonNum"));
                    map.put("type", ThreeBackTypesEnum.BARCODE_ID.getCode());
                    responseResult = JSON.toJSONString(ResponseUtil.responseSuccess(0, "操作成功",map));
                }
            }

            Thread.sleep(1000 * 2); // 睡眠2秒

            // 关闭视频文件
            capture.release();
            frame.dispose();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseResult;
    }

下面这段是实现人脸识别捕捉的代码

 	/**
     * opencv实现人脸识别
     *
     * @param img
     */
    public FaceDetectDto detectFace(Mat img) throws Exception {
        FaceDetectDto faceDetectDto = new FaceDetectDto();
        // String pathName = getHaarcascade();
        // 人脸特征分类
        String faceXml = StringUtils.join("config/", "haarcascade_frontalface_alt.xml");
        // 眼睛特征分类
        String eyeXml = StringUtils.join("config/", "haarcascade_eye.xml");
        // 嘴巴特征分类
        // String mouthXml = StringUtils.join("config/", "haarcascade_mcs_mouth.xml");

        // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器
        CascadeClassifier faceDetector = new CascadeClassifier(faceXml);
        CascadeClassifier eyeDetector = new CascadeClassifier(eyeXml);
        // 在图片中检测人脸
        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(img, faceDetections);
        Rect[] faceRects = faceDetections.toArray();
        // 只需要捕捉一张人脸
        if (faceRects != null && faceRects.length == 1) {
            Rect faceRect = faceRects[0];
            // 绘制矩形
            Imgproc.rectangle(img, new Point(faceRect.x, faceRect.y),
                    new Point(faceRect.x + faceRect.width, faceRect.y + faceRect.height),
                    new Scalar(0, 0, 255), 2);
            //绘制圆形。
            //Imgproc.ellipse(frame, center, Size( faces[i].width/2, faces[i].height/2 ), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
            // 保证人脸头像大小
            if (faceRect.width > 260 && faceRect.height > 260) {
                // Mat face = new Mat(img, new Range(rect.y, rect.y + rect.height), new Range(rect.x, rect.x + rect.width));
                Mat faceMat = new Mat(img, faceRect);
                // 在图片中检测眼睛
                MatOfRect eyeDetections = new MatOfRect();
                eyeDetector.detectMultiScale(faceMat, eyeDetections);
                Rect[] eyeRects = eyeDetections.toArray();
                if (null != eyeRects && eyeRects.length >= 2) {
                    for (Rect eyeRect : eyeRects) {
                        // 需要加上人脸框的坐标
                        Imgproc.rectangle(img, new Point(faceRect.x + eyeRect.x, faceRect.y + eyeRect.y),
                                new Point(faceRect.x + eyeRect.x + eyeRect.width, faceRect.y + eyeRect.y + eyeRect.height),
                                new Scalar(0, 0, 255), 2);
                    }
                    faceDetectDto.setFaceFlag(true);
                }
            }
        }
//        else {
//            System.out.println("未检测到人脸或超过一张人脸!!!");
//        }
        faceDetectDto.setMat(img);
        return faceDetectDto;
    }

为了代码的完整性我将调用三方得到的信息的代码也放上来了,你可以根据自己的业务需求,进行更改。

  /**
     * 调用三方的到信息
     *
     * @return
     */
    public static String getUserInfo(String image, String dbid, String deviceid, Integer user_top_num, Integer score) throws IOException {
        String address = ConfigUtil.getPropValue("address");
        String post = HttpUtil.readContentFromPost(address, image);
        System.out.println(post);
        return post;
    }

图像显示

	private BufferedImage mImg;

    public BufferedImage getmImg() {
        return mImg;
    }

    public void setmImg(BufferedImage mImg) {
        this.mImg = mImg;
    }

public BufferedImage mat2BI(Mat mat) {
        int dataSize = mat.cols() * mat.rows() * (int) mat.elemSize();
        byte[] data = new byte[dataSize];
        mat.get(0, 0, data);
        int type = mat.channels() == 1 ?
                BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_3BYTE_BGR;

        if (type == BufferedImage.TYPE_3BYTE_BGR) {
            for (int i = 0; i < dataSize; i += 3) {
                byte blue = data[i + 0];
                data[i + 0] = data[i + 2];
                data[i + 2] = blue;
            }
        }
        BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type);
        image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data);

        return image;
    }

	public void paintComponent(Graphics g) {
        if (mImg != null) {
            g.drawImage(mImg, 0, 0, mImg.getWidth(), mImg.getHeight(), this);
        }
    }

还有一些配置文件:
大家上网搜一下即可,太长了,就不放上来了。
在这里插入图片描述

你可能感兴趣的:(opencv)