SpringBoot使用OpenCV的超詳細(xì)步驟
Spring boot 整合 OpenCV 4.5
本文展示W(wǎng)indows下Spring Boot 整合Opencv 4.5 進(jìn)行對(duì)圖片中的人臉提取,開發(fā)工具IDEA。
環(huán)境安裝
1、下載opencv安裝包【下載地址】 或者點(diǎn)擊這里下載最新版
2、下載后運(yùn)行exe、安裝。
配置spring boot項(xiàng)目
1、創(chuàng)建空白spring boot項(xiàng)目,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>項(xiàng)目骨架</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數(shù)據(jù)集,按圖存放。
3、測(cè)試代碼
創(chuàng)建類 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)); } /** * 轉(zhuǎn)換成base64編碼 * * @param buffer * @return */ public static String bufferToBase64(byte[] buffer) { return Base64Utils.encodeToString(buffer); } /** * base64編碼轉(zhuǎn)換成字節(jié)數(shù)組 * * @param base64Str * @return */ public static byte[] base64ToByteArray(String base64Str) { return Base64Utils.decodeFromString(base64Str); } /** * base64 編碼轉(zhuǎn)換為 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轉(zhuǎn)換成bufferedImage * * @param matrix * @return */ public static byte[] toByteArray(Mat matrix) { MatOfByte mob = new MatOfByte(); Imgcodecs.imencode(".jpg", matrix, mob); return mob.toArray(); } /** * mat轉(zhuǎn)換成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轉(zhuǎn)Mat * * @param base64 * @return * @throws IOException */ public static Mat base642Mat(String base64) { return bufImg2Mat(base64ToBufferedImage(base64), BufferedImage.TYPE_3BYTE_BGR, CvType.CV_8UC3); } /** * BufferedImage轉(zhuǎn)換成Mat * * @param original 要轉(zhuǎn)換的BufferedImage * @param imgType bufferedImage的類型 如 BufferedImage.TYPE_3BYTE_BGR * @param matType 轉(zhuǎn)換成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; } }
測(cè)試代碼
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 訓(xùn)練自己的模型,實(shí)現(xiàn)特定物體的識(shí)別
opencv 3.4版本才能有訓(xùn)練器文件,4.5版本去掉了;但是訓(xùn)練出的數(shù)據(jù)集能通用。本人喜歡用新版,前面介紹使用的是高版本,訓(xùn)練自己的模型必須用3.4.X版本的。
環(huán)境安裝
1、下載opencv安裝包【下載地址】
2、下載后選擇目錄安裝,提取文件到本地,檢查是否存在目錄。
前期準(zhǔn)備
1、正樣本數(shù)據(jù)圖片5張(image\positive\img);創(chuàng)建文件info.dat(image\positive)并編輯如下內(nèi)容。
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、負(fù)樣本數(shù)據(jù)圖片5張(image\negitive\img);創(chuàng)建bg.txt文件并編輯如下內(nèi)容。
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執(zhí)行,生成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同級(jí)目錄(opencv有這個(gè)bug,不能指定目錄,不然會(huì)產(chǎn)生報(bào)錯(cuò)),cmd執(zhí)行;
注意:numPos 不能為正樣本數(shù)量,只能小于實(shí)際數(shù)量。numNeg為負(fù)樣本數(shù)量,可以大于實(shí)際數(shù)量
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
執(zhí)行結(jié)果:
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、執(zhí)行完生成 cascade.xml
6、創(chuàng)建測(cè)試代碼使用,可行。
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); }
總結(jié)
本文只是學(xué)習(xí)如何訓(xùn)練自己模型,選用正本和反面數(shù)據(jù)較小,實(shí)際項(xiàng)目中需要選用大量得樣本數(shù)據(jù)圖片。
到此這篇關(guān)于SpringBoot使用OpenCV的文章就介紹到這了,更多相關(guān)SpringBoot使用OpenCV內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中將一個(gè)列表拆分為多個(gè)較小列表的三種不同方法
有時(shí)候我們需要將大集合按指定的數(shù)量分割成若干個(gè)小集合,這篇文章主要給大家介紹了關(guān)于Java中將一個(gè)列表拆分為多個(gè)較小列表的三種不同方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09Java程序圖形用戶界面設(shè)計(jì)之容器JFrame
圖形界面(簡(jiǎn)稱GUI)是指采用圖形方式顯示的計(jì)算機(jī)操作用戶界面。與早期計(jì)算機(jī)使用的命令行界面相比,圖形界面對(duì)于用戶來說在視覺上更易于接受,本篇精講Java語言中關(guān)于圖形用戶界面的基本容器JFrame2022-02-02java實(shí)現(xiàn)多線程交替打印兩個(gè)數(shù)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多線程交替打印兩個(gè)數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11詳解spring開發(fā)_JDBC操作MySQL數(shù)據(jù)庫
本篇文章主要介紹了spring開發(fā)_JDBC操作MySQL數(shù)據(jù)庫,具有一定的參考價(jià)值,有興趣的可以了解一下。2016-12-12Java獲取調(diào)用當(dāng)前方法的類名或方法名(棧堆信息)的四種方式舉例
在Java編程中我們經(jīng)常需要在運(yùn)行時(shí)獲取當(dāng)前執(zhí)行的方法名稱,這在日志記錄、性能監(jiān)控、調(diào)試等方面非常有用,這篇文章主要給大家介紹了關(guān)于Java獲取調(diào)用當(dāng)前方法的類名或方法名(棧堆信息)的四種方式,需要的朋友可以參考下2024-09-09springboot2.2.2集成dubbo的實(shí)現(xiàn)方法
這篇文章主要介紹了springboot2.2.2集成dubbo的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01