SpringBoot使用OpenCV
作者:mmseoamin日期:2024-04-27

SpringBoot使用OpenCV

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

        Spring boot 整合 OpenCV 4.5

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

        环境安装

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

        SpringBoot使用OpenCV,在这里插入图片描述,第1张

        2、下载后运行exe、安装。

        SpringBoot使用OpenCV,在这里插入图片描述,第2张

        配置spring boot项目

        1、创建空白spring boot项目,jar放入如下图,pom添加依赖。

        SpringBoot使用OpenCV,在这里插入图片描述,第3张

        
        
            4.0.0
            org.example
            OpenCVStudy
            1.0-SNAPSHOT
            pom
            OpenCVStudy
            项目骨架
            
                org.springframework.boot
                spring-boot-starter-parent
                2.0.6.RELEASE
                
            
            
                UTF-8
                UTF-8
                1.8
                Finchley.SR1
            
            
                
                    org.springframework.boot
                    spring-boot-starter-test
                    test
                
                
                    org.springframework.boot
                    spring-boot-starter-web
                
                
                    org.springframework.boot
                    spring-boot-starter-test
                    test
                
                
                
                    org.opencv
                    opencv
                    4.5.1
                    system
                    ${project.basedir}/src/main/resources/lib/opencv-451.jar
                
            
            
                
                    
                        org.springframework.boot
                        spring-boot-maven-plugin
                    
                
            
            
                
                    gfs-maven-snapshot-repository
                    gfs-maven-snapshot-repository
                    https://raw.githubusercontent.com/gefangshuai/maven/master/
                
            
        
        

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

        SpringBoot使用OpenCV,在这里插入图片描述,第4张

        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安装包【下载地址】

        SpringBoot使用OpenCV,在这里插入图片描述,第5张

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

        前期准备

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

        SpringBoot使用OpenCV,在这里插入图片描述,第7张

        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文件并编辑如下内容。

        SpringBoot使用OpenCV,在这里插入图片描述,第8张

        D:\tools\OpenCV\xl\image\negitive\img.jpg
        D:\tools\OpenCV\xl\image\negitive\img.jpg
        D:\tools\OpenCV\xl\image\negitive\img.jpg
        D:\tools\OpenCV\xl\image\negitive\img.jpg
        D:\tools\OpenCV\xl\image\negitive\img.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 =====
        
        Training until now has taken 0 days 0 hours 0 minutes 0 seconds.
        ===== TRAINING 1-stage =====
        
        Training until now has taken 0 days 0 hours 0 minutes 0 seconds.
        ===== TRAINING 2-stage =====
        
        Training until now has taken 0 days 0 hours 0 minutes 0 seconds.
        ===== TRAINING 3-stage =====
        
        Training until now has taken 0 days 0 hours 0 minutes 0 seconds.
        ===== TRAINING 4-stage =====
        
        Training until now has taken 0 days 0 hours 0 minutes 0 seconds.
        ===== TRAINING 5-stage =====
         
        

        5、执行完生成 cascade.xml

        SpringBoot使用OpenCV,在这里插入图片描述,第9张

        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);
            }
        

        总结

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