opencv人脸识别

需求:任意自拍照,生成证件照,有特定的检测接口

这里提供一点基础,人脸识别脸部区域,最大坐标借用了face++的抠图判断透明度获取,https://console.faceplusplus.com.cn/documents/40608240

public class TestOpencv {

    static {
        // 载入opencv的库
        /*String opencvpath = TestOpencv2.class.getResource("/opencv").getPath() + "/";
        String opencvDllName = opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll";
        System.out.println(opencvDllName);
        System.load(opencvDllName);*/

        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    private static final int orgWidth = 354;
    private static final int orgHeight = 472;

    /**
     * 将BufferedImage类型转换成Mat类型 
     *
     * @param bfImg
     * @param imgType bufferedImage的类型 如 BufferedImage.TYPE_3BYTE_BGR
     * @param matType 转换成mat的type 如 CvType.CV_8UC3
     * @return
     */
    public static Mat bufferedImage2Mat(BufferedImage bfImg, int imgType, int matType) {
        BufferedImage original = bfImg;
        int itype = imgType;
        int mtype = matType;

        if (original == null) {
            throw new IllegalArgumentException("original == null");
        }

        if (original.getType() != itype) {
            BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), itype);

            Graphics2D g = image.createGraphics();
            try {
                g.setComposite(AlphaComposite.Src);
                g.drawImage(original, 0, 0, null);
            } finally {
                g.dispose();
            }
        }
        byte[] pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData();
        Mat mat = Mat.eye(original.getHeight(), original.getWidth(), mtype);
        mat.put(0, 0, pixels);
        return mat;
    }

    public static BufferedImage mat2BufferedImage(Mat matrix) throws IOException {
        MatOfByte mob = new MatOfByte();
        Imgcodecs.imencode(".jpg", matrix, mob);
        return ImageIO.read(new ByteArrayInputStream(mob.toArray()));
    }


    /**
     * opencv实现人脸识别
     *
     * @param bufferedImage
     * @throws Exception
     */
    public static Map<String, Integer> detectFace(BufferedImage bufferedImage) throws Exception {

        System.out.println("Running DetectFace ... ");
        // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
        CascadeClassifier faceDetector = new CascadeClassifier(
                TestOpencv2.class.getResource("/opencv").getPath() + "/" + "haarcascade_frontalface_alt.xml");

        //Mat image = Imgcodecs.imread(imagePath);
        Mat image = bufferedImage2Mat(bufferedImage, BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);
        if (image.width() < orgWidth || image.height() < orgHeight) {
            throw new RuntimeException("人脸图像尺寸必须不小于" + orgWidth + "*" + orgHeight);
        }

        // 在图片中检测人脸
        MatOfRect faceDetections = new MatOfRect();

        //参数设置为scaleFactor=1.1f, minNeighbors=4, flags=0 以此来增加识别人脸的正确率
        //人脸识别的最大和最小像素范围minSize和maxSize
        faceDetector.detectMultiScale(image, faceDetections, 1.1f, 4, 0, new Size(120, 120));

        System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

        Rect[] rects = faceDetections.toArray();
        if (0 == rects.length) {
            throw new RuntimeException("人脸图像必须不小于120*120,无法识别人脸图像");
        }
        if (rects.length > 1) {
            throw new RuntimeException("超过一个脸");
        }
        // 在每一个识别出来的人脸周围画出一个方框
        Rect rect = rects[0];

        Imgproc.rectangle(image, new Point(rect.x, rect.y),
                new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(0, 255, 0));

        //Imgcodecs.imwrite(outFile, image);
        //System.out.println(String.format("人脸识别成功,人脸图片文件为: %s", outFile));
        Map<String, Integer> map = new HashMap<>();
        map.put("x", rect.x);
        map.put("y", rect.y);
        map.put("w", rect.width);
        map.put("h", rect.height);
        map.put("width", image.width());
        map.put("height", image.height());
        return map;
    }

    /**
     * 裁剪图片并重新装换大小
     *
     * @param bufferedImage
     * @param posX
     * @param posY
     * @param width
     * @param height
     */
    public static BufferedImage imageCut(BufferedImage bufferedImage, int posX, int posY, int width, int height) throws IOException {
        //原始图像
        Mat image = bufferedImage2Mat(bufferedImage, BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);//Imgcodecs.imread(imagePath);
        //截取的区域:参数,坐标X,坐标Y,截图宽度,截图长度
        Rect rect = new Rect(posX, posY, width, height);
        //两句效果一样
        Mat sub = image.submat(rect);   //Mat sub = new Mat(image,rect);
        Mat mat = new Mat();
        Size size = new Size(width, height);
        Imgproc.resize(sub, mat, size,1);//将人脸进行截图并保存
        return mat2BufferedImage(mat);
        //Imgcodecs.imwrite(outFile, mat);
        //System.out.println(String.format("图片裁切成功,裁切后图片文件为: %s", outFile));
    }

public static void main(String[] args) throws Exception {
        String picNo = "2";
        BufferedImage buffImage1 = ImageIO.read(new FileInputStream("C:\\Users\\GC\\Desktop\\z" + picNo + ".jpg"));
        System.out.println("buffImage1:" + buffImage1.getWidth());
        //handleDpi(buffImage1,300,300);
        Map<String, Integer> map = detectFace(buffImage1);
        int rectX = map.get("x");
        int rectY = map.get("y");
        int rectWidth = map.get("w");
        int rectHeight = map.get("h");
        int oldWidht = map.get("width");
        int oldHeight = map.get("height");
        System.out.println(map);
        ImageIO.write(buffImage1, "jpg", new File("C:\\Users\\GC\\Desktop\\g"+picNo+".jpg"));
        System.exit(0);
}

}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值