springboot集成opencv实现简单的人脸识别

前言 项目中检测人脸图片是否合法的功能,之前用的是百度的人脸识别接口,由于成本高昂不得不寻求替代方案, 什么是 opencv? OpenCV 是一个基于 BSD 许可(开源)发行的跨平台计算机视觉和机器学习软件库

本文包含相关资料包-----> 点击直达获取<-------

前言

项目中检测人脸图片是否合法的功能,之前用的是百度的人脸识别接口,由于成本高昂不得不寻求替代方案。

什么是 opencv?

OpenCV 是一个基于 BSD 许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在 Linux、Windows、Android 和 Mac OS 操作系统上。轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了 Python、Java、MATLAB 等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

项目集成步骤

由于项目是放在 Linux 系统中跑的,开发环境是 Windows10,所以项目中涉及到 opencv 的要分两套。

准备工作

Windows 安装 opencv

opencv 官网下载安装包 https://opencv.org/releases/ 我这里选择的是 4.1.1 版本 分别下载了 Windows 版本和源码

Windows 环境下集成

安装 opencv,没什么说的,指定一个路径安装即可,注意安装路径不能是中文。 项目中集成的 三个关键点

  • 引入 jar 依赖
  • 读取 OpenCV 自带的人脸识别特征 XML 文件
  • 配置 opencv 的库文件地址

关键点 1:引入 jar 包

jar 包位置在安装路径下的 Java 文件夹中 两种方式引入

方式一:idea 添加 jar

或者直接在 Libraries 中添加二者皆可。

方式二:将 jar 上传至私服,在 maven 中引入

我这里是将 jar 上传至私服,然后引用的。 注意 Windows 版的 jar 和 Linux 中的 jar 不一样,二者要区分开来 通过 Maven 配置在不同环境下加载不同的 jar

```xml dev

        <dependency>
        <!--                这里改成自己的仓库地址-->
            <groupId>com.***.cloud.resource</groupId>
            <artifactId>opencv-window</artifactId>
            <version>411</version>
        </dependency>
    </dependencies>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
</profile>
<profile>
    <id>test</id>
    <dependencies>
        <dependency>
        <!--                这里改成自己的仓库地址-->
            <groupId>com.***.cloud.resource</groupId>
            <artifactId>opencv-linux</artifactId>
            <version>411</version>
        </dependency>
    </dependencies>
</profile>

```

关键点 2:配置人脸识别特征 XML 文件的地址

在 bootstrap.yml 添加如下参数

```xml

函数库地址 在 vm optionis中 配置

windows地址: -Djava.library.path=D:\software\opencv\build\java\x64

linux地址: -Djava.library.path=/usr/local/opencv-4.1.1/build/lib/

opencv: lib: linuxxmlpath: /usr/local/share/opencv4/haarcascades/haarcascade_frontalface_alt.xml windowxmlpath: D:\software\opencv\sources\data\haarcascades\haarcascade_frontalface_alt.xml ```

测试的方法中就直接写死了

```java /* * 初始化人脸探测器 / static CascadeClassifier faceDetector;

static {
    String systemProperties = String.valueOf(System.getProperties());
    log.info(systemProperties);
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    faceDetector = new CascadeClassifier("D:\\software\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
}

```

注意路径!!

关键点 3:配置 opencv 的库文件地址

bash -Djava.library.path=D:\software\opencv\build\java\x64

这里其实指向的就是 该目录下的 opencv_java411.dll 文件 (Linux 的配置见下文)

代码

测试方法

```java package com.example.opencvdemo.test;

import lombok.extern.slf4j.Slf4j; import org.opencv.core.*; import org.opencv.highgui.HighGui; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.CascadeClassifier;

/ * @author aaron * @since 2021-06-07 */ @Slf4j public class FaceVideo { / * 初始化人脸探测器 */ static CascadeClassifier faceDetector;

static {
    String systemProperties = String.valueOf(System.getProperties());
    log.info(systemProperties);
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    faceDetector = new CascadeClassifier("D:\\software\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
}

public static void main(String[] args){
    // 3- 本地图片人脸识别,识别成功并保存人脸图片到本地
    String imgPath = "C:\\Users\\Administrator\\Pictures\\wang.jpg";
    face(imgPath);
}

/**
 * OpenCV-4.1.1 图片人脸识别
 *
 * @return: void
 * @date: 2019年5月7日12:16:55
 */
public static void face(String imgPath) {
    /**
     * 读取本地
     */
    Mat image = Imgcodecs.imread(imgPath);
    if (image.empty()) {
        System.out.println("image 内容不存在!");
        return;
    }
    // 3 特征匹配
    MatOfRect face = new MatOfRect();
    faceDetector.detectMultiScale(image, face);
    // 4 匹配 Rect 矩阵 数组
    Rect[] rects = face.toArray();
    System.out.println("匹配到 " + rects.length + " 个人脸");
    // 5 为每张识别到的人脸画一个圈
    int i = 1;
    for (Rect rect : face.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(imgPath, "D:\\pictures\\" + i + ".jpg", rect.x, rect.y, rect.width, rect.height);// 进行图片裁剪
        i++;
    }
    // 6 展示图片
    HighGui.imshow("人脸识别", image);
    HighGui.waitKey(0);
}
/**
 * 裁剪人脸
 *
 * @param imagePath
 * @param outFile
 * @param posX
 * @param posY
 * @param width
 * @param height
 */
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));

}

}

```

注意!Mat image = Imgcodecs.imread(imgPath); imgPath 中不能带有中文! opencv 安装路径中如果有中文的话就会报错。

集成到 SpringBoot

```java package com.example.opencvdemo.util;

import com.example.opencvdemo.exception.PublicException; import com.example.opencvdemo.result.ErrorCode; import com.google.common.primitives.Bytes; import lombok.extern.slf4j.Slf4j; import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.objdetect.CascadeClassifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component;

import java.io.*; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List;

/* * @author aaron * @since 2021-06-07 / @Component @Slf4j public class OpenCvUtils implements CommandLineRunner {

@Value("${opencv.lib.linuxxmlpath}")
private String linuxXmlPath;
@Value("${opencv.lib.windowxmlpath}")
private String windowXmlPath;

/**
 * 人脸探测器对象
 */
static CascadeClassifier faceDetector;

/**
 * 判断是否是Windows系统
 */
private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("win");

/**
 * 监测图片是否合法,是否只有一张脸
 */
public static void checkFace(String pictureUrl) throws Exception {

// //将在线图片保存为本地图片 // String imgPath = saveLocal(pictureUrl); // //本地图片 // File file = new File(imgPath); // FileInputStream fileInputStream = new FileInputStream(file); // ByteArrayOutputStream out = new ByteArrayOutputStream(); // byte[] localBuff = new byte[fileInputStream.available()]; // fileInputStream.read(localBuff); // out.write(localBuff); // log.info("本地图片:"+localBuff.length);

    //在线图片
    URL url = new URL(pictureUrl);
    URLConnection uc = url.openConnection();
    InputStream inputStream = uc.getInputStream();
    ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
    byte[] buff = new byte[1024];
    int rc;
    while ((rc = inputStream.read(buff, 0, 1024)) > 0) {
        swapStream.write(buff, 0, rc);
    }
    byte[] urlBuff = swapStream.toByteArray();

    log.info("在线图片:"+urlBuff.length);

    List<Byte> bs = new ArrayList<>();
    bs.addAll(Bytes.asList(urlBuff));
    log.info("buffer长度"+bs.size());
    /**
     * 不好使
     */

// Mat image = Converters.vector_char_to_Mat(bs); // Mat image = Converters.vector_uchar_to_Mat(bs); / * 读取本地 */ // Mat image = Imgcodecs.imread(imgPath); / * 读数据流 */ Mat image = Imgcodecs.imdecode(new MatOfByte(urlBuff), Imgcodecs.IMREAD_UNCHANGED);

    if (image.empty()) {
        log.error("image 内容不存在!");
        return;
    }
    // 3 特征匹配
    MatOfRect face = new MatOfRect();
    faceDetector.detectMultiScale(image, face);
    // 4 匹配 Rect 矩阵 数组
    Rect[] rects = face.toArray();
    System.out.println("匹配到 " + rects.length + " 个人脸");

// delFile(imgPath); if (rects.length == 0) { throw new PublicException(ErrorCode.A0430.getCode(), "没有监测到人脸"); } else if (rects.length > 1) { throw new PublicException(ErrorCode.A0430.getCode(), "检测到图片有多张人脸,请重新上传"); } }

public static String saveLocal(String pictureUrl) throws IOException {
    URL url = new URL(pictureUrl);
    URLConnection uc = url.openConnection();
    InputStream inputStream = uc.getInputStream();
    String[] value = pictureUrl.split("/");
    String firstFilePath = "D:\\pictures\\";
    if (!IS_WINDOWS) {
        firstFilePath = "/tmp/tmp-picture/";
    }
    String fileName = firstFilePath + value[value.length - 1];
    FileOutputStream out = new FileOutputStream(fileName);
    int j = 0;
    while ((j = inputStream.read()) != -1) {
        out.write(j);
    }
    inputStream.close();
    return fileName;
}

/**
 * Callback used to run the bean.
 *
 * @param args incoming main method arguments
 * @throws Exception on error
 */
@Override
public void run(String... args){
    String systemProperties = String.valueOf(System.getProperties());
    log.info(systemProperties);
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    String path = "";
    //如果是window系统取出路径开头的/
    if (IS_WINDOWS) {
        path = windowXmlPath;
    }else{
        path = linuxXmlPath;
    }
    /**
     * 初始化人脸探测器
     */
    faceDetector = new CascadeClassifier(path);
    log.info("==========初始化人脸探测器成功===========");
}

} ```

OpenCV 提供的 API 是直接根据路径读取图片的,所以最开始的时候我是把图片保存到本地在读取才成功的,但是这种方式太憨了点,在实际生产环境中,大部分情况下都是直接读取网络图片。在内存就完成图片和 opencv 的 Mat 对象的转换。这里代码中已经解决了 url 地址图片转化的问题。 这里附上解决该问题的博客 传送门

Linux 安装 opencv

Linux 平台须要咱们手动编译,下载 opencv-4.1.1.zip,解压到/user/local 目录下,而后编译

powershell yum install ant gcc gtk2-devel pkgconfig zlib-devel

安装 unzip 命令

powershell yum install -y unzip zip

解压命令

powershell unzip opencv-4.1.1.zip

powershell yum groupinstall "Development Tools"

安装 cmake

查看 cmake 当前版本

powershell cmake --version

powershell yum -y install wget

下载获得 cmake-3.9.2 源码

powershell wget https://cmake.org/files/v3.9/cmake-3.9.2.tar.gz

解压、安装新版本

```powershell tar -xvf cmake-3.9.2.tar.gz

cd cmake-3.9.2

./configure

sudo make && make install ```

powershell cd /usr/local/opencv-4.1.1 mkdir build cd build cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS=OFF .. make -j8 sudo make install

对应的 jar 和.so 文件在

powershell /usr/local/share/java/opencv4/

人脸识别特征 XML 文件的地址

powershell /usr/local/share/opencv4/haarcascades/haarcascade_frontalface_alt.xml

Linux 启动

jar 启动命令添加 Vm options

powershell nohup java -jar -Djava.library.path=/usr/local/share/java/opencv4/ opencv-demo-1.0.jar > logs/opencv-demo-1.0.log 2>&1 &

参考文献

  • 基于人脸聚类的图片管理系统的设计与实现(首都经济贸易大学·王子涛)
  • 基于人脸识别的人员通行信息管理系统的设计与实现(电子科技大学·袁寿柠)
  • 基于人脸聚类的图片管理系统的设计与实现(首都经济贸易大学·王子涛)
  • 提供人脸识别服务的计费管理系统设计与实现(大连理工大学·宋一凡)
  • 基于Spring框架的MVC控制器的优化与改进(山东大学·邵刚)
  • 基于人脸聚类的图片管理系统的设计与实现(首都经济贸易大学·王子涛)
  • 面向校园的人脸识别设备管理平台的设计与实现(佛山科学技术学院·陈嘉欢)
  • 基于人脸识别的人员通行信息管理系统的设计与实现(电子科技大学·袁寿柠)
  • 人脸识别与RFID相结合的身份认证系统的设计与实现(苏州大学·钟海林)
  • 基于web的人脸识别登陆和管理系统设计与实现(郑州大学·王哲)
  • 面向校园的人脸识别设备管理平台的设计与实现(佛山科学技术学院·陈嘉欢)
  • 基于人脸聚类的图片管理系统的设计与实现(首都经济贸易大学·王子涛)
  • 基于Spring技术的大型视频网站后台上传系统的设计与实现(南京大学·徐悦轩)
  • 基于web的人脸识别登陆和管理系统设计与实现(郑州大学·王哲)
  • 基于人脸识别的相册管理系统(上海交通大学·田华伟)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:毕设海岸 ,原文地址:https://m.bishedaima.com/yuanma/35914.html

相关推荐

  • 基于Python实现图像分类

    一, 理论知识 1,1 softmax线性分类器 线性分类器的函数为线性形式,即为(这里将偏置项看做参与乘积的一部分): $$ f(x_1,,,,x_m)=w_0+w_1x_1+
    2024年05月14日
    3 1 1
  • 人事管理系统

    这是一个🔥🔥基于SpringBoot框架的人事管理系统设计与实现🔥🔥的项目源码,开发语言Java,框架使用的SpringBoot+vue技术,开发环境Idea/Eclipse
    2024年05月23日
    1 1 1
  • 基于Python制作的热血足球小游戏

    基于 Python 制作的热血足球小游戏 导语 最近有读者说我发的文章太水了,都是炒冷饭的,那就带大家整点新鲜的东西吧,反正估计今年都得"坐牢"了,炒冷饭的机会有得是
    2024年05月14日
    5 1 2
  • 基于jsp+servlet+mysql的大学社团交流BBS平台

    这是一个🔥🔥基于jsp的大学社团交流BBS平台🔥🔥的项目源码,开发语言Java,开发环境Idea/Eclipse,这个 大学社团交流BBS开发技术栈为JSP项目,可以作为毕业设计课程设计作业大学生社团作为大学生活的重要一部分
    2024年05月23日
    6 1 2
  • Python 新浪微博爬虫

    Python 新浪微博爬虫,支持模拟登陆,微博文字另存为本地文件 网上大部分对微博的爬虫都是先人工登陆获取cookie再进行接下来的抓取操作的,所以我写了一份模拟登陆获取cookie的(因为是分析为主要目的
    2024年05月14日
    2 1 1
  • 基于SpringBoot框架的酒店客房管理系统

    这是一套采用Java语言编写的🔥🔥酒店客房管理系统的源代码,基于SpringBoot框架构建,我们运用了现代化的SpringBoot和Vue技术栈,开发工具为Idea或Eclipse
    2024年05月23日
    1 1 1
  • Spring boot 实战--- 社区论坛

    Spring boot 实战--- 社区论坛 开发社区首页 开发流程 1 次请求的执行过程 分步实现 开发社区首页
    2024年05月14日
    2 1 2
  • 基于 flask 的 Web 计算器

    基于 flask 的 Web 计算器 需求分析 1, 前言 开发基于 flask 作为框架的计算器 Web 应用是为了能够方便快捷的使用计算器
    2024年05月14日
    22 1 3
  • 基于Python实现成绩统计系统

    1, 课程设计目的 《软件设计基础-Python》课程设计是这门课程的实践性教学环节之一,本次设计结合实际应用的要求,使课程设计既覆盖Python的知识点,又接近工程实际需要
    2024年05月14日
    1 1 1
  • 基于WEB的图书阅读器的实现

    2017-毕业设计(基于 Web 平台的阅读 APP 设计与实现) 该项目实现了一款基于 Web 平台的阅读 APP,该 APP 采用简洁护眼颜色搭配,简洁舒适的设计风格
    2024年05月14日
    2 1 1

发表回复

登录后才能评论