Java项目中使用OpenCV检测人脸的应用

Java项目中使用OpenCV检测人脸的应用

一、准备工作

将下载好的opencv的jar包放在项目的根目录下,可以新建一个lib的文件夹,将其放在此处;

在pom文件中引入:

xml 复制代码
    <profiles>
	<!-- 生产环境 -->
        <profile>
            <id>pro</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <profiles.active>pro</profiles.active>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>org.opencv</groupId>
                    <artifactId>opencv</artifactId>
                    <version>480</version>
                    <scope>system</scope>
                    <systemPath>${project.basedir}/lib/opencv-480.jar</systemPath>
                </dependency>
            </dependencies>
        </profile>
    </profiles>

二、编写人脸库初始化

以下是基于Windows环境,Linux环境中同理

在你的application-dev.properties文件中配置好opencv的文件地址:

############################################################################################################################################

openCV配置

############################################################################################################################################

opencv.lib.path=C:/OpenCV/opencv/build/java/x64/opencv_java480.dll

opencv.face.detector.path=C:/OpenCV/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml

基础配置属性注入,新建一个config文件夹存放SimpFaceProperties类:

java 复制代码
@Getter
@Configuration
public class SimpFaceProperties {

    /**
     * opencv库绝对路径
     */
    @Value("${opencv.lib.path:}")
    private String openCvLibPath;

    /**
     * opencv模型数据
     */
    @Value("${opencv.face.detector.path:}")
    private String openCvFaceXml;
}

可以在你的项目中新建一个专门存放人脸相关服务的模块module,如init文件夹下中的:

java 复制代码
@Slf4j
@Component("InitLoadLib")
@SuppressWarnings("all")
public class InitLoadLib {

    /**
     * 是否加载库
     */
    private static boolean IS_LIB_OPEN = false;

    private static CascadeClassifier faceDetector;

    @Resource
    private SimpFaceProperties simpFaceProperties;

    /**
     * 项目初始化完成后加载lib库
     */
    @PostConstruct
    public void init() {
        if (StringUtils.isBlank(simpFaceProperties.getOpenCvLibPath())) {
            log.error("---> init opencv 库未配置");
            return;
        }
        boolean isAbsolutePath = simpFaceProperties.getOpenCvLibPath().contains("/") || simpFaceProperties.getOpenCvLibPath().contains("\\");
        // 判断是不是填写的绝对路径
        if (isAbsolutePath && !FileUtil.exist(simpFaceProperties.getOpenCvLibPath())) {
            log.error("---> init opencv 库不存在:{}", simpFaceProperties.getOpenCvLibPath());
            return;
        }
        try {
            // 获取系统类型
            String os = System.getProperty("os.name").toLowerCase();
            // 判断是不是windows
            if (os.contains("windows")) {
                log.info("---> init opencv Windows系统");
                if (isAbsolutePath) {
                    System.load(simpFaceProperties.getOpenCvLibPath());
                } else {
                    System.loadLibrary(simpFaceProperties.getOpenCvLibPath());
                }
                IS_LIB_OPEN = true;
            } else if (os.contains("linux")) {
                log.info("---> init opencv Linux系统");
                if (isAbsolutePath) {
                    System.load(simpFaceProperties.getOpenCvLibPath());
                } else {
                    System.loadLibrary(simpFaceProperties.getOpenCvLibPath());
                }
                IS_LIB_OPEN = true;
            } else {
                log.error("---> init opencv 不支持该系统");
            }
            if (IS_LIB_OPEN) {
                faceDetector = new CascadeClassifier(simpFaceProperties.getOpenCvFaceXml());
            }
        } catch (Exception e) {
            log.error("---> init opencv 库加载失败:{}", e.getMessage());
            IS_LIB_OPEN = false;
        }
    }

    public static boolean isOpenCvLib() {
        return IS_LIB_OPEN;
    }

    public static CascadeClassifier getFaceDetector() {
        return faceDetector;
    }
}

三、编写人脸服务接口业务

控制层中的接口代码:

java 复制代码
/**
* 人脸检测
* @param file 文件
* @throws IOException 异常
*/
@PostMapping("faceDetection")
public Object faceDetection(MultipartFile file) throws IOException {
    int rlsl = simpFaceService.faceDetection(file);
    Map<String, Object> resMap = new HashMap<>();
    resMap.put("rlsl", rlsl);
    return resMap;
}

新建一个service文件夹,存放SimpFaceService接口服务类:

java 复制代码
public interface SimpFaceService {

    /**
     * 检测图片上人脸数量
     * @param file 文件(支持MultipartFile, InputStream, URL(网络文件地址),String(本地文件地址))
     * @return 人脸数量
     * @throws IOException 异常
     */
    int faceDetection(Object file) throws IOException;
}

该接口服务的实现类:

java 复制代码
@Service
public class SimpFaceServiceImpl implements SimpFaceService {

    @Resource
    private SimpFaceProperties simpFaceProperties;

    /**
     * 检测图片上人脸数量
     * @param file 文件(支持MultipartFile, InputStream, URL(网络文件地址),String(本地文件地址))
     * @return 人脸数量
     * @throws IOException 异常
     */
    @Override
    public int faceDetection(Object file) throws IOException {
        if (!InitLoadLib.isOpenCvLib()) {
            return 0;
        }
        // 文件转byte数组
        byte[] byteArray = this.fileToBytes(file);
        // 读取图片
        Mat mat = Imgcodecs.imdecode(new MatOfByte(byteArray), Imgcodecs.IMREAD_UNCHANGED);
        // 目标灰色图像
        Mat dstGrayImg = new Mat();
        // 转换灰色
        Imgproc.cvtColor(mat, dstGrayImg, Imgproc.COLOR_BGR2GRAY);
        // 检测脸部
        MatOfRect face = new MatOfRect();
        // 检测图像中的人脸
        InitLoadLib.getFaceDetector().detectMultiScale(dstGrayImg, face);
        return face.rows();
    }

    private byte[] fileToBytes(Object file) throws IOException {
        if (file instanceof MultipartFile) {
            return IoUtil.readBytes(((MultipartFile) file).getInputStream());
        }
        if (file instanceof URL) {
            return HttpUtil.downloadBytes(((URL) file).getPath());
        }
        if (file instanceof InputStream) {
            return IoUtil.readBytes((InputStream) file);
        }
        if (file instanceof String) {
            return FileUtil.readBytes((String) file);
        }
        return null;
    }
}
相关推荐
A了LONE7 分钟前
h5的底部导航栏模板
java·前端·javascript
专注VB编程开发20年9 分钟前
各版本操作系统对.NET支持情况(250707更新)
开发语言·前端·ide·vscode·.net
我喜欢就喜欢17 分钟前
RapidFuzz-CPP:高效字符串相似度计算的C++利器
开发语言·c++
莫彩20 分钟前
【Modern C++ Part7】_创建对象时使用()和{}的区别
开发语言·c++
经典199224 分钟前
spring boot 详解以及原理
java·spring boot·后端
星光542225 分钟前
飞算JavaAI:给Java开发装上“智能引擎”的超级助手
java·开发语言
June bug1 小时前
【Python基础】变量、运算与内存管理全解析
开发语言·python·职场和发展·测试
醇醛酸醚酮酯1 小时前
Qt项目锻炼——TODO(五)
开发语言·qt
学习3人组1 小时前
JVM GC长暂停问题排查
java
R_AirMan1 小时前
深入浅出Redis:一文掌握Redis底层数据结构与实现原理
java·数据结构·数据库·redis