当前位置:   article > 正文

SpringBoot使用OpenCV_springboot opencv

springboot 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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126

测试代码


    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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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
  • 1
  • 2
  • 3
  • 4
  • 5

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
  • 1
  • 2
  • 3
  • 4
  • 5

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

  • 1
  • 2

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

  • 1
  • 2

执行结果:


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.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

总结

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/623223
推荐阅读
相关标签
  

闽ICP备14008679号