{"id":18918279,"url":"https://github.com/avidbyte/opencv-demo","last_synced_at":"2025-04-15T10:32:39.532Z","repository":{"id":105401467,"uuid":"375384236","full_name":"avidbyte/opencv-demo","owner":"avidbyte","description":"springboot集成opencv实现简单的人脸识别","archived":false,"fork":false,"pushed_at":"2021-10-26T07:22:23.000Z","size":23,"stargazers_count":9,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2023-09-25T17:38:29.745Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avidbyte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-06-09T14:28:32.000Z","updated_at":"2023-05-12T06:44:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"d7142a90-9523-44b0-8be9-a369a449b52c","html_url":"https://github.com/avidbyte/opencv-demo","commit_stats":null,"previous_names":["tianzunh/opencv-demo","avidbyte/opencv-demo"],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidbyte%2Fopencv-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidbyte%2Fopencv-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidbyte%2Fopencv-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avidbyte%2Fopencv-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avidbyte","download_url":"https://codeload.github.com/avidbyte/opencv-demo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223668272,"owners_count":17182901,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T10:30:57.325Z","updated_at":"2024-11-08T10:32:08.146Z","avatar_url":"https://github.com/avidbyte.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 前言\n项目中检测人脸图片是否合法的功能，之前用的是百度的人脸识别接口，由于成本高昂不得不寻求替代方案。\n# 什么是opencv？\nOpenCV是一个基于BSD许可（开源）发行的跨平台计算机视觉和机器学习软件库，可以运行在Linux、Windows、Android和Mac OS操作系统上。轻量级而且高效——由一系列 C 函数和少量 C++ 类构成，同时提供了Python、Java、MATLAB等语言的接口，实现了图像处理和计算机视觉方面的很多通用算法。\n\n\n# 项目集成步骤\n由于项目是放在Linux系统中跑的，开发环境是Windows10，所以项目中涉及到opencv的要分两套。\n## 准备工作\n### Windows安装opencv\nopencv官网下载安装包[https://opencv.org/releases/](https://opencv.org/releases/)\n![在这里插入图片描述](https://img-blog.csdnimg.cn/2021060917234471.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDM5MjA1Mw==,size_16,color_FFFFFF,t_70)\n我这里选择的是4.1.1版本\n分别下载了Windows版本和源码\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20210609172523838.png)\n\n### Windows环境下集成\n安装opencv，没什么说的，指定一个路径安装即可，注意安装路径不能是中文。\n项目中集成的**三个关键点**。\n\n - 引入jar依赖\n - 读取OpenCV自带的人脸识别特征XML文件\n - 配置opencv的库文件地址\n\n\n\n#### 关键点1：引入jar包\njar包位置在安装路径下的java文件夹中\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20210609201415840.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDM5MjA1Mw==,size_16,color_FFFFFF,t_70)\n两种方式引入\n##### 方式一：idea添加jar\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20210609202112678.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDM5MjA1Mw==,size_16,color_FFFFFF,t_70)\n或者直接在Libraries中添加二者皆可。\n##### 方式二：将jar上传至私服，在maven中引入\n我这里是将jar上传至私服，然后引用的。\n注意Windows版的jar和Linux中的jar不一样，二者要区分开来\n通过Maven配置在不同环境下加载不同的jar\n\n```xml\n\u003cprofiles\u003e\n    \u003cprofile\u003e\n        \u003cid\u003edev\u003c/id\u003e\n        \u003cdependencies\u003e\n\u003c!--            本地引用--\u003e\n\u003c!--                \u003cdependency\u003e--\u003e\n\u003c!--                    \u003cgroupId\u003eop\u003c/groupId\u003e--\u003e\n\u003c!--                    \u003cartifactId\u003eopencv\u003c/artifactId\u003e--\u003e\n\u003c!--                    \u003cversion\u003e411\u003c/version\u003e--\u003e\n\u003c!--                    \u003cscope\u003esystem\u003c/scope\u003e--\u003e\n\u003c!--                    \u003csystemPath\u003e--\u003e\n\u003c!--                        ${project.basedir}/src/main/resources/opencv/windows/opencv-411.jar--\u003e\n\u003c!--                    \u003c/systemPath\u003e--\u003e\n\u003c!--                \u003c/dependency\u003e--\u003e\n            \n\u003c!--            仓库引用--\u003e\n            \u003cdependency\u003e\n            \u003c!--                这里改成自己的仓库地址--\u003e\n                \u003cgroupId\u003ecom.***.cloud.resource\u003c/groupId\u003e\n                \u003cartifactId\u003eopencv-window\u003c/artifactId\u003e\n                \u003cversion\u003e411\u003c/version\u003e\n            \u003c/dependency\u003e\n        \u003c/dependencies\u003e\n        \u003cactivation\u003e\n            \u003cactiveByDefault\u003etrue\u003c/activeByDefault\u003e\n        \u003c/activation\u003e\n    \u003c/profile\u003e\n    \u003cprofile\u003e\n        \u003cid\u003etest\u003c/id\u003e\n        \u003cdependencies\u003e\n            \u003cdependency\u003e\n            \u003c!--                这里改成自己的仓库地址--\u003e\n                \u003cgroupId\u003ecom.***.cloud.resource\u003c/groupId\u003e\n                \u003cartifactId\u003eopencv-linux\u003c/artifactId\u003e\n                \u003cversion\u003e411\u003c/version\u003e\n            \u003c/dependency\u003e\n        \u003c/dependencies\u003e\n    \u003c/profile\u003e\n\u003c/profiles\u003e\n```\n\n#### 关键点2：配置人脸识别特征XML文件的地址\n在bootstrap.yml添加如下参数\n\n```xml\n#  函数库地址 在 vm optionis中 配置\n#  windows地址: -Djava.library.path=D:\\software\\opencv\\build\\java\\x64\n#  linux地址:   -Djava.library.path=/usr/local/opencv-4.1.1/build/lib/\nopencv:\n  lib:\n    linuxxmlpath: /usr/local/share/opencv4/haarcascades/haarcascade_frontalface_alt.xml\n    windowxmlpath: D:\\software\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml\n```\n测试的方法中就直接写死了\n\n```java\n    /**\n     * 初始化人脸探测器\n     */\n    static CascadeClassifier faceDetector;\n\n    static {\n        String systemProperties = String.valueOf(System.getProperties());\n        log.info(systemProperties);\n        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);\n        faceDetector = new CascadeClassifier(\"D:\\\\software\\\\opencv\\\\sources\\\\data\\\\haarcascades\\\\haarcascade_frontalface_alt.xml\");\n    }\n```\n注意路径！！\n\n#### 关键点3：配置opencv的库文件地址\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20210609214227904.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MDM5MjA1Mw==,size_16,color_FFFFFF,t_70)\n\n```bash\n-Djava.library.path=D:\\software\\opencv\\build\\java\\x64\n```\n这里其实指向的就是 该目录下的 opencv_java411.dll 文件\n（linux的配置见下文）\n\n### 代码\n#### 测试方法\n```java\npackage com.example.opencvdemo.test;\n\nimport lombok.extern.slf4j.Slf4j;\nimport org.opencv.core.*;\nimport org.opencv.highgui.HighGui;\nimport org.opencv.imgcodecs.Imgcodecs;\nimport org.opencv.imgproc.Imgproc;\nimport org.opencv.objdetect.CascadeClassifier;\n\n/**\n * @author aaron\n * @since 2021-06-07\n */\n@Slf4j\npublic class FaceVideo {\n    /**\n     * 初始化人脸探测器\n     */\n    static CascadeClassifier faceDetector;\n\n    static {\n        String systemProperties = String.valueOf(System.getProperties());\n        log.info(systemProperties);\n        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);\n        faceDetector = new CascadeClassifier(\"D:\\\\software\\\\opencv\\\\sources\\\\data\\\\haarcascades\\\\haarcascade_frontalface_alt.xml\");\n    }\n\n    public static void main(String[] args){\n        // 3- 本地图片人脸识别，识别成功并保存人脸图片到本地\n        String imgPath = \"C:\\\\Users\\\\Administrator\\\\Pictures\\\\wang.jpg\";\n        face(imgPath);\n    }\n\n    /**\n     * OpenCV-4.1.1 图片人脸识别\n     *\n     * @return: void\n     * @date: 2019年5月7日12:16:55\n     */\n    public static void face(String imgPath) {\n        /**\n         * 读取本地\n         */\n        Mat image = Imgcodecs.imread(imgPath);\n        if (image.empty()) {\n            System.out.println(\"image 内容不存在！\");\n            return;\n        }\n        // 3 特征匹配\n        MatOfRect face = new MatOfRect();\n        faceDetector.detectMultiScale(image, face);\n        // 4 匹配 Rect 矩阵 数组\n        Rect[] rects = face.toArray();\n        System.out.println(\"匹配到 \" + rects.length + \" 个人脸\");\n        // 5 为每张识别到的人脸画一个圈\n        int i = 1;\n        for (Rect rect : face.toArray()) {\n            Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),\n                    new Scalar(0, 255, 0), 3);\n            imageCut(imgPath, \"D:\\\\pictures\\\\\" + i + \".jpg\", rect.x, rect.y, rect.width, rect.height);// 进行图片裁剪\n            i++;\n        }\n        // 6 展示图片\n        HighGui.imshow(\"人脸识别\", image);\n        HighGui.waitKey(0);\n    }\n    /**\n     * 裁剪人脸\n     *\n     * @param imagePath\n     * @param outFile\n     * @param posX\n     * @param posY\n     * @param width\n     * @param height\n     */\n    public static void imageCut(String imagePath, String outFile, int posX, int posY, int width, int height) {\n        // 原始图像\n        Mat image = Imgcodecs.imread(imagePath);\n        // 截取的区域：参数,坐标X,坐标Y,截图宽度,截图长度\n        Rect rect = new Rect(posX, posY, width, height);\n        // 两句效果一样\n        Mat sub = image.submat(rect); // Mat sub = new Mat(image,rect);\n        Mat mat = new Mat();\n        Size size = new Size(width, height);\n        Imgproc.resize(sub, mat, size);// 将人脸进行截图并保存\n        Imgcodecs.imwrite(outFile, mat);\n        System.out.println(String.format(\"图片裁切成功，裁切后图片文件为： %s\", outFile));\n\n    }\n}\n\n```\n**注意！Mat image = Imgcodecs.imread(imgPath); \nimgPath中不能带有中文！** opencv安装路径中如果有中文的话就会报错。\n\n#### 集成到Springboot\n```java\npackage com.example.opencvdemo.util;\n\nimport com.example.opencvdemo.exception.PublicException;\nimport com.example.opencvdemo.result.ErrorCode;\nimport com.google.common.primitives.Bytes;\nimport lombok.extern.slf4j.Slf4j;\nimport org.opencv.core.*;\nimport org.opencv.imgcodecs.Imgcodecs;\nimport org.opencv.objdetect.CascadeClassifier;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.boot.CommandLineRunner;\nimport org.springframework.stereotype.Component;\n\nimport java.io.*;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * @author aaron\n * @since 2021-06-07\n */\n@Component\n@Slf4j\npublic class OpenCvUtils implements CommandLineRunner {\n\n    @Value(\"${opencv.lib.linuxxmlpath}\")\n    private String linuxXmlPath;\n    @Value(\"${opencv.lib.windowxmlpath}\")\n    private String windowXmlPath;\n\n    /**\n     * 人脸探测器对象\n     */\n    static CascadeClassifier faceDetector;\n\n    /**\n     * 判断是否是Windows系统\n     */\n    private static final boolean IS_WINDOWS = System.getProperty(\"os.name\").toLowerCase().contains(\"win\");\n\n    /**\n     * 监测图片是否合法，是否只有一张脸\n     */\n    public static void checkFace(String pictureUrl) throws Exception {\n//        //将在线图片保存为本地图片\n//        String imgPath = saveLocal(pictureUrl);\n//        //本地图片\n//        File file  = new File(imgPath);\n//        FileInputStream fileInputStream = new FileInputStream(file);\n//        ByteArrayOutputStream out = new ByteArrayOutputStream();\n//        byte[] localBuff = new byte[fileInputStream.available()];\n//        fileInputStream.read(localBuff);\n//        out.write(localBuff);\n//        log.info(\"本地图片:\"+localBuff.length);\n\n        //在线图片\n        URL url = new URL(pictureUrl);\n        URLConnection uc = url.openConnection();\n        InputStream inputStream = uc.getInputStream();\n        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();\n        byte[] buff = new byte[1024];\n        int rc;\n        while ((rc = inputStream.read(buff, 0, 1024)) \u003e 0) {\n            swapStream.write(buff, 0, rc);\n        }\n        byte[] urlBuff = swapStream.toByteArray();\n\n        log.info(\"在线图片:\"+urlBuff.length);\n\n        List\u003cByte\u003e bs = new ArrayList\u003c\u003e();\n        bs.addAll(Bytes.asList(urlBuff));\n        log.info(\"buffer长度\"+bs.size());\n        /**\n         * 不好使\n         */\n//        Mat image =  Converters.vector_char_to_Mat(bs);\n//        Mat image  =  Converters.vector_uchar_to_Mat(bs);\n        /**\n         * 读取本地\n         */\n//        Mat image = Imgcodecs.imread(imgPath);\n        /**\n         * 读数据流\n         */\n        Mat image  = Imgcodecs.imdecode(new MatOfByte(urlBuff), Imgcodecs.IMREAD_UNCHANGED);\n\n        if (image.empty()) {\n            log.error(\"image 内容不存在！\");\n            return;\n        }\n        // 3 特征匹配\n        MatOfRect face = new MatOfRect();\n        faceDetector.detectMultiScale(image, face);\n        // 4 匹配 Rect 矩阵 数组\n        Rect[] rects = face.toArray();\n        System.out.println(\"匹配到 \" + rects.length + \" 个人脸\");\n//        delFile(imgPath);\n        if (rects.length == 0) {\n            throw new PublicException(ErrorCode.A0430.getCode(), \"没有监测到人脸\");\n        } else if (rects.length \u003e 1) {\n            throw new PublicException(ErrorCode.A0430.getCode(), \"检测到图片有多张人脸,请重新上传\");\n        }\n    }\n\n    public static String saveLocal(String pictureUrl) throws IOException {\n        URL url = new URL(pictureUrl);\n        URLConnection uc = url.openConnection();\n        InputStream inputStream = uc.getInputStream();\n        String[] value = pictureUrl.split(\"/\");\n        String firstFilePath = \"D:\\\\pictures\\\\\";\n        if (!IS_WINDOWS) {\n            firstFilePath = \"/tmp/tmp-picture/\";\n        }\n        String fileName = firstFilePath + value[value.length - 1];\n        FileOutputStream out = new FileOutputStream(fileName);\n        int j = 0;\n        while ((j = inputStream.read()) != -1) {\n            out.write(j);\n        }\n        inputStream.close();\n        return fileName;\n    }\n\n    /**\n     * Callback used to run the bean.\n     *\n     * @param args incoming main method arguments\n     * @throws Exception on error\n     */\n    @Override\n    public void run(String... args){\n        String systemProperties = String.valueOf(System.getProperties());\n        log.info(systemProperties);\n        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);\n        String path = \"\";\n        //如果是window系统取出路径开头的/\n        if (IS_WINDOWS) {\n            path = windowXmlPath;\n        }else{\n            path = linuxXmlPath;\n        }\n        /**\n         * 初始化人脸探测器\n         */\n        faceDetector = new CascadeClassifier(path);\n        log.info(\"==========初始化人脸探测器成功===========\");\n    }\n}\n```\nOpenCV 提供的 API 是直接根据路径读取图片的，所以最开始的时候我是把图片保存到本地在读取才成功的，但是这种方式太憨了点，在实际生产环境中，大部分情况下都是直接读取网络图片。在内存就完成图片和 opencv 的 Mat 对象的转换。这里代码中已经解决了url地址图片转化的问题。\n这里附上解决该问题的博客   [传送门](http://blog.joylau.cn/2019/04/03/OpenCV-ByteImage/)\n\n\n\n### Linux安装opencv\nLinux平台须要咱们手动编译，下载opencv-4.1.1.zip，解压到/user/local目录下，而后编译\n\n```powershell\nyum  install   ant    gcc  gtk2-devel   pkgconfig  zlib-devel\n```\n安装unzip命令\n```powershell\nyum install -y unzip zip\n```\n解压命令\n```powershell\nunzip opencv-4.1.1.zip\n```\n\n```powershell\nyum   groupinstall \"Development Tools\"\n```\n**安装cmake**\n\n查看cmake当前版本\n```powershell\ncmake --version\n```\n```powershell\nyum -y install wget\n```\n下载获得cmake-3.9.2源码\n\n```powershell\nwget https://cmake.org/files/v3.9/cmake-3.9.2.tar.gz\n```\n解压、安装新版本\n\n```powershell\ntar -xvf cmake-3.9.2.tar.gz\n\ncd cmake-3.9.2\n\n./configure\n\nsudo make \u0026\u0026 make install\n```\n\n```powershell\ncd /usr/local/opencv-4.1.1\nmkdir build\ncd build\ncmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS=OFF ..\nmake -j8\nsudo make install\n```\n对应的jar和.so文件在\n\n```powershell\n/usr/local/share/java/opencv4/\n```\n![在这里插入图片描述](https://img-blog.csdnimg.cn/20210610112715954.png)\n\n人脸识别特征XML文件的地址\n\n```powershell\n/usr/local/share/opencv4/haarcascades/haarcascade_frontalface_alt.xml\n```\n\n### Linux启动\njar 启动命令添加Vm options\n```powershell\nnohup java -jar -Djava.library.path=/usr/local/share/java/opencv4/ opencv-demo-1.0.jar  \u003e logs/opencv-demo-1.0.log 2\u003e\u00261 \u0026\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favidbyte%2Fopencv-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favidbyte%2Fopencv-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favidbyte%2Fopencv-demo/lists"}