SpringBoot使用OpenCV

SpringBoot使用OpenCV

  • Spring boot 整合 OpenCV 4.5
    • 环境安装
    • 配置spring boot项目
  • OpenCV 训练自己的模型,实现特定物体的识别
    • 环境安装
    • 前期准备
    • 总结

Spring boot 整合 OpenCV 4.5

本文展示Windows下Spring Boot 整合Opencv 4.5 进行对图片中的人脸提取,开发工具IDEA。

环境安装

1、下载opencv安装包【下载地址】

在这里插入图片描述
2、下载后运行exe、安装。

在这里插入图片描述

配置spring boot项目

1、创建空白spring boot项目,jar放入如下图,pom添加依赖。
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>OpenCVStudy</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>OpenCVStudy</name>
    <description>项目骨架</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.6.RELEASE</version>
        <relativePath/>
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.SR1</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--openCV 依赖包-->
        <dependency>
            <groupId>org.opencv</groupId>
            <artifactId>opencv</artifactId>
            <version>4.5.1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/opencv-451.jar</systemPath>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>gfs-maven-snapshot-repository</id>
            <name>gfs-maven-snapshot-repository</name>
            <url>https://raw.githubusercontent.com/gefangshuai/maven/master/</url>
        </repository>
    </repositories>
</project>

2、opencv\build\java目录的dll,opencv\sources\data\haarcascades数据集,按图存放。

在这里插入图片描述

3、测试代码

创建类 StreamUtils.java


import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.IOException;


public class StreamUtils {
    /**
     * 装换回编码
     *
     * @param correctMat
     * @return
     */
    public static String catToBase64(Mat correctMat) {
        return bufferToBase64(toByteArray(correctMat));
    }

    /**
     * 转换成base64编码
     *
     * @param buffer
     * @return
     */
    public static String bufferToBase64(byte[] buffer) {
        return Base64Utils.encodeToString(buffer);
    }

    /**
     * base64编码转换成字节数组
     *
     * @param base64Str
     * @return
     */
    public static byte[] base64ToByteArray(String base64Str) {
        return Base64Utils.decodeFromString(base64Str);
    }

    /**
     * base64 编码转换为 BufferedImage
     *
     * @param base64
     * @return
     */
    public static BufferedImage base64ToBufferedImage(String base64) {
        BASE64Decoder Base64 = new BASE64Decoder();
        try {
            byte[] bytes1 = Base64.decodeBuffer(base64);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
            return ImageIO.read(bais);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * mat转换成bufferedImage
     *
     * @param matrix
     * @return
     */
    public static byte[] toByteArray(Mat matrix) {
        MatOfByte mob = new MatOfByte();
        Imgcodecs.imencode(".jpg", matrix, mob);
        return mob.toArray();
    }

    /**
     * mat转换成bufferedImage
     *
     * @param matrix
     * @return
     */
    public static BufferedImage toBufferedImage(Mat matrix) throws IOException {
        byte[] buffer = toByteArray(matrix);
        ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
        return ImageIO.read(bais);
    }

    /**
     * base64转Mat
     *
     * @param base64
     * @return
     * @throws IOException
     */
    public static Mat base642Mat(String base64) {
        return bufImg2Mat(base64ToBufferedImage(base64), BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3);
    }

    /**
     * BufferedImage转换成Mat
     *
     * @param original 要转换的BufferedImage
     * @param imgType  bufferedImage的类型 如 BufferedImage.TYPE_3BYTE_BGR
     * @param matType  转换成mat的type 如 CvType.CV_8UC3
     */
    public static Mat bufImg2Mat(BufferedImage original, int imgType, int matType) {
        if (original == null) {
            throw new IllegalArgumentException("original == null");
        }
        // Don't convert if it already has correct type
        if (original.getType() != imgType) {
            // Create a buffered image
            BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType);
            // Draw the image onto the new buffer
            Graphics2D g = image.createGraphics();
            try {
                g.setComposite(AlphaComposite.Src);
                g.drawImage(original, 0, 0, null);
                original = image;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                g.dispose();
            }
        }
        byte[] pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData();
        Mat mat = Mat.eye(original.getHeight(), original.getWidth(), matType);
        mat.put(0, 0, pixels);
        return mat;
    }
}

测试代码


    public static String markFace(String base64Images) {
        String path = System.getProperty("user.dir").concat("/haarcascades/haarcascade_frontalface_alt.xml");
        CascadeClassifier faceDetector = new CascadeClassifier(path);
        MatOfRect faceDetections = new MatOfRect();
        Mat mat = StreamUtils.base642Mat(base64Images);
        faceDetector.detectMultiScale(mat, faceDetections);
        if (faceDetections.toArray().length > 0) {
            for (Rect rect : faceDetections.toList()) {
                Imgproc.rectangle(mat, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0), 3);
            }
        }
        return StreamUtils.catToBase64(mat);
    }
    
    public static void main(String[] args) {
        String base64Img = "";
        String base64Back = markFace(base64Img);
    }

OpenCV 训练自己的模型,实现特定物体的识别

opencv 3.4版本才能有训练器文件,4.5版本去掉了;但是训练出的数据集能通用。本人喜欢用新版,前面介绍使用的是高版本,训练自己的模型必须用3.4.X版本的。

环境安装

1、下载opencv安装包【下载地址】

在这里插入图片描述

2、下载后选择目录安装,提取文件到本地,检查是否存在目录。在这里插入图片描述

前期准备

1、正样本数据图片5张(image\positive\img);创建文件info.dat(image\positive)并编辑如下内容。

在这里插入图片描述

img/1.jpg 1 0 0 55 55
img/2.jpg 1 0 0 55 55
img/3.jpg 1 0 0 55 55
img/4.jpg 1 0 0 55 55
img/5.jpg 1 0 0 55 55

2、负样本数据图片5张(image\negitive\img);创建bg.txt文件并编辑如下内容。

在这里插入图片描述

D:\tools\OpenCV\xl\image\negitive\img\1.jpg
D:\tools\OpenCV\xl\image\negitive\img\2.jpg
D:\tools\OpenCV\xl\image\negitive\img\3.jpg
D:\tools\OpenCV\xl\image\negitive\img\4.jpg
D:\tools\OpenCV\xl\image\negitive\img\5.jpg

3、cmd执行,生成sample.vec文件;

> D:\tools\OpenCV\opencv3.4\opencv\build\x64\vc15\bin\opencv_createsamples.exe -info D:\tools\OpenCV\xl\image\positive\info.dat -vec D:\tools\OpenCV\xl\image\sample.vec -num 5 -bgcolor 0 -bgthresh 0 -w 24 -h 24

4、生成的sample.vec和bg.txt拷贝到opencv_traincascade.exe同级目录(opencv有这个bug,不能指定目录,不然会产生报错),cmd执行;

注意:numPos 不能为正样本数量,只能小于实际数量。numNeg为负样本数量,可以大于实际数量

D:\tools\OpenCV\opencv3.4\opencv\build\x64\vc15\bin\opencv_traincascade.exe -data D:\tools\OpenCV\xl\image -vec sample.vec -bg bg.txt -numPos 3 -numNeg 7 -numStages 12 -feattureType HAAR -w 24 -h 24 -minHitRate 0.995 -maxFalseAlarmRate 0.5

执行结果:


PARAMETERS:
cascadeDirName: D:\tools\OpenCV\xl\image
vecFileName: sample.vec
bgFileName: bg.txt
numPos: 4
numNeg: 7
numStages: 12
precalcValBufSize[Mb] : 1024
precalcIdxBufSize[Mb] : 1024
acceptanceRatioBreakValue : -1
stageType: BOOST
featureType: HAAR
sampleWidth: 24
sampleHeight: 24
boostType: GAB
minHitRate: 0.995
maxFalseAlarmRate: 0.5
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
mode: BASIC
Number of unique features given windowSize [24,24] : 162336

===== TRAINING 0-stage =====
<BEGIN
POS count : consumed   4 : 4
NEG count : acceptanceRatio    7 : 1
Precalculation time: 0.008
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        0|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 0 minutes 0 seconds.

===== TRAINING 1-stage =====
<BEGIN
POS count : consumed   4 : 4
NEG count : acceptanceRatio    7 : 0.875
Precalculation time: 0.008
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        0|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 0 minutes 0 seconds.

===== TRAINING 2-stage =====
<BEGIN
POS count : consumed   4 : 4
NEG count : acceptanceRatio    7 : 0.636364
Precalculation time: 0.008
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        0|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 0 minutes 0 seconds.

===== TRAINING 3-stage =====
<BEGIN
POS count : consumed   4 : 4
NEG count : acceptanceRatio    7 : 0.01983
Precalculation time: 0.008
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        0|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 0 minutes 0 seconds.

===== TRAINING 4-stage =====
<BEGIN
POS count : consumed   4 : 4
NEG count : acceptanceRatio    7 : 0.00266565
Precalculation time: 0.007
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        0|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 0 minutes 0 seconds.

===== TRAINING 5-stage =====
<BEGIN
POS count : consumed   4 : 4
NEG count : acceptanceRatio    0 : 0
Required leaf false alarm rate achieved. Branch training terminated.

5、执行完生成 cascade.xml
在这里插入图片描述
6、创建测试代码使用,可行。

 public static String cascade(String base64Images) {
        String path = System.getProperty("user.dir").concat("/haarcascades/cascade.xml");
        CascadeClassifier faceDetector = new CascadeClassifier(path);
        MatOfRect faceDetections = new MatOfRect();
        Mat mat = StreamUtils.base642Mat(base64Images);
        faceDetector.detectMultiScale(mat, faceDetections);
        if (faceDetections.toArray().length > 0) {
            for (Rect rect : faceDetections.toList()) {
                Imgproc.rectangle(mat, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0), 3);
            }
        }
        return StreamUtils.catToBase64(mat);
    }

    public static void main(String[] args) {
        String base64Img = "";
        String base64Back = cascade(base64Img);
    }

总结

本文只是学习如何训练自己模型,选用正本和反面数据较小,实际项目中需要选用大量得样本数据图片。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/358032.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

防火墙到防火墙的高可用知识汇总

目录​​​​​​​ 防火墙 防火墙的分类&#xff1a; 防火墙的发展史 传统防火墙&#xff08;包过滤防火墙&#xff09;—— 一个严格的规则表 传统防火墙&#xff08;应用代理防火墙&#xff09;—— 每个应用添加代理 传统防火墙&#xff08;状态检测防火墙&#xff09…

责任链模式在java中的实现

1 总览 2 概念 避免请求发送者与接收者耦合在一起&#xff0c;让多个对象都有可能接收请求&#xff0c;将这些对象连接成一条链&#xff0c;并且沿着这条链传递请求&#xff0c;直到有对象处理它为止。职责链模式是一种对象行为型模式。 3 实现 公共部分&#xff0c;一个系…

Windows、Linux、Mac数据库的安装(mysql、MongoDB、Redis)

数据库的安装 作为数据存储的重要部分&#xff0c;数据库同样是必不可少的&#xff0c;数据库可以分为关系型数据库和非关系型数据库。 关系型数据库如 SQLite、MySQL、Oracle、SQL Server、DB2 等&#xff0c;其数据库是以表的形式存储&#xff1b;非关系型数据库如 MongoDB…

wsl-ubuntu 安装 nginx

wsl-ubuntu 安装 nginx 1. 安装 nginx2. 确认 nginx 启动状态3. 重启 nginx4. 停止 nginx 1. 安装 nginx sudo apt install nginx2. 确认 nginx 启动状态 systemctl status nginx3. 重启 nginx systemctl restart nginx4. 停止 nginx systemctl stop nginx完成&#xff01;…

CRM系统多少钱一套?

CRM系统多少钱一套&#xff1f; 相信这是企业普遍关心的一个问题。 我们公司也使用过CRM客户关系管理系统&#xff0c;经验就是&#xff0c;建议在开发前先进行一次详细的需求分析&#xff0c;确定采用哪种开发方式&#xff0c;估量所需的工作量&#xff1b;然后在此基础上&a…

【软考问题】-- 5 - 知识精讲 - 项目进度管理

一、基本问题 项目进度管理&#xff08;按时完成&#xff09; 1&#xff1a;紧前关系绘图法&#xff1f; 定义&#xff1a;它是创建进度模型的一种技术。别称&#xff1a; PDM、前导图法、单代号网络图&#xff08;只有节点需要编号&#xff09;、活动节点图&#xff08;AON&a…

Habitat环境学习二:导航任务中的Habitat-sim基础Habitat-sim Basics for Navigation

导航任务在Habitat-sim任务中的实现 官方教程概述重要概念1、Hello World程序1.0.1 基础设置Basic settings1.0.2 模拟器设置Configurations for the simulator1.0.3 创建模拟器实例1.0.4 初始化Agent1.0.5 导航和探索 官方教程 Habitat是一个高效的真实的3D模拟器&#xff0c…

iTunes Connect 中修改后的内购(IPA)审核所需的时间

引言 在 iOS 开发过程中&#xff0c;将应用上传到 App Store 是一个重要的步骤。应用审核和 IAP 商品审核是分开的&#xff0c;审核一般需要等待一周左右。如果审核通过&#xff0c;我们会收到 Apple 发来的反馈邮件&#xff0c;根据邮件中的指示进行后续操作。如果已经上架的…

客户点赞,“信”任满满 | 竹云喜获近百封感谢信!

玉兔辞旧岁&#xff0c;威龙迎新春 在新春佳节来临之际 一封封感谢信、表扬信 纷至沓来 纸短情长 每一封感谢信的背后 都记载着一个动人的故事 字里行间情真意切 激励着竹云继续前行&#xff01; 国家电投 竹云项目组成员凭借丰富的业务、技术经验、专业的职业素养和较…

从换脸到克隆:IP Adapter FaceID的技术突破与应用

引言 换脸技术&#xff0c;一直以来都是数字图像处理领域的热门话题。从最早的传统方法到现在的AI驱动技术&#xff0c;换脸技术已经经历了多次重大的技术革新。近年来&#xff0c;随着深度学习和计算机视觉技术的发展&#xff0c;换脸技术开始向更加智能化、自动化的方向演进…

Springboot自定义线程池实现多线程任务

1. 在启动类添加EnableAsync注解 2.自定义线程池 package com.bt.springboot.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTask…

移动端深度编辑产品技术解决方案

视频编辑已经成为企业宣传、教育、娱乐等多个领域的重要工具。美摄科技凭借其深厚的技术积累和对市场需求的敏锐洞察&#xff0c;开发出业界领先的移动端深度编辑产品&#xff0c;为企业提供高效、专业的视频编辑解决方案。 美摄科技移动端深度编辑产品方案&#xff0c;基于多…

思维导图:大神教你如何画思维导图

思维导图是什么&#xff1f; 思维导图是一种图形化的工具&#xff0c;用于组织和展示思维过程、概念关系和信息结构。它以一个中心主题为起点&#xff0c;通过分支和连接的方式&#xff0c;将相关的想法、概念、关键词等呈现在一个图形化的结构中。 思维导图通常以中心节点开始…

自动化测试——selenium工具(web自动化测试)

1、自动化测试 优点&#xff1a;通过自动化测试有效减少人力的投入&#xff0c;同时提高了测试的质量和效率。 也用于回归测试。随着版本越来越多&#xff0c;版本回归的压力越来越大&#xff0c;仅仅通过人工测试 来回归所以的版本肯定是不现实的&#xff0c;所以…

备战蓝桥杯--数据结构及STL应用(基础)

今天轻松一点&#xff0c;讲一讲stl的基本操作吧&#xff01; 首先&#xff0c;让我们一起创建一个vector容器吧&#xff01; #include<bits/stdc.h> using namespace std; struct cocoack{ int coco,ck; } void solve(){vector<cocoack> x;for(int i0;i<5;i){…

springboot3+vue3支付宝在线支付案例-渲染产品列表页面

springboot3vue3支付宝在线支付案例-渲染产品列表页面&#xff01;今天折腾了半天&#xff0c;完成了vue3前端项目的产品列表选染。 我们使用到了技术有axios&#xff08;发送跨域的请求获取产品&#xff09;。pinia&#xff08;绑定数据&#xff09;, import { ref } from vu…

203.移除链表元素(力扣LeetCode)

文章目录 203.移除链表元素题目描述原链表删除元素虚拟头节点 203.移除链表元素 题目描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head …

redis-4 集群

应用场景 为什么需要redis集群&#xff1f; 当主备复制场景&#xff0c;无法满足主机的单点故障时&#xff0c;需要引入集群配置。 一般数据库要处理的读请求远大于写请求 &#xff0c;针对这种情况&#xff0c;我们优化数据库可以采用读写分离的策略。我们可以部 署一台主服…

网安文件包含漏洞

文件包含概念&#xff1a; 开发人员通常会把可重复使用的函数写到单个文件中&#xff0c;在使用某些函数时&#xff0c;直接调用此文件&#xff0c;而无需再次编写&#xff0c;这种调用文件的过程一般被称为包含。为了使代码更加灵活&#xff0c;通常会将被包含的文件设置为变…

【C/C++ 01】初级排序算法

排序算法通常是针对数组或链表进行排序&#xff0c;在C语言中&#xff0c;需要手写排序算法完成对数据的排序&#xff0c;排序规则通常为升序或降序&#xff08;本文默认为升序&#xff09;&#xff0c;在C中&#xff0c;<algorithm>头文件中已经封装了基于快排算法的 st…