作物病害實(shí)例分割數(shù)據(jù)集:從標(biāo)注格式到Y(jié)OLOv8訓(xùn)練落地)
簡(jiǎn)介這份農(nóng)作物病害實(shí)例分割數(shù)據(jù)集面向農(nóng)業(yè)AI診斷、精準(zhǔn)農(nóng)業(yè)監(jiān)測(cè)及植物病理學(xué)交叉研究場(chǎng)景適合從事YOLO實(shí)例分割任務(wù)開(kāi)發(fā)與農(nóng)業(yè)圖像算法驗(yàn)證的工程師、科研人員及農(nóng)業(yè)院校師生使用。資源包共582個(gè)文件以290張jpg圖像與290個(gè)txt標(biāo)注文件為主體另含1個(gè)yaml配置和1個(gè)docx說(shuō)明文檔壓縮包約58.81MB標(biāo)注采用YOLO多邊形格式精確勾勒病害區(qū)域邊界。數(shù)據(jù)集總計(jì)290張圖片按訓(xùn)練集258張、驗(yàn)證集23張、測(cè)試集9張劃分覆蓋細(xì)菌性枯萎病、褐條病與花葉病三類(lèi)典型病害兼顧細(xì)菌性與病毒性樣本類(lèi)別代表性較強(qiáng)。已有89人學(xué)習(xí)關(guān)注。讀者可借助其直接開(kāi)展實(shí)例分割模型訓(xùn)練與部署用于病害區(qū)域自動(dòng)識(shí)別、早期診斷系統(tǒng)搭建及農(nóng)業(yè)物聯(lián)網(wǎng)實(shí)時(shí)監(jiān)測(cè)也可作為教學(xué)與科研中的標(biāo)注范例和實(shí)驗(yàn)基線降低數(shù)據(jù)采集與標(biāo)注成本。1. 農(nóng)作物病害實(shí)例分割數(shù)據(jù)集從標(biāo)注格式到 YOLOv8 訓(xùn)練落地的完整路徑拿到一個(gè)名為農(nóng)作物病害實(shí)例分割數(shù)據(jù)集_20251117_001317.zip的壓縮包第一反應(yīng)不應(yīng)該是直接解壓丟進(jìn)模型而是先搞清楚它到底以什么格式標(biāo)注、類(lèi)別怎么定義、掩碼是多邊形還是 RLE。農(nóng)作物病害識(shí)別這件事分類(lèi)模型只能告訴你「這片葉子有病」目標(biāo)檢測(cè)能框出病斑位置但只有實(shí)例分割才能精確到每一個(gè)病斑的像素邊界——這在計(jì)算病害面積占比、評(píng)估嚴(yán)重程度、做精準(zhǔn)施藥決策時(shí)是剛需。這個(gè)數(shù)據(jù)集面向的就是這類(lèi)場(chǎng)景葉片上的多個(gè)獨(dú)立病斑需要被逐個(gè)分割出來(lái)而不是籠統(tǒng)地標(biāo)一個(gè)框。適合已經(jīng)跑通過(guò) YOLOv8 檢測(cè)任務(wù)、想往分割方向升級(jí)的工程師也適合農(nóng)業(yè) AI 方向需要快速驗(yàn)證實(shí)例分割方案可行性的團(tuán)隊(duì)。下面從數(shù)據(jù)集結(jié)構(gòu)拆解開(kāi)始一步步走到訓(xùn)練、評(píng)估和部署。2. 拆開(kāi)壓縮包農(nóng)作物病害實(shí)例分割數(shù)據(jù)集的目錄結(jié)構(gòu)與標(biāo)注格式判定2.1 先看目錄樹(shù)再?zèng)Q定怎么處理解壓之后別急著寫(xiě)訓(xùn)練腳本先花五分鐘把目錄結(jié)構(gòu)摸清楚。常見(jiàn)的實(shí)例分割數(shù)據(jù)集組織方式有兩種COCO 風(fēng)格的annotations/images/分離結(jié)構(gòu)以及 YOLO 風(fēng)格的images/labels/平行結(jié)構(gòu)。前者標(biāo)注文件是單個(gè) JSON后者是每張圖對(duì)應(yīng)一個(gè) TXT。# 先看壓縮包內(nèi)文件列表不解壓 unzip -l 農(nóng)作物病害實(shí)例分割數(shù)據(jù)集_20251117_001317.zip | head -50 # 解壓到指定目錄 mkdir -p ./agri_disease_seg unzip 農(nóng)作物病害實(shí)例分割數(shù)據(jù)集_20251117_001317.zip -d ./agri_disease_seg # 查看目錄樹(shù)只看兩層 find ./agri_disease_seg -maxdepth 2 -type d | sort邏輯說(shuō)明unzip -l先窺探內(nèi)容避免解壓出一堆無(wú)關(guān)文件。find -maxdepth 2控制輸出深度快速判斷是 COCO 還是 YOLO 結(jié)構(gòu)。如果看到annotations/instances.json就是 COCO 風(fēng)格如果看到labels/下全是.txt就是 YOLO 風(fēng)格。參數(shù)說(shuō)明-d指定解壓目標(biāo)目錄建議單獨(dú)建目錄避免污染當(dāng)前工作區(qū)。-maxdepth根據(jù)實(shí)際嵌套深度調(diào)整一般 2 到 3 層足夠判斷結(jié)構(gòu)。2.2 判定標(biāo)注格式多邊形、RLE 還是 YOLO 分割行實(shí)例分割的標(biāo)注格式直接決定后續(xù)轉(zhuǎn)換腳本怎么寫(xiě)。COCO 格式的segmentation字段可能是多邊形點(diǎn)列表[[x1,y1,x2,y2,...]]或 RLERun-Length Encoding。YOLO 分割格式則是每行class_id x1 y1 x2 y2 ...坐標(biāo)是歸一化后的多邊形點(diǎn)。import json import os # 如果是 COCO 格式檢查 segmentation 字段類(lèi)型 ann_path ./agri_disease_seg/annotations/instances.json if os.path.exists(ann_path): with open(ann_path, r) as f: coco json.load(f) # 看第一條標(biāo)注的 segmentation 類(lèi)型 seg coco[annotations][0][segmentation] if isinstance(seg, list): print(多邊形格式點(diǎn)數(shù), len(seg[0]) // 2) elif isinstance(seg, dict): print(RLE 格式size, seg.get(size)) # 統(tǒng)計(jì)類(lèi)別 for cat in coco[categories]: print(cat[id], cat[name]) else: # 檢查 YOLO 格式 label_dir ./agri_disease_seg/labels if os.path.exists(label_dir): sample os.listdir(label_dir)[0] with open(os.path.join(label_dir, sample)) as f: line f.readline().strip() parts line.split() print(類(lèi)別ID:, parts[0], 多邊形點(diǎn)數(shù):, (len(parts) - 1) // 2)邏輯說(shuō)明COCO 的segmentation如果是 list 就是多邊形每個(gè)子列表是一串x,y交替的點(diǎn)如果是 dict 就是 RLE需要pycocotools解碼。YOLO 格式直接讀一行就能判斷第一個(gè)數(shù)是類(lèi)別 ID后面全是歸一化坐標(biāo)。參數(shù)說(shuō)明len(seg[0]) // 2得到多邊形頂點(diǎn)數(shù)頂點(diǎn)太少比如少于 3 個(gè)說(shuō)明標(biāo)注質(zhì)量可能有問(wèn)題。類(lèi)別統(tǒng)計(jì)用來(lái)確認(rèn)病害種類(lèi)數(shù)量常見(jiàn)的有早疫病、晚疫病、葉斑病等。2.3 類(lèi)別分布與樣本均衡性檢查在動(dòng)手訓(xùn)練之前必須知道每個(gè)類(lèi)別有多少個(gè)實(shí)例。農(nóng)作物病害數(shù)據(jù)集經(jīng)常出現(xiàn)長(zhǎng)尾分布——健康葉片樣本多某種罕見(jiàn)病害只有幾十個(gè)實(shí)例。不查清楚就訓(xùn)練模型對(duì)少數(shù)類(lèi)基本沒(méi)反應(yīng)。from collections import Counter # 假設(shè)已加載 COCO 格式 cat_counter Counter() for ann in coco[annotations]: cat_counter[ann[category_id]] 1 id2name {c[id]: c[name] for c in coco[categories]} for cid, cnt in cat_counter.most_common(): print(f{id2name[cid]}: {cnt} 個(gè)實(shí)例) # 同時(shí)統(tǒng)計(jì)每張圖的實(shí)例數(shù)判斷是否有多病斑同圖的情況 img_ann_count Counter() for ann in coco[annotations]: img_ann_count[ann[image_id]] 1 multi sum(1 for v in img_ann_count.values() if v 1) print(f含多個(gè)病斑的圖像數(shù): {multi} / {len(coco[images])})邏輯說(shuō)明Counter統(tǒng)計(jì)每個(gè)類(lèi)別的實(shí)例總數(shù)most_common()按數(shù)量降序排列。第二個(gè)統(tǒng)計(jì)看有多少?gòu)垐D包含多個(gè)病斑——這個(gè)比例高說(shuō)明實(shí)例分割確實(shí)有必要檢測(cè)框會(huì)重疊。參數(shù)說(shuō)明如果某個(gè)類(lèi)別實(shí)例數(shù)少于 100訓(xùn)練時(shí)需要過(guò)采樣或加類(lèi)別權(quán)重。多病斑圖像占比超過(guò) 30% 就值得做實(shí)例分割而不是檢測(cè)。3. 從 COCO 到 YOLO 分割格式轉(zhuǎn)換腳本與四個(gè)邊界坑3.1 轉(zhuǎn)換腳本多邊形坐標(biāo)歸一化與類(lèi)別重映射YOLOv8 的分割訓(xùn)練需要 YOLO 格式的標(biāo)注每張圖一個(gè) TXT每行class_id x1 y1 x2 y2 ...坐標(biāo)是相對(duì)于圖像寬高的歸一化值。COCO 的多邊形坐標(biāo)是絕對(duì)像素值需要除以寬高。import json import os from PIL import Image def coco_to_yolo_seg(coco_json, image_dir, output_label_dir): with open(coco_json, r) as f: coco json.load(f) # 建立 image_id - (file_name, width, height) 映射 img_info {} for img in coco[images]: img_info[img[id]] (img[file_name], img[width], img[height]) # 類(lèi)別 ID 重映射為 0 起始連續(xù)整數(shù) cat_ids sorted([c[id] for c in coco[categories]]) cat_id_map {old: new for new, old in enumerate(cat_ids)} # 按 image_id 聚合標(biāo)注 from collections import defaultdict img_anns defaultdict(list) for ann in coco[annotations]: img_anns[ann[image_id]].append(ann) os.makedirs(output_label_dir, exist_okTrue) for img_id, anns in img_anns.items(): fname, w, h img_info[img_id] label_name os.path.splitext(fname)[0] .txt lines [] for ann in anns: seg ann[segmentation] if not isinstance(seg, list): continue # 跳過(guò) RLE需要單獨(dú)處理 cls_id cat_id_map[ann[category_id]] for poly in seg: # 歸一化并保留 6 位小數(shù) coords [] for i in range(0, len(poly), 2): x min(max(poly[i] / w, 0.0), 1.0) y min(max(poly[i1] / h, 0.0), 1.0) coords.append(f{x:.6f}) coords.append(f{y:.6f}) if len(coords) 6: # 至少 3 個(gè)點(diǎn) lines.append(f{cls_id} .join(coords)) with open(os.path.join(output_label_dir, label_name), w) as f: f.write(\n.join(lines)) print(f轉(zhuǎn)換完成類(lèi)別映射: {cat_id_map}) coco_to_yolo_seg( ./agri_disease_seg/annotations/instances.json, ./agri_disease_seg/images, ./agri_disease_seg/labels )邏輯說(shuō)明先建立圖像 ID 到文件名和尺寸的映射再把類(lèi)別 ID 重映射為從 0 開(kāi)始的連續(xù)整數(shù)——YOLO 要求類(lèi)別 ID 必須連續(xù)。按圖像聚合標(biāo)注后逐條轉(zhuǎn)換坐標(biāo)裁剪到[0,1]防止越界。參數(shù)說(shuō)明:.6f保留 6 位小數(shù)精度足夠且文件不會(huì)太大。len(coords) 6確保至少 3 個(gè)點(diǎn)退化的多邊形直接丟棄。如果遇到 RLE 格式的segmentation需要用pycocotools的annToMask轉(zhuǎn)成二值掩碼再提取輪廓。3.2 坑一坐標(biāo)越界與退化多邊形現(xiàn)象轉(zhuǎn)換后的 TXT 里有坐標(biāo)小于 0 或大于 1訓(xùn)練時(shí)報(bào)NaN loss或直接崩潰。原因COCO 標(biāo)注中偶爾有多邊形頂點(diǎn)超出圖像邊界或者標(biāo)注工具導(dǎo)出的坐標(biāo)有浮點(diǎn)誤差。解決轉(zhuǎn)換時(shí)強(qiáng)制裁剪到[0,1]如上面腳本中的min(max(...))。同時(shí)過(guò)濾掉面積過(guò)小的多邊形——計(jì)算多邊形面積小于圖像面積 0.1% 的直接丟棄。3.3 坑二類(lèi)別 ID 不連續(xù)導(dǎo)致訓(xùn)練報(bào)錯(cuò)現(xiàn)象YOLOv8 訓(xùn)練啟動(dòng)時(shí)報(bào)AssertionError: class id must be in range [0, nc)。原因COCO 的類(lèi)別 ID 可能是 1, 3, 7 這種不連續(xù)的而 YOLO 要求從 0 開(kāi)始連續(xù)編號(hào)。解決轉(zhuǎn)換時(shí)做重映射如腳本中的cat_id_map。同時(shí)生成data.yaml時(shí)names列表的順序必須和重映射后的 ID 一致。3.4 坑三圖像與標(biāo)簽文件名不匹配現(xiàn)象訓(xùn)練時(shí)提示No labels found但labels/目錄下明明有文件。原因圖像是.jpg標(biāo)簽是.txt但文件名前綴不一致——比如圖像叫IMG_001.jpg標(biāo)簽叫img_001.txt大小寫(xiě)或前綴不同。解決轉(zhuǎn)換腳本中用os.path.splitext(fname)[0]統(tǒng)一取文件名主干確保一一對(duì)應(yīng)。轉(zhuǎn)換后跑一遍校驗(yàn)?zāi)_本檢查每個(gè)圖像是否有對(duì)應(yīng)標(biāo)簽。4. YOLOv8 實(shí)例分割訓(xùn)練data.yaml 配置與關(guān)鍵超參設(shè)置4.1 data.yaml 的五個(gè)必填字段YOLOv8 分割訓(xùn)練的配置文件比檢測(cè)多一個(gè)task字段且names必須與類(lèi)別數(shù)嚴(yán)格對(duì)應(yīng)。# data.yaml path: ./agri_disease_seg # 數(shù)據(jù)集根目錄 train: images/train # 訓(xùn)練集圖像相對(duì)路徑 val: images/val # 驗(yàn)證集圖像相對(duì)路徑 test: images/test # 測(cè)試集可選 task: segment # 關(guān)鍵指定分割任務(wù) nc: 5 # 類(lèi)別數(shù)根據(jù)實(shí)際修改 names: # 類(lèi)別名稱(chēng)順序必須與訓(xùn)練標(biāo)簽中的 ID 一致 0: 早疫病 1: 晚疫病 2: 葉斑病 3: 銹病 4: 健康邏輯說(shuō)明path是根目錄train和val是相對(duì)于根目錄的路徑。task: segment告訴 YOLOv8 加載分割頭而不是檢測(cè)頭。names用字典或列表都行但順序不能錯(cuò)。參數(shù)說(shuō)明nc必須等于names的長(zhǎng)度。如果類(lèi)別數(shù)超過(guò) 10建議用列表形式寫(xiě)names更緊湊。test字段可選不寫(xiě)就不做測(cè)試集評(píng)估。4.2 訓(xùn)練命令與 batch size 的顯存估算# 單卡訓(xùn)練imgsz 根據(jù)圖像實(shí)際尺寸調(diào)整 yolo segment train \ data./data.yaml \ modelyolov8n-seg.pt \ epochs100 \ imgsz640 \ batch16 \ lr00.01 \ patience20 \ device0 \ projectagri_seg \ nameexp1邏輯說(shuō)明modelyolov8n-seg.pt加載預(yù)訓(xùn)練的分割模型n 是最小版本顯存不夠就換 n夠就換 s 或 m。imgsz640是輸入尺寸如果原始圖像是 1024 以上可以設(shè) 1024 但顯存翻倍。patience20表示 20 輪驗(yàn)證指標(biāo)不提升就早停。參數(shù)說(shuō)明batch16在 8GB 顯存上跑 640 尺寸的 n 模型基本夠用。如果 OOM先降 batch 到 8再降 imgsz 到 512。lr00.01是初始學(xué)習(xí)率分割任務(wù)通常比檢測(cè)稍小0.005 到 0.01 之間比較穩(wěn)。4.3 訓(xùn)練過(guò)程監(jiān)控看哪些指標(biāo)、什么時(shí)候該停訓(xùn)練啟動(dòng)后終端會(huì)輸出每輪的box_loss、seg_loss、cls_loss和mAP50。分割任務(wù)重點(diǎn)看seg_loss和mask mAP50。# 訓(xùn)練完成后查看結(jié)果 ls agri_seg/exp1/ # 關(guān)鍵文件results.csv每輪指標(biāo)、weights/best.pt最佳權(quán)重、 # confusion_matrix.png混淆矩陣、val_batch0_pred.jpg驗(yàn)證集預(yù)測(cè)可視化邏輯說(shuō)明results.csv可以用 pandas 讀取畫(huà)曲線重點(diǎn)看metrics/mAP50(M)是否還在漲。如果seg_loss持續(xù)下降但mAP50不漲說(shuō)明過(guò)擬合需要加數(shù)據(jù)增強(qiáng)或減模型復(fù)雜度。參數(shù)說(shuō)明mAP50(M)是掩碼 IoU 閾值 0.5 時(shí)的平均精度分割任務(wù)的核心指標(biāo)。mAP50-95(M)更嚴(yán)格但農(nóng)作物病害場(chǎng)景下 0.5 就夠用。5. 避坑與排查農(nóng)作物病害分割訓(xùn)練中最容易翻車(chē)的五個(gè)地方5.1 坑一驗(yàn)證集 mAP 很高但實(shí)際預(yù)測(cè)全是背景現(xiàn)象訓(xùn)練日志里mAP50(M)到了 0.8但拿新圖預(yù)測(cè)時(shí)模型輸出全是背景沒(méi)有任何掩碼。原因驗(yàn)證集和訓(xùn)練集來(lái)自同一批圖像分布太相似。模型學(xué)會(huì)了「猜」驗(yàn)證集的類(lèi)別分布但沒(méi)有真正學(xué)到病斑的視覺(jué)特征。解決手動(dòng)劃分驗(yàn)證集時(shí)確保不同批次、不同光照條件的圖像分開(kāi)。如果數(shù)據(jù)集本身多樣性不足用albumentations做離線增強(qiáng)擴(kuò)充訓(xùn)練集。預(yù)測(cè)時(shí)降低置信度閾值試試yolo segment predict conf0.1。5.2 坑二小病斑被完全忽略現(xiàn)象大塊病斑分割得很準(zhǔn)但直徑小于 20 像素的早期病斑一個(gè)都檢不出來(lái)。原因YOLOv8 的 P3 特征圖 stride 是 8對(duì)應(yīng) 640 輸入下最小感受野約 8 像素。小于這個(gè)尺寸的目標(biāo)在淺層特征中信息太少。解決把imgsz提到 1024 或 1280讓 P3 特征圖覆蓋更多像素?;蛘咴跀?shù)據(jù)增強(qiáng)中加copy_paste把小病斑復(fù)制到其他位置增加樣本。如果顯存不夠用yolov8s-seg換yolov8n-seg小模型的特征提取能力更弱。5.3 坑三掩碼邊緣鋸齒嚴(yán)重現(xiàn)象預(yù)測(cè)出的病斑掩碼邊緣呈鋸齒狀和真實(shí)邊界差距大。原因YOLOv8 分割頭輸出的掩碼原型分辨率是 160x160輸入 640 時(shí)上采樣到原圖尺寸時(shí)細(xì)節(jié)丟失。解決訓(xùn)練時(shí)設(shè)overlap_maskTrue默認(rèn)開(kāi)啟推理時(shí)用retina_masksTrue獲得更高分辨率的掩碼。如果還不夠換yolov8x-seg或yolov8l-seg大模型的原型掩碼通道更多。5.4 坑四類(lèi)別不平衡導(dǎo)致少數(shù)類(lèi)完全學(xué)不到現(xiàn)象早疫病和晚疫病樣本多mAP 正常銹病只有幾十個(gè)實(shí)例mAP 接近 0。解決在data.yaml同級(jí)目錄建一個(gè)hyp.yaml設(shè)置cls_pw1.0開(kāi)啟類(lèi)別權(quán)重?;蛘哂肳eightedRandomSampler做數(shù)據(jù)重采樣。最直接的辦法是離線過(guò)采樣把少數(shù)類(lèi)的圖像復(fù)制多份文件名加后綴區(qū)分。5.5 坑五訓(xùn)練 loss 震蕩不收斂現(xiàn)象seg_loss在 0.5 到 2.0 之間反復(fù)跳始終不下降。原因?qū)W習(xí)率太大或者 batch size 太小導(dǎo)致梯度噪聲大。解決先把lr0降到 0.001 試 10 輪。如果還震蕩把batch翻倍顯存允許的話。另外檢查數(shù)據(jù)標(biāo)注是否有大量錯(cuò)誤——用yolo segment train的--verbose模式看每批數(shù)據(jù)的損失分布異常高的批次對(duì)應(yīng)的圖像大概率標(biāo)注有問(wèn)題。6. 掩碼后處理與面積計(jì)算把分割結(jié)果變成可用的病害評(píng)估指標(biāo)6.1 從預(yù)測(cè)掩碼到病斑面積占比訓(xùn)練完模型只是第一步實(shí)際業(yè)務(wù)要的是「這片葉子上病斑占了多少面積」。YOLOv8 預(yù)測(cè)返回的masks是二值掩碼直接算像素占比就行。from ultralytics import YOLO import numpy as np import cv2 model YOLO(agri_seg/exp1/weights/best.pt) results model.predict(test_leaf.jpg, conf0.25, retina_masksTrue) for r in results: if r.masks is None: print(未檢測(cè)到病斑) continue # masks.data 形狀 [N, H, W]N 是檢測(cè)到的實(shí)例數(shù) masks r.masks.data.cpu().numpy() img_h, img_w r.orig_shape total_pixels img_h * img_w for i, mask in enumerate(masks): # 調(diào)整掩碼到原圖尺寸 mask_resized cv2.resize(mask, (img_w, img_h), interpolationcv2.INTER_NEAREST) area_ratio mask_resized.sum() / total_pixels cls_name r.names[int(r.boxes.cls[i])] print(f病斑 {i}: 類(lèi)別{cls_name}, 面積占比{area_ratio:.4f})邏輯說(shuō)明retina_masksTrue讓預(yù)測(cè)返回原圖分辨率的掩碼避免手動(dòng)上采樣。r.masks.data是[N, H, W]的張量每個(gè)通道對(duì)應(yīng)一個(gè)實(shí)例的二值掩碼。cv2.resize用最近鄰插值保持二值性。參數(shù)說(shuō)明conf0.25是置信度閾值農(nóng)作物病害場(chǎng)景可以降到 0.15 提高召回。area_ratio就是病斑面積占比超過(guò) 0.3 通常意味著嚴(yán)重感染。6.2 多病斑合并與嚴(yán)重度分級(jí)一張葉子上可能有多個(gè)同類(lèi)病斑業(yè)務(wù)上需要合并計(jì)算總感染面積。# 按類(lèi)別合并掩碼 from collections import defaultdict cls_masks defaultdict(list) for i, mask in enumerate(masks): cls_name r.names[int(r.boxes.cls[i])] cls_masks[cls_name].append(mask) for cls_name, mask_list in cls_masks.items(): # 邏輯或合并同類(lèi)掩碼 merged np.zeros_like(mask_list[0]) for m in mask_list: merged np.logical_or(merged, m 0.5) ratio merged.sum() / total_pixels # 分級(jí) if ratio 0.05: level 輕微 elif ratio 0.15: level 中度 elif ratio 0.30: level 重度 else: level 極重 print(f{cls_name}: 總面積占比{ratio:.4f}, 嚴(yán)重度{level})邏輯說(shuō)明np.logical_or合并同類(lèi)掩碼避免重疊區(qū)域重復(fù)計(jì)算。分級(jí)閾值根據(jù)實(shí)際業(yè)務(wù)調(diào)整這里給的是通用參考值。參數(shù)說(shuō)明m 0.5把概率掩碼二值化。分級(jí)閾值需要和農(nóng)學(xué)專(zhuān)家確認(rèn)不同作物的耐受度不同。6.3 一個(gè)容易忽略的細(xì)節(jié)掩碼面積計(jì)算時(shí)的圖像預(yù)處理還原如果推理時(shí)用了imgsz640但原圖是 2048x2048YOLOv8 內(nèi)部會(huì)縮放。retina_masksTrue會(huì)自動(dòng)還原到原圖尺寸但如果你手動(dòng)處理masks.data必須自己 resize 回去。我一般直接在predict里加retina_masksTrue省掉這一步。另外注意r.orig_shape返回的是(height, width)順序別搞反了。這套流程跑下來(lái)從拿到壓縮包到算出病斑面積占比順利的話半天能跑通。最耗時(shí)間的往往是標(biāo)注格式轉(zhuǎn)換和驗(yàn)證集劃分——這兩步做扎實(shí)后面訓(xùn)練基本不會(huì)出大問(wèn)題。我自己的習(xí)慣是轉(zhuǎn)換完先拿 10 張圖可視化檢查一遍確認(rèn)掩碼和原圖對(duì)齊了再啟動(dòng)訓(xùn)練能省下大量排查時(shí)間。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取