【移花接木】OpenCV4.8 For Java 深度學習 實時人臉檢測

學習《OpenCV應用開發:入門、進階與工程化實踐》一書,學會本文所有技能就這么簡單!
做真正的OpenCV開發者,從入門到入職,一步到位!

前言

我寫這篇文章之前,我搜索整個網絡文章跟問各種語言大模型,太可怕了,它們沒有一個正確的,但是都在給我一本正經的胡說八道。所以沒辦法,我只好自己研究一番,經過兩天的折騰終于搞定了OpenCV DNN部署YOLOv5、YOLOv8等各種模型。然后我特別想把這塊最關鍵的知識點給大家分享一下,所以寫了這篇文章,以Java語言完成OpenCV DNN的實時人臉檢測,同時解釋其中的關鍵知識點。

OpenCV DNN人臉檢測

各種博客上的很多Java人臉檢測的文章都還是基于級聯檢測器的,有的好像是我2017年前文章的代碼。后來我再也沒寫過Java,所以網上居然再也找不到Java版本的OpenCV DNN人臉檢測的文章跟代碼,各種博客上的代碼一看就早已落伍多時。這里使用最新版本的Java SDK和OpenCV4.8深度神經網絡模塊進行深度學習和人臉檢測的方法。關于JDK環境搭建與IDE安裝可以看這篇文章:
OpenCV4.8 Java SDK實現YOLOv5模型部署

OpenCV DNN官方提供的人臉檢測模型下載地址如下:

https://gitee.com/opencv_ai/opencv_tutorial_data/tree/master/models

輸入的數據格式如下:
在這里插入圖片描述

這是一個SSD的對象檢測模型輸出的格式為:

1x1xNx7
[batchId, classId, confidence, left, top, right, bottom]

代碼實現與演示

我給OpenCV DNN 人臉檢測的Java實現封裝成了一個類,客戶端只要兩行代碼即可調用執行,簡單方便,寫個Java的Main方法即可調用,實現人臉檢測,唯一需要的就是先加載OpenCV Java的DLL支持,然后就可以正常調用了。客戶端代碼如下:

public static void main(String[] args) {String model_file = "D:/projects/opencv_face_detector_uint8.pb";String pb_txt_file = "D:/projects/opencv_face_detector.pbtxt";System.load("D:/opencv-4.8.0/opencv/build/java/x64/opencv_java480.dll");System.out.println("start to read image...");Mat inputImage = Imgcodecs.imread("D:/images/mmc.png");JavaFaceDetection face_detector = new JavaFaceDetection(model_file, pb_txt_file, 0.5f);face_detector.infer_image(inputImage);HighGui.imshow("OpenCV Java 深度學習人臉檢測演示", inputImage);HighGui.waitKey(0);VideoCapture capture = new VideoCapture();capture.open(0);while(true) {Mat frame = new Mat();boolean ret = capture.read(frame);Core.flip(frame, frame, 1);if(ret) {face_detector.infer_image(frame);HighGui.imshow("OpenCV Java 深度學習人臉檢測演示", frame);int c = HighGui.waitKey(1);if (c == 27) {break;}}}HighGui.destroyAllWindows();System.exit(0);
}

封裝的Java版本深度學習人臉檢測類的代碼如下:

import com.sun.jna.Pointer;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.dnn.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.videoio.VideoCapture;public class JavaFaceDetection {public Net getNet() {return net;}public void setNet(Net net) {this.net = net;}private Net net;private float score_t = 0.5f;public JavaFaceDetection(String model_path, String pb_txt_file, float conf) {this.score_t = conf;this.net = Dnn.readNetFromTensorflow(model_path, pb_txt_file);}public void infer_image(Mat frame) {long stime = System.currentTimeMillis();// 推理Mat blob = Dnn.blobFromImage(frame, 1.0, new Size(300, 300), new Scalar(104.0, 177.0, 123.0), false, false);this.net.setInput(blob);Mat probs = this.net.forward();// 1x1xNx7int rows = probs.size(2);int cols = probs.size(3);float[] result = new Pointer(probs.dataAddr()).getFloatArray(0, rows*cols);probs.get(0, 0, result);Mat detectOut = new Mat(rows, cols, CvType.CV_32F);detectOut.put(0, 0, result);for (int row = 0; row < detectOut.rows(); row++) {float conf = (float)detectOut.get(row, 2)[0];if (conf > this.score_t) {float x1 = (float)(detectOut.get(row, 3)[0] * frame.cols());float y1 = (float)(detectOut.get(row, 4)[0] * frame.rows());float x2 = (float)(detectOut.get(row, 5)[0] * frame.cols());float y2 = (float)(detectOut.get(row, 6)[0] * frame.rows());Rect2d box = new Rect2d();box.x = x1;box.y = y1;box.width = x2 - x1;box.height = y2 - y1;Rect rect = new Rect((int) box.x, (int) box.y, (int) box.width, (int) box.height);Imgproc.rectangle(frame, rect, new Scalar(0,0, 255), 2, 8);Imgproc.putText(frame, String.format("%.2f", conf), new Point(rect.x, rect.y-5), Imgproc.FONT_HERSHEY_COMPLEX, 0.5, new Scalar(255, 0, 255), 1, 8);}}long end_time = System.currentTimeMillis();float fps = 1000.0f /  (end_time - stime);Imgproc.putText(frame, String.format("FPS: %.2f", fps), new Point(30, 30), Imgproc.FONT_HERSHEY_COMPLEX, 1.0, new Scalar(0, 0, 255), 2, 8);}
}

其中最關鍵的是如何把推理輸出得到四維Tensor張量 1x1xNx7 轉換為 一個2D的Mat對象,這個就是各種大語言模型胡編亂造的地方,其實只有用JNA通過JNI接口訪問本地C++地址獲取推理以后的浮點數數組,然后重新構建一個2D Mat對象即可。解決這個問題其它代碼基本是C++版本的Java語言翻譯,容易了。

檢測單張圖像
在這里插入圖片描述
視頻實時檢測-本人親測有效
在這里插入圖片描述
學習《OpenCV應用開發:入門、進階與工程化實踐》一書,學會本文所有技能就這么簡單!
做真正的OpenCV開發者,從入門到入職,一步到位!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/14345.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/14345.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/14345.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

速賣通測評揭秘:如何選擇安全的渠道操作

許多商家對測評存在誤解&#xff0c;認為只需進行幾次測評就能迅速打造爆款。實際上&#xff0c;測評是一個需要計劃和持久性的過程&#xff0c;以便讓平臺檢測到產品的受眾程度并提高產品的曝光和權重。 在進行測評時&#xff0c;安全是首要考慮的問題。平臺可以通過設備、網…

黑馬點評1——短信篇(基于session)

&#x1f308;hello&#xff0c;你好鴨&#xff0c;我是Ethan&#xff0c;一名不斷學習的碼農&#xff0c;很高興你能來閱讀。 ??目前博客主要更新Java系列、項目案例、計算機必學四件套等。 &#x1f3c3;人生之義&#xff0c;在于追求&#xff0c;不在成敗&#xff0c;勤通…

如何使用多種算法解決LeetCode第135題——分發糖果問題

?????? 歡迎來到我的博客。希望您能在這里找到既有價值又有趣的內容&#xff0c;和我一起探索、學習和成長。歡迎評論區暢所欲言、享受知識的樂趣&#xff01; 推薦&#xff1a;數據分析螺絲釘的首頁 格物致知 終身學習 期待您的關注 導航&#xff1a; LeetCode解鎖100…

WPF 的 style 定義 使用 繼承 復用

style 樣式 如何定義一個 style 樣式 <Button Content"樣式" Width"100" Height"50"><Button.Style><Style></Style></Button.Style></Button>擁有的屬性 targetType “” 針對什么類型生效setter 設置屬…

Ubuntu中 petalinux 安裝 移植linux --tftp/tftp-hpa服務的方法

Xilinx 文檔 PetaLinux 指南&#xff1a;如何創建 PetaLinux 環境 &#xff08;2019.1&#xff09; PetaLinux工具參考指南 PetaLinux安裝詳解(Xilinx , linux, zynq, zynqMP) petalinux 2020.1安裝教程 一、PetaLinux工具和庫安裝 PetaLinux 工具要求主機系統 /bin/sh 為“b…

18.網絡編程

網絡編程 又稱為Socket編程。 Java中網絡編程主要是以Java語言完成信息數據在網絡上的傳輸。 網絡 計算機網絡&#xff0c;指的是將不同地理位置的多臺計算機連接起來&#xff0c;可以實現信息共享和信息傳輸。 Java是Internet上的語言&#xff0c;提供了對網絡應用程序的…

筆記 | 《css權威指南》

網絡安全色 URL text-indent line-height & vertical-align 字體 font-weight 400 normal 700 bold background-attachment

SpringBoot項目集成JetCache緩存框架步驟

JetCache是阿里開源的基于java開發的緩存框架&#xff0c;支持多種緩存類型&#xff1a;本地緩存、分布式緩存、多級緩存。能夠滿足不同業務場景的緩存需求。 1.導入依賴 <!--jetcache緩存 --> <dependency><groupId>com.alicp.jetcache</groupId>&l…

【調試筆記-20240516-Windows-使用VS2019編譯edk2(上)】

調試筆記-系列文章目錄 調試筆記-20240516-Windows-使用VS2019編譯edk2&#xff08;上&#xff09; 文章目錄 調試筆記-系列文章目錄調試筆記-20240516-Windows-使用VS2019編譯edk2&#xff08;上&#xff09; 前言一、安裝開發工具1. 安裝 VS20192. 安裝 Python 3.103. 安裝 …

pdf加水印怎么加?3種添加水印方法分享

pdf加水印怎么加&#xff1f;PDF加水印不僅是為了保護文檔內容&#xff0c;確保信息的安全性和完整性&#xff0c;更是一種有效的版權保護措施。通過添加水印&#xff0c;您可以在文檔中嵌入公司名稱、日期、編號等信息&#xff0c;以明確文檔的歸屬權和使用限制。此外&#xf…

小而美:兩步完成從源碼到應用的極簡交付

作者&#xff1a;花三&#xff08;王俊&#xff09; Serverless 應用引擎 SAE 是阿里云推出的一款零代碼改造、極簡易用、自適應彈性的容器化應用托管平臺&#xff0c;面市以來為幾萬家企業客戶提供服務&#xff0c;運行穩定&#xff0c;廣受好評。 SAE 的出現解決了眾多企業…

Python庫之lxml的簡介、安裝、使用方法詳細攻略

Python庫之lxml的簡介、安裝、使用方法詳細攻略 簡介 lxml是一個用于處理XML和HTML文檔的Python庫&#xff0c;它提供了簡單易用的API來解析和生成這些文檔。lxml以其性能和易用性而受到廣泛歡迎&#xff0c;特別適合于需要處理大量數據或需要高性能解析的場景。 安裝 安裝…

運行時異常和編譯時異常的區別

Java中的異常被分為兩大類&#xff1a;編譯時異常和運行時異常。 都是RuntimeException類及其子類異常&#xff0c;如NullPointerException、IndexOutOfBoundsException。這些異常是不檢查異常&#xff0c;運行時異常的特點是Java編譯器不會檢查它&#xff0c;程序中可以選擇捕…

純代碼如何實現WordPress搜索包含評論內容?

WordPress自帶的搜索默認情況下是不包含評論內容的&#xff0c;不過有些WordPress網站評論內容比較多&#xff0c;而且也比較有用&#xff0c;所以想要讓用戶在搜索時也能夠同時搜索到評論內容&#xff0c;那么應該怎么做呢&#xff1f; 網絡上很多教程都是推薦安裝SearchWP插…

RK3588 Android13 預安裝自己的apk應用及把這個應用設置為默認桌面

1、cp -rf device/rockchip/rk3588/rk3588m_s/preinstall device/rockchip/rk3588/rk3588_t/ 2、給device/rockchip/rk3588/rk3588_t/preinstall/的存放app的文件夾改名為app-imms2&#xff0c;在app-imms2放入app-imms2.apk,編譯安卓源碼即可&#xff0c; 3、編譯完會在out/…

android sp指針的cast

sp<Base> b; sp<Derived> d; b static_cast<Base*>(d.get()); 對于c原生的智能指針&#xff0c;有static_pointer_cast之類的操作方法。可以看cppreference。

Spring Web MVC介紹及詳細教程

目錄 1.什么是Spring Web MVC&#xff1f; 1.1 MVC定義 1.2 Spring MVC與MVC關系 2.為什么要學習Spring MVC 3.項目創建 4.Spring MVC連接 4.1 RequestMapping 4.2 PostMapping和GetMapping 5.Spring MVC參數獲取 5.1 獲取單個參數 5.2 獲取多個參數 5.3 獲取普通對…

通用代碼生成器應用場景一,項目前期

通用代碼生成器是一種自動化編程軟件&#xff0c;是一種先進的編譯系統。它具有表級抽象。把系統抽象為域對象&#xff0c;枚舉&#xff0c;彈性登錄模塊&#xff0c;復雜版面和圖形報表。使用通用代碼生成器完成項目前期&#xff0c;比直接使用對應的高級語言快的多&#xff0…

element Notification 消息過多需要折疊

Notification 消息過多太長 希望能折疊 如圖下效果 element-plus 可以將dom 插入到具體的元素 結合css :nth-child 來控制樣式達到效果 element dom 只能插入到body中 所以無法使用:nth-child 1.Notification需要消息提示時設置class let eleNum 0 // 彈窗的序號 function…

vue+canvas實現逐字手寫效果

在pc端進行逐字手寫的功能。用戶可以在一個 inputCanvas 上書寫單個字&#xff0c;然后在特定時間后將這個字添加到 outputCanvas 上&#xff0c;形成一個逐字的手寫效果。用戶還可以保存整幅圖像或者撤銷上一個添加的字。 <template><div class"container"…