很多刚接触计算机视觉的同学都有个误区“YOLO只能用Python跑”其实Java调用YOLO模型的流程远比想象中简单——不用复杂的工程化配置不用懂底层原理跟着这篇教程走10分钟就能完成从模型转换到Java调用的全流程新手也能一次跑通。本文全程聚焦“最小可行方案”剔除所有冗余的工业级配置只保留核心步骤模型转换1分钟→ 环境准备2分钟→ 代码编写4分钟→ 测试验证1分钟→ 避坑指南2分钟真正做到“10分钟上手”。一、前置认知Java调用YOLO的核心逻辑先花1分钟搞懂核心原理避免盲目敲代码YOLO官方提供的是Python版本的模型.pt格式Java无法直接识别所以核心流程是YOLO .pt模型 → 转换为ONNX格式 → Java通过ONNX Runtime调用ONNX模型 → 解析检测结果整个过程就3个核心角色ONNX模型通用的模型格式跨语言兼容ONNX Runtime JavaJava端的推理引擎负责执行ONNX模型OpenCV Java负责图片预处理缩放、归一化。二、第一步模型转换1分钟这一步用Python完成Python做模型转换效率最高没必要用Java硬刚新手直接复制命令即可1. 安装依赖pipinstallultralytics2. 转换YOLO模型为ONNX新建convert_yolo2onnx.py文件复制以下代码以YOLOv8为例新手用轻量化的yolov8n.pt即可# convert_yolo2onnx.pyfromultralyticsimportYOLO# 加载官方预训练的YOLOv8n模型轻量化适合新手测试modelYOLO(yolov8n.pt)# 导出为ONNX格式动态批次新手不用改参数model.export(formatonnx,dynamicTrue,imgsz640)3. 执行转换python convert_yolo2onnx.py执行完成后会在当前目录生成yolov8n.onnx文件——这就是Java能识别的模型文件把它保存好后续要放到Java项目里。三、第二步Java环境准备2分钟1. 新建Maven项目打开IDEA/Eclipse新建一个普通Maven项目无需SpringBoot纯Java项目即可新手先跑通核心逻辑再扩展框架。2. 配置pom.xml依赖复制以下依赖到pom.xml核心只需要3个ONNX Runtime、OpenCV、SLF4J日志可选?xml version1.0 encodingUTF-8?projectxmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.example/groupIdartifactIdjava-yolo-demo/artifactIdversion1.0-SNAPSHOT/versiondependencies!-- ONNX Runtime Java核心推理引擎 --dependencygroupIdcom.microsoft.onnxruntime/groupIdartifactIdonnxruntime/artifactIdversion1.15.1/version/dependency!-- OpenCV Java图片预处理 --dependencygroupIdorg.openpnp/groupIdartifactIdopencv/artifactIdversion4.7.0-0/version/dependency!-- 日志可选方便看输出 --dependencygroupIdorg.slf4j/groupIdartifactIdslf4j-simple/artifactIdversion2.0.7/version/dependency/dependenciesbuildplugins!-- Java版本指定新手用1.8即可 --plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.8.1/versionconfigurationsource8/sourcetarget8/target/configuration/plugin/plugins/build/project刷新Maven依赖等待下载完成如果下载慢可换阿里云镜像。3. 放置模型文件在Java项目的src/main/resources目录下新建model文件夹把第一步生成的yolov8n.onnx放进去。四、第三步核心代码编写4分钟新建YoloJavaDemo.java文件复制以下完整代码注释写满新手能看懂每一步importai.onnxruntime.*;importorg.opencv.core.*;importorg.opencv.imgcodecs.Imgcodecs;importorg.opencv.imgproc.Imgproc;importjava.nio.FloatBuffer;importjava.util.*;/** * Java调用YOLOv8核心代码 * 新手直接复制只需修改图片路径即可运行 */publicclassYoloJavaDemo{// YOLO核心参数新手不用改privatestaticfinalintINPUT_SIZE640;// 输入图片尺寸privatestaticfinalfloatCONF_THRESHOLD0.5f;// 置信度阈值只保留50%的检测结果privatestaticfinalfloatNMS_THRESHOLD0.45f;// 非极大值抑制阈值// COCO类别YOLOv8默认检测80类新手不用改privatestaticfinalListStringCLASS_NAMESArrays.asList(person,bicycle,car,motorcycle,airplane,bus,train,truck,boat,traffic light,fire hydrant,stop sign,parking meter,bench,bird,cat,dog,horse,sheep,cow,elephant,bear,zebra,giraffe,backpack,handbag,umbrella,tie,suitcase,frisbee,skis,snowboard,sports ball,kite,baseball bat,baseball glove,skateboard,surfboard,tennis racket,bottle,wine glass,cup,fork,knife,spoon,bowl,banana,apple,sandwich,orange,broccoli,carrot,hot dog,pizza,donut,cake,chair,couch,potted plant,bed,dining table,toilet,tv,laptop,mouse,remote,keyboard,cell phone,microwave,oven,toaster,sink,refrigerator,book,clock,vase,scissors,teddy bear,hair drier,toothbrush);publicstaticvoidmain(String[]args){// 1. 初始化加载OpenCV和ONNX模型try{// 加载OpenCV原生库System.loadLibrary(Core.NATIVE_LIBRARY_NAME);// 初始化ONNX环境OrtEnvironmentenvOrtEnvironment.getEnvironment();OrtSession.SessionOptionsoptionsnewOrtSession.SessionOptions();// 加载模型路径对应resources/model/yolov8n.onnxStringmodelPathYoloJavaDemo.class.getClassLoader().getResource(model/yolov8n.onnx).getPath();OrtSessionsessionenv.createSession(modelPath,options);System.out.println(模型加载成功);// 2. 加载测试图片新手修改这里的图片路径StringimgPathtest.jpg;// 替换为你的测试图片路径如D:/test.jpgMatsrcMatImgcodecs.imread(imgPath);if(srcMat.empty()){System.out.println(图片加载失败请检查路径);return;}// 3. 图片预处理YOLO要求的格式MatresizedMatnewMat();// 缩放图片到640x640Imgproc.resize(srcMat,resizedMat,newSize(INPUT_SIZE,INPUT_SIZE));// 归一化0-255 → 0-1resizedMat.convertTo(resizedMat,CvType.CV_32FC3,1.0/255.0);// 转置HWC高宽通道→ CHW通道高宽YOLO要求的输入格式float[]inputDatatransposeMat(resizedMat);// 4. 构造ONNX输入long[]inputShape{1,3,INPUT_SIZE,INPUT_SIZE};// batch1, 3通道, 640x640OrtTensorinputTensorOrtTensor.createTensor(env,FloatBuffer.wrap(inputData),inputShape);MapString,OrtTensorinputsnewHashMap();inputs.put(images,inputTensor);// 输入名称要和ONNX模型一致YOLOv8默认是images// 5. 执行推理longstartTimeSystem.currentTimeMillis();OrtSession.Resultresultsession.run(inputs);float[][]outputData((float[][])result.get(0).getValue());longcostTimeSystem.currentTimeMillis()-startTime;System.out.println(推理完成耗时costTimems);// 6. 解析检测结果ListDetectionResultresultspostProcess(outputData,srcMat.width(),srcMat.height());// 7. 打印结果新手重点看这里System.out.println(检测结果);for(DetectionResultdr:results){System.out.println(类别dr.className置信度String.format(%.2f,dr.confidence)位置xdr.x, ydr.y, 宽dr.width, 高dr.height);}// 8. 释放资源避免内存泄漏inputTensor.close();result.close();session.close();env.close();srcMat.release();resizedMat.release();}catch(Exceptione){e.printStackTrace();}}/** * 图片转置HWC → CHW */privatestaticfloat[]transposeMat(Matmat){float[]chwDatanewfloat[3*INPUT_SIZE*INPUT_SIZE];intidx0;for(intc0;c3;c){for(inth0;hINPUT_SIZE;h){for(intw0;wINPUT_SIZE;w){chwData[idx](float)mat.get(h,w)[c];}}}returnchwData;}/** * 后处理解析推理结果过滤低置信度NMS去重 */privatestaticListDetectionResultpostProcess(float[][]output,intsrcWidth,intsrcHeight){ListDetectionResultresultsnewArrayList();// YOLOv8输出格式[8400, 84] → 8400个检测框844个坐标80个类别float[][]boxesnewfloat[output.length][4];float[][]scoresnewfloat[output.length][CLASS_NAMES.size()];// 提取坐标和类别得分for(inti0;ioutput.length;i){boxes[i][0]output[i][0];// x1boxes[i][1]output[i][1];// y1boxes[i][2]output[i][2];// x2boxes[i][3]output[i][3];// y2System.arraycopy(output[i],4,scores[i],0,CLASS_NAMES.size());}// NMS非极大值抑制去掉重复的检测框MatOfFloatconfidencesnewMatOfFloat();MatOfIntindicesnewMatOfInt();MatOfRect2dbboxesnewMatOfRect2d();for(intcls0;clsCLASS_NAMES.size();cls){ListFloatconfListnewArrayList();ListRect2dboxListnewArrayList();// 过滤低置信度的框for(inti0;ioutput.length;i){floatscorescores[i][cls];if(scoreCONF_THRESHOLD){// 还原坐标到原始图片尺寸floatx1boxes[i][0]/INPUT_SIZE*srcWidth;floaty1boxes[i][1]/INPUT_SIZE*srcHeight;floatx2boxes[i][2]/INPUT_SIZE*srcWidth;floaty2boxes[i][3]/INPUT_SIZE*srcHeight;boxList.add(newRect2d(x1,y1,x2-x1,y2-y1));confList.add(score);}}// 执行NMSif(!boxList.isEmpty()){bboxes.fromList(boxList);confidences.fromList(confList);Imgproc.dnn.NMSBoxes(bboxes,confidences,CONF_THRESHOLD,NMS_THRESHOLD,indices);// 解析NMS结果int[]indicesArrindices.toArray();for(intidx:indicesArr){Rect2dboxboxList.get(idx);results.add(newDetectionResult(CLASS_NAMES.get(cls),confList.get(idx),box.x,box.y,box.width,box.height));}}}// 释放Mat资源confidences.release();indices.release();bboxes.release();returnresults;}/** * 检测结果实体类新手不用改 */staticclassDetectionResult{StringclassName;// 类别名称floatconfidence;// 置信度doublex;// 左上角x坐标doubley;// 左上角y坐标doublewidth;// 宽度doubleheight;// 高度publicDetectionResult(StringclassName,floatconfidence,doublex,doubley,doublewidth,doubleheight){this.classNameclassName;this.confidenceconfidence;this.xx;this.yy;this.widthwidth;this.heightheight;}}}五、第四步测试验证1分钟1. 准备测试图片找一张包含常见物体的图片如有人、车、杯子的图片重命名为test.jpg放到项目根目录或修改代码里的imgPath为绝对路径如D:/test.jpg。2. 运行代码直接运行YoloJavaDemo的main方法控制台会输出模型加载成功 推理完成耗时35ms 检测结果 类别person置信度0.98位置x120.5, y80.2, 宽60.3, 高180.1 类别cup置信度0.92位置x300.1, y200.8, 宽15.2, 高20.5看到这个输出说明Java调用YOLO模型成功了六、新手避坑指南2分钟图片加载失败检查图片路径是否正确绝对路径要用/如D:/test.jpg不要用\模型加载失败确认yolov8n.onnx放在resources/model目录下Maven项目要刷新资源OpenCV库加载失败如果报UnsatisfiedLinkError手动下载对应系统的OpenCV库放到项目根目录或指定库路径System.setProperty(java.library.path,你的OpenCV库路径);推理结果为空降低CONF_THRESHOLD如改为0.3可能是置信度阈值太高过滤了结果输入名称错误如果报No such input: images检查ONNX模型的输入名称YOLOv8默认是imagesYOLOv5是images或input。七、总结关键点回顾Java调用YOLO的核心是先将.pt模型转为ONNX格式再通过ONNX Runtime执行推理完整流程模型转换 → 环境准备 → 图片预处理 → 模型推理 → 结果解析新手只需按步骤复制代码、修改图片路径即可跑通新手避坑重点路径正确、OpenCV库加载、置信度阈值调整。这篇教程聚焦“最小可行方案”10分钟就能跑通核心流程。如果想进一步扩展如集成SpringBoot、做接口、工业级优化可以参考我之前的文章但新手先把这个基础流程跑通再逐步进阶。其实Java调用YOLO一点都不难核心是找对方法避开新手坑——希望这篇教程能帮你快速入门不用再局限于Python调用YOLO