微信公眾號:OpenCV學堂
關注獲取更多計算機視覺與深度學習知識
前言
OpenCV DNN人臉檢測
OpenCV4.8 Java SDK實現YOLOv5模型部署
https://gitee.com/opencv_ai/opencv_tutorial_data/tree/master/models
1x1xNx7[batchId, classId, confidence, left, top, right, bottom]
代碼實現與演示
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);
}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();
????????//?1x1xNx7
????????int?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?????????????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語言翻譯,容易了。



推薦閱讀
OpenCV4.8+YOLOv8對象檢測C++推理演示
ZXING+OpenCV打造開源條碼檢測應用
總結 | OpenCV4 Mat操作全接觸
三行代碼實現 TensorRT8.6 C++ 深度學習模型部署
實戰 | YOLOv8+OpenCV 實現DM碼定位檢測與解析
對象檢測邊界框損失 – 從IOU到ProbIOU
YOLOv8 OBB實現自定義旋轉對象檢測
初學者必看 | 學習深度學習的五個誤區
YOLOv8自定義數據集訓練實現安全帽檢測
