使用yolo11训练火、烟雾 目标检测

📅 2026/8/22 1:40:06
使用yolo11训练火、烟雾 目标检测
平台使用 Kaggle GPU T4 × 2数据集Checking your browser - reCAPTCHA训练命令pip install -U ultralytics !yolo train modelyolo11n.pt data/kaggle/input/datasets/cubeai/fire-and-smoke-detection-for-yolov8/data.yaml epochs30 imgsz640 batch128 device0,1训练输出Downloading https://github.com/ultralytics/assets/releases/download/v8.4.0/yolo11n.pt to yolo11n.pt: 100% ━━━━━━━━━━━━ 5.4MB 74.7MB/s 0.1s Ultralytics 8.4.124 Python-3.12.13 torch-2.10.0cu128 CUDA:0 (Tesla T4, 14912MiB) CUDA:1 (Tesla T4, 14912MiB) engine/trainer: agnostic_nmsFalse, ampTrue, angle1.0, augmentFalse, auto_augmentrandaugment, batch128, bgr0.0, box7.5, cacheFalse, cfgNone, channels_lastFalse, classesNone, close_mosaic10, cls0.5, cls_pw0.0, cls_remapTrue, compileFalse, confNone, copy_paste0.0, copy_paste_modeflip, cos_lrFalse, cutmix0.0, data/kaggle/input/datasets/cubeai/fire-and-smoke-detection-for-yolov8/data.yaml, degrees0.0, deterministicTrue, device0,1, dfl1.5, dgrad0.5, dis6.0, distill_modelNone, dlam1.0, dlog1.0, dnnFalse, dropout0.0, dynamicFalse, embedNone, end2endNone, epochs30, erasing0.4, exist_okFalse, fliplr0.5, flipud0.0, formattorchscript, fraction1.0, freezeNone, hsv_h0.015, hsv_s0.7, hsv_v0.4, imgsz640, iou0.7, kerasFalse, kobj1.0, line_widthNone, lr00.01, lrf0.01, mask_ratio4, max_det300, mixup0.0, modetrain, modelyolo11n.pt, momentum0.937, mosaic1.0, multi_scale0.0, nametrain, nbs64, nmsFalse, opsetNone, optimizeFalse, optimizerauto, overlap_maskTrue, patience100, perspective0.0, plotsTrue, pose12.0, pretrainedTrue, profileFalse, projectNone, quantizeNone, rectFalse, resumeFalse, retina_masksFalse, rle1.0, saveTrue, save_confFalse, save_cropFalse, save_dir/kaggle/working/runs/detect/train, save_framesFalse, save_jsonFalse, save_period-1, save_txtFalse, scale0.5, seed0, shear0.0, showFalse, show_boxesTrue, show_confTrue, show_labelsTrue, simplifyTrue, single_clsFalse, sourceNone, splitval, stream_bufferFalse, taskdetect, timeNone, trackertracktrack.yaml, translate0.1, valTrue, verboseTrue, vid_stride1, visualizeFalse, warmup_bias_lr0.1, warmup_epochs3.0, warmup_momentum0.8, weight_decay0.0005, workers8, workspaceNone Downloading https://ultralytics.com/assets/Arial.Unicode.ttf to /root/.config/Ultralytics/Arial.Unicode.ttf: 100% ━━━━━━━━━━━━ 22.2MB 105.6MB/s 0.2s0.2s0.0s Overriding model.yaml nc80 with nc2 from n params module arguments 0 -1 1 464 ultralytics.nn.modules.conv.Conv [3, 16, 3, 2] 1 -1 1 4672 ultralytics.nn.modules.conv.Conv [16, 32, 3, 2] 2 -1 1 6640 ultralytics.nn.modules.block.C3k2 [32, 64, 1, False, 0.25] 3 -1 1 36992 ultralytics.nn.modules.conv.Conv [64, 64, 3, 2] 4 -1 1 26080 ultralytics.nn.modules.block.C3k2 [64, 128, 1, False, 0.25] 5 -1 1 147712 ultralytics.nn.modules.conv.Conv [128, 128, 3, 2] 6 -1 1 87040 ultralytics.nn.modules.block.C3k2 [128, 128, 1, True] 7 -1 1 295424 ultralytics.nn.modules.conv.Conv [128, 256, 3, 2] 8 -1 1 346112 ultralytics.nn.modules.block.C3k2 [256, 256, 1, True] 9 -1 1 164608 ultralytics.nn.modules.block.SPPF [256, 256, 5] 10 -1 1 249728 ultralytics.nn.modules.block.C2PSA [256, 256, 1] 11 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, nearest] 12 [-1, 6] 1 0 ultralytics.nn.modules.conv.Concat [1] 13 -1 1 111296 ultralytics.nn.modules.block.C3k2 [384, 128, 1, False] 14 -1 1 0 torch.nn.modules.upsampling.Upsample [None, 2, nearest] 15 [-1, 4] 1 0 ultralytics.nn.modules.conv.Concat [1] 16 -1 1 32096 ultralytics.nn.modules.block.C3k2 [256, 64, 1, False] 17 -1 1 36992 ultralytics.nn.modules.conv.Conv [64, 64, 3, 2] 18 [-1, 13] 1 0 ultralytics.nn.modules.conv.Concat [1] 19 -1 1 86720 ultralytics.nn.modules.block.C3k2 [192, 128, 1, False] 20 -1 1 147712 ultralytics.nn.modules.conv.Conv [128, 128, 3, 2] 21 [-1, 10] 1 0 ultralytics.nn.modules.conv.Concat [1] 22 -1 1 378880 ultralytics.nn.modules.block.C3k2 [384, 256, 1, True] 23 [16, 19, 22] 1 431062 ultralytics.nn.modules.head.Detect [2, 16, None, [64, 128, 256]] YOLO11n summary: 182 layers, 2,590,230 parameters, 2,590,214 gradients, 6.5 GFLOPs Transferred 448/499 items from pretrained weights DDP: debug command /usr/bin/python3 -m torch.distributed.run --nproc_per_node 2 --master_port 24764 /root/.config/Ultralytics/DDP/_temp_bxrzb17_138672449512096.py Ultralytics 8.4.124 Python-3.12.13 torch-2.10.0cu128 CUDA:0 (Tesla T4, 14912MiB) CUDA:1 (Tesla T4, 14912MiB) Overriding model.yaml nc80 with nc2 Transferred 448/499 items from pretrained weights Freezing layer model.23.dfl.conv.weight AMP: running Automatic Mixed Precision (AMP) checks... Downloading https://github.com/ultralytics/assets/releases/download/v8.4.0/yolo26n.pt to yolo26n.pt: 100% ━━━━━━━━━━━━ 5.3MB 69.7MB/s 0.1s AMP: checks passed ✅ WARNING ⚠️ train: Slow image access detected (ping: 0.7±0.4 ms, read: 11.9±7.4 MB/s, size: 94.5 KB). Use local storage instead of remote/mounted storage for better performance. See https://docs.ultralytics.com/guides/model-training-tips/ train: Scanning /kaggle/input/datasets/cubeai/fire-and-smoke-detection-for-yolov8/train/labels... 7000 images, 0 backgrounds, 0 corrupt: 100% ━━━━━━━━━━━━ 7000/7000 198.9it/s 35.2s0.1ss WARNING ⚠️ train: Cache directory /kaggle/input/datasets/cubeai/fire-and-smoke-detection-for-yolov8/train is not writable, cache not saved. WARNING ⚠️ Box and segment counts should be equal, but got len(segments) 1, len(boxes) 15190. To resolve this only boxes will be used and all segments will be removed. To avoid this please supply either a detect or segment dataset, not a detect-segment mixed dataset. albumentations: Blur(p0.01, blur_limit(3, 7)), MedianBlur(p0.01, blur_limit(3, 7)), ToGray(p0.01, methodweighted_average, num_output_channels3), CLAHE(p0.01, clip_limit(1.0, 4.0), tile_grid_size(8, 8)) WARNING ⚠️ val: Slow image access detected (ping: 0.0±0.0 ms, read: 10.9±9.0 MB/s, size: 66.8 KB). Use local storage instead of remote/mounted storage for better performance. See https://docs.ultralytics.com/guides/model-training-tips/ val: Scanning /kaggle/input/datasets/cubeai/fire-and-smoke-detection-for-yolov8/valid/labels... 2000 images, 0 backgrounds, 0 corrupt: 100% ━━━━━━━━━━━━ 2000/2000 189.6it/s 10.6s0.1s WARNING ⚠️ val: Cache directory /kaggle/input/datasets/cubeai/fire-and-smoke-detection-for-yolov8/valid is not writable, cache not saved. WARNING ⚠️ Box and segment counts should be equal, but got len(segments) 1, len(boxes) 4312. To resolve this only boxes will be used and all segments will be removed. To avoid this please supply either a detect or segment dataset, not a detect-segment mixed dataset. optimizer: optimizerauto found, ignoring lr00.01 and momentum0.937 and determining best optimizer, lr0 and momentum automatically... optimizer: AdamW(lr0.001667, momentum0.9) with parameter groups 81 weight(decay0.0), 88 weight(decay0.001), 87 bias(decay0.0) Plotting labels to /kaggle/working/runs/detect/train/labels.jpg... Image sizes 640 train, 640 val Using 4 dataloader workers Logging results to /kaggle/working/runs/detect/train Starting training for 30 epochs... Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size Downloading https://ultralytics.com/assets/Arial.ttf to /root/.config/Ultralytics/Arial.ttf: 100% ━━━━━━━━━━━━ 755.1KB 10.4MB/s 0.1s 1/30 9.04G 1.902 2.981 1.764 147 640: 100% ━━━━━━━━━━━━ 55/55 1.4s/it 1:151.3sss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.6s/it 12.5s1.2s all 2000 4312 0.713 0.0565 0.0879 0.0297 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 2/30 8.33G 1.82 2.203 1.668 160 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.6s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.6s/it 12.6s1.8s all 2000 4312 0.161 0.118 0.0925 0.0309 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 3/30 8.24G 1.849 2.011 1.705 154 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.7s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 11.6s1.4s all 2000 4312 0.242 0.105 0.0503 0.0162 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 4/30 8.23G 1.847 1.886 1.694 123 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.8s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 12.1s1.8s all 2000 4312 0.337 0.277 0.223 0.0872 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 5/30 8.26G 1.793 1.785 1.669 172 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.8s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.4s1.5s all 2000 4312 0.31 0.231 0.181 0.075 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 6/30 8.17G 1.755 1.702 1.64 161 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.2s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 11.7s1.7s all 2000 4312 0.621 0.214 0.235 0.105 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 7/30 8.22G 1.74 1.626 1.61 149 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.0s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 12.2s1.7s all 2000 4312 0.373 0.316 0.294 0.129 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 8/30 8.17G 1.71 1.588 1.59 144 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 47.0s0.8ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 11.9s1.5s all 2000 4312 0.506 0.344 0.358 0.15 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 9/30 8.16G 1.692 1.562 1.595 149 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.9s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.6s/it 12.5s1.8s all 2000 4312 0.565 0.336 0.357 0.164 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 10/30 8.22G 1.684 1.51 1.576 138 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.0s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 12.0s1.6s all 2000 4312 0.585 0.447 0.477 0.218 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 11/30 8.25G 1.652 1.476 1.55 142 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.0s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 12.1s1.7s all 2000 4312 0.5 0.415 0.423 0.197 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 12/30 8.17G 1.634 1.439 1.548 159 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.1s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 11.9s1.7s all 2000 4312 0.544 0.397 0.43 0.199 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 13/30 8.25G 1.61 1.4 1.516 158 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.1s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 11.9s1.7s all 2000 4312 0.615 0.468 0.521 0.253 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 14/30 8.16G 1.601 1.37 1.523 112 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.9s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 12.2s1.7s all 2000 4312 0.613 0.455 0.508 0.251 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 15/30 8.16G 1.586 1.355 1.512 128 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.8s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.6s/it 13.0s1.9s all 2000 4312 0.593 0.489 0.522 0.259 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 16/30 8.2G 1.557 1.286 1.476 143 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 46.1s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 11.7s1.6s all 2000 4312 0.599 0.496 0.524 0.26 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 17/30 8.23G 1.536 1.286 1.471 194 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.8s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 11.8s1.6s all 2000 4312 0.636 0.505 0.549 0.284 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 18/30 8.17G 1.554 1.27 1.467 159 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.9s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.6s1.7s all 2000 4312 0.606 0.501 0.536 0.269 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 19/30 8.17G 1.51 1.253 1.449 159 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.7s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 12.4s1.7s all 2000 4312 0.658 0.515 0.562 0.29 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 20/30 8.28G 1.488 1.206 1.438 149 640: 100% ━━━━━━━━━━━━ 55/55 1.2it/s 45.8s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 12.3s1.8s all 2000 4312 0.693 0.5 0.572 0.299 Closing dataloader mosaic albumentations: Blur(p0.01, blur_limit(3, 7)), MedianBlur(p0.01, blur_limit(3, 7)), ToGray(p0.01, methodweighted_average, num_output_channels3), CLAHE(p0.01, clip_limit(1.0, 4.0), tile_grid_size(8, 8)) Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 21/30 8.16G 1.508 1.132 1.462 67 640: 100% ━━━━━━━━━━━━ 55/55 1.1it/s 49.1s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.3s/it 10.7s.3ss all 2000 4312 0.64 0.543 0.588 0.301 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 22/30 8.14G 1.48 1.086 1.448 68 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 42.2s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.1s1.4s all 2000 4312 0.666 0.543 0.595 0.313 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 23/30 8.2G 1.464 1.072 1.443 81 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 42.1s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.0s.2ss all 2000 4312 0.692 0.556 0.626 0.333 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 24/30 8.14G 1.431 1.017 1.416 78 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 42.3s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.4s1.5s all 2000 4312 0.724 0.57 0.644 0.35 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 25/30 8.16G 1.424 1.002 1.403 97 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 42.6s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.2s1.4s all 2000 4312 0.725 0.593 0.664 0.356 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 26/30 8.16G 1.405 0.9725 1.39 87 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 42.5s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.4s1.5s all 2000 4312 0.724 0.606 0.666 0.366 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 27/30 8.16G 1.373 0.9394 1.374 86 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 41.9s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.0s1.5s all 2000 4312 0.727 0.593 0.661 0.36 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 28/30 8.16G 1.353 0.9077 1.354 90 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 41.6s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.5s/it 11.6s1.5s all 2000 4312 0.755 0.611 0.685 0.385 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 29/30 8.16G 1.324 0.861 1.333 88 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 41.4s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.3s1.4s all 2000 4312 0.752 0.614 0.693 0.39 Epoch GPU_mem box_loss cls_loss dfl_loss Instances Size 30/30 8.16G 1.295 0.8484 1.315 90 640: 100% ━━━━━━━━━━━━ 55/55 1.3it/s 41.9s0.7ss Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 10.9s1.4s all 2000 4312 0.773 0.631 0.704 0.398 30 epochs completed in 0.498 hours. Optimizer stripped from /kaggle/working/runs/detect/train/weights/last.pt, 5.5MB Optimizer stripped from /kaggle/working/runs/detect/train/weights/best.pt, 5.5MB Validating /kaggle/working/runs/detect/train/weights/best.pt... YOLO11n summary (fused): 101 layers, 2,582,542 parameters, 0 gradients, 6.4 GFLOPs Class Images Instances Box(P R mAP50 mAP50-95): 100% ━━━━━━━━━━━━ 8/8 1.4s/it 11.5s1.4s all 2000 4312 0.772 0.632 0.705 0.398 火 1895 3627 0.83 0.748 0.815 0.491 烟 462 685 0.715 0.516 0.595 0.304 Speed: 0.1ms preprocess, 1.3ms inference, 0.0ms loss, 1.7ms postprocess per image Results saved to /kaggle/working/runs/detect/train Learn more at https://docs.ultralytics.com/modes/train下载结果和训练好的模型from IPython.display import display, FileLinks display(FileLinks(./))模型使用OK那就实际用用看看效果吧这是用 Streamlit 搭建的一个简易平台import tempfile from pathlib import Path import cv2 import pandas as pd import streamlit as st from PIL import Image from ultralytics import YOLO st.set_page_config( page_titleYOLO11 目标检测平台, page_icon, layoutwide, ) WEIGHTS_DIR Path(__file__).resolve().parent.parent / weights st.cache_resource def load_model(weight_path: str) - YOLO: return YOLO(weight_path) def list_models() - list[str]: if not WEIGHTS_DIR.exists(): return [] return sorted(p.name for p in WEIGHTS_DIR.iterdir() if p.suffix .pt) def draw_results(frame, results, conf: float) - tuple[cv2.Mat, pd.DataFrame]: annotated results[0].plot(line_width2) rows [] for box in results[0].boxes: cls_id int(box.cls[0]) name results[0].names[cls_id] conf_val float(box.conf[0]) x1, y1, x2, y2 (float(v) for v in box.xyxy[0]) rows.append({类别: name, 置信度: round(conf_val, 4), 左上角(x,y): (round(x1, 1), round(y1, 1)), 右下角(x,y): (round(x2, 1), round(y2, 1))}) return annotated, pd.DataFrame(rows) def process_image(model, img, conf: float, iou: float, imgsz: int, device: str): results model.predict(img, confconf, iouiou, imgszimgsz, devicedevice, verboseFalse) annotated, df draw_results(img, results, conf) return annotated, df def process_video(model, video_path, conf: float, iou: float, imgsz: int, device: str, progress_bar, status_text): cap cv2.VideoCapture(video_path) fps cap.get(cv2.CAP_PROP_FPS) or 25 width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) total int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) or 1 tmp_out tempfile.NamedTemporaryFile(suffix.mp4, deleteFalse) writer cv2.VideoWriter(tmp_out.name, cv2.VideoWriter_fourcc(*mp4v), fps, (width, height)) idx 0 while True: ok, frame cap.read() if not ok: break results model.predict(frame, confconf, iouiou, imgszimgsz, devicedevice, verboseFalse) writer.write(results[0].plot(line_width2)) idx 1 progress_bar.progress(idx / total) status_text.write(f处理中{idx}/{total} 帧) cap.release() writer.release() return tmp_out.name def main(): st.title( YOLO11 目标检测平台) st.caption(基于 Ultralytics Streamlit 的简易目标检测演示) with st.sidebar: st.header(⚙️ 模型与参数) models list_models() if not models: st.error(f未在 weights 目录找到模型文件{WEIGHTS_DIR}) st.stop() model_name st.selectbox(选择模型, models) model_path str(WEIGHTS_DIR / model_name) conf st.slider(置信度阈值, 0.05, 1.0, 0.25, 0.05) iou st.slider(IoU 阈值 (NMS), 0.05, 1.0, 0.45, 0.05) imgsz st.selectbox(推理尺寸, [320, 416, 512, 640, 800, 1024], index3) device st.selectbox(设备, [auto, cpu, cuda:0]) st.divider() st.caption(f模型{model_name}{model_path}) st.caption(提示将更多 .pt 权重放入 weights 目录即可自动出现在下拉框中。) if st.session_state.get(yolo_model_path) ! model_path: with st.spinner(f正在加载模型 {model_name} ...): model load_model(model_path) st.session_state.yolo_model model st.session_state.yolo_model_path model_path model st.session_state.yolo_model tab_img, tab_video, tab_cam st.tabs([ 图片检测, 视频检测, 摄像头实时检测]) with tab_img: st.subheader(图片目标检测) source st.radio(图片来源, [上传图片, 示例图片], horizontalTrue) uploaded None if source 上传图片: uploaded st.file_uploader(选择一张图片, type[jpg, jpeg, png, bmp, webp]) if uploaded is not None: img Image.open(uploaded).convert(RGB) st.image(img, caption原图, use_container_widthTrue) if st.button(开始检测, typeprimary, keybtn_img): with st.spinner(检测中...): annotated, df process_image(model, img, conf, iou, imgsz, device) col1, col2 st.columns(2) with col1: st.image(annotated, caption检测结果, use_container_widthTrue) st.download_button(下载检测结果, datacv2.imencode(.jpg, annotated)[1].tobytes(), file_nameyolo_result.jpg, mimeimage/jpeg) with col2: if not df.empty: st.success(f共检测到 **{len(df)}** 个目标) st.dataframe(df, use_container_widthTrue) else: st.warning(未检测到任何目标) else: st.info(选择一张示例图片或上传图片进行检测。) with tab_video: st.subheader(视频目标检测) uploaded_video st.file_uploader(选择视频文件, type[mp4, avi, mov, mkv]) if uploaded_video is not None: tmp_video tempfile.NamedTemporaryFile(suffixPath(uploaded_video.name).suffix, deleteFalse) tmp_video.write(uploaded_video.read()) tmp_video.close() st.video(tmp_video.name) if st.button(开始检测, typeprimary, keybtn_video): progress_bar st.progress(0) status_text st.empty() with st.spinner(视频处理中...): out_path process_video(model, tmp_video.name, conf, iou, imgsz, device, progress_bar, status_text) status_text.write(处理完成 ✅) st.video(out_path) with open(out_path, rb) as f: st.download_button(下载检测结果视频, dataf.read(), file_nameyolo_result.mp4, mimevideo/mp4) with tab_cam: st.subheader(摄像头实时检测) st.caption(使用 OpenCV 读取摄像头点击按钮单帧检测。) if st.button(从摄像头抓取一帧并检测, typeprimary): cap cv2.VideoCapture(0) if not cap.isOpened(): st.error(无法打开摄像头) else: ok, frame cap.read() cap.release() if ok: with st.spinner(检测中...): annotated, df process_image(model, frame, conf, iou, imgsz, device) st.image(annotated, caption摄像头检测结果, use_container_widthTrue) if not df.empty: st.dataframe(df, use_container_widthTrue) else: st.error(摄像头读取失败) if __name__ __main__: main()