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尘埃4 分钟前
SpringBoot的数据访问
java·spring boot·后端
yang-23075 分钟前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
沉登c6 分钟前
幂等性接口实现
java·rpc
代码之光_198018 分钟前
SpringBoot校园资料分享平台:设计与实现
java·spring boot·后端
wjs20241 小时前
XSLT 实例:掌握 XML 转换的艺术
开发语言
萧鼎1 小时前
Python第三方库选择与使用陷阱避免
开发语言·python
安冬的码畜日常1 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
一颗星星辰1 小时前
C语言 | 第十章 | 函数 作用域
c语言·开发语言
lxp1997411 小时前
php函数积累
开发语言·php
科技资讯早知道1 小时前
java计算机毕设课设—坦克大战游戏
java·开发语言·游戏·毕业设计·课程设计·毕设