java idea openCV 人脸照片裁剪

 

先上opencv 工具代码

package com.example.demo.util;

import org.apache.commons.io.FileUtils;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.MultipartConfigElement;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

/**
 * @Author wong
 * @MethodName
 * @Description //TODO 人脸裁剪
 * @Date 11:31 2021/3/16
 **/
@RestController
public class OpenCVController {

    @Value("classpath:haarcascade_frontalface_alt.xml")
    private Resource xml;

    @PostMapping("/face")
    public void FaceDetector(HttpServletResponse response,MultipartFile file) throws IOException {
        // D:\workspace-sts-3.9.2.RELEASE\OpenCV\src\main\resources
        // String opencvpath = System.getProperty("user.dir") +
        // "\\src\\main\\resources\\";
        // String opencvDllName = opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll";
        // System.load(opencvDllName);
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("人脸检测开始……");

        // 创建临时文件,因为boot打包后无法读取文件内的内容
        File targetXmlFile = new File("src/" + xml.getFilename() + "");
        FileUtils.copyInputStreamToFile(xml.getInputStream(), targetXmlFile);
        CascadeClassifier faceDetector = new CascadeClassifier(targetXmlFile.toString());
        if (faceDetector.empty()) {
            System.out.println("请引入文件……");
            return;
        }
        // 创建图片tempFile
        File tempFile = new File("src/" + file.getOriginalFilename() + "");
        FileUtils.copyInputStreamToFile(file.getInputStream(), tempFile);

        // 读取创建的图片tempFile
        Mat image = Imgcodecs.imread(tempFile.toString());
        MatOfRect faceDetections = new MatOfRect();
        // 进行人脸检测
        faceDetector.detectMultiScale(image, faceDetections);
        System.out.println(String.format("检测到人脸: %s", faceDetections.toArray().length));
        Integer i = 1;
        // 制图将图填充到image中
        for (Rect rect : faceDetections.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(tempFile.toString(), i+".jpg", rect.x, rect.y, rect.width, rect.height);// 进行图片裁剪
            i++;
        }
        // 下面部分是返回给页面
        String filename = file.getOriginalFilename();
        Imgcodecs.imwrite(filename, image);
        File imgFile = new File(filename);
        if (imgFile.exists()) {
            response.getOutputStream().write(toByteArray(imgFile));
            response.getOutputStream().close();
        }

        // 删除临时文件
        if (targetXmlFile.exists() && targetXmlFile.isFile()) {
            if (targetXmlFile.delete()) {
                System.out.println("删除临时文件" + targetXmlFile + "成功!");
            }
        }
        if (imgFile.exists() && imgFile.isFile()) {
            if (imgFile.delete()) {
                System.out.println("删除临时文件" + imgFile + "成功!");
            }
        }
        if (tempFile.exists() && tempFile.isFile()) {
            if (tempFile.delete()) {
                System.out.println("删除临时文件" + tempFile + "成功!");
            }
        }
    }

    public static void imageCut(String imagePath, String outFile, int posX, int posY, int width, int height) {
        // 原始图像
        Mat image = 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);// 将人脸进行截图并保存
        Imgcodecs.imwrite(outFile, mat);
        System.out.println(String.format("图片裁切成功,裁切后图片文件为: %s", outFile));

    }

    public static byte[] toByteArray(File file) throws IOException {
        File f = file;
        if (!f.exists()) {
            throw new FileNotFoundException("file not exists");
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(f));
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
    }

//    /**
//     * 设置文件上传大小
//     * @return
//     */
//    @Bean
//    public MultipartConfigElement multipartConfigElement() {
//        MultipartConfigFactory factory = new MultipartConfigFactory();
//        //单个文件最大
//        factory.setMaxFileSize(DataSize.ofMegabytes(5)); //MB
//        //factory.setMaxFileSize(DataSize.ofKilobytes(80)); //KB
//        //factory.setMaxFileSize(DataSize.ofGigabytes(80)); //Gb
//        /// 设置总上传数据总大小
//        factory.setMaxRequestSize(DataSize.ofMegabytes(50));
//        return factory.createMultipartConfig();
//    }

}

 

第一步: 下载opencv 的jar包 ,根据自己的环境下载,我的是Windows 环境的

https://opencv.org/releases/

 

 

 

下载完成后,点击 exe 安装 ,自己配置路径安装就好了

 

 

 

安装完毕后就可以导入jar包了  我这里是演示的是 idea

首先打开 项目配置管理

 

添加jar 包

 

 

 找到自己安装opencv 文件夹里的java jar包 进行添加

 

 

 添加后在列表会有显示

 

 

 

 然后配置自己的vm启动路径

路径格式 :                -Djava.library.path=D:\openCV\opencv\build\java\x64;D:\openCV\opencv\build\java\x64

 

 

 

这时候启动 会报错, 因为没有 haarcascade_frontalface_alt.xml文件

 

 找到opencv 安装 路径下的这个文件就行了 

 

 

 粘贴到项目中

 

 有些老铁还是报错, 那就看下target  calsses包有这个文件没有,有时候是编译问题

 

 

直接 clean 再 build 下就行了

 

 

到这里就配置完成  接下来测试一下 debug启动项目 后 postman 进行测试

 

测试结果

 

 

看下裁剪后的照片 , 在本项目的根目录

 

 

 有些会遇到图片文件 过大的问题

两种解决方法

第一种是 使用 bean 配置  MultipartFile 的文件大小

 

 

 第二种是 在配置文件中配置

#配置文件传输
spring.servlet.multipart.enabled=true
#单个数据的大小
spring.servlet.multipart.max-file-size=20MB
#总数据的大小
spring.servlet.multipart.max-request-size=100MB

 

posted @ 2021-03-16 14:31  database-  阅读(793)  评论(0编辑  收藏  举报