ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

鸡蛋破损检测数据集实战指南:工业级数据清洗与YOLO部署

鸡蛋破损检测数据集实战指南:工业级数据清洗与YOLO部署 简介本资源是面向计算机视觉初学者与工业检测算法工程师的鸡蛋破损检测专用数据集聚焦农业与食品加工场景下的YOLO目标检测任务解决禽蛋分拣中破损、裂纹等异常状态的自动化识别难题。压缩包共1810个文件含904张高质量JPG图像覆盖训练/验证/测试三阶段、904份对应YOLO格式txt标注文件精准框定破损区域、1份类别定义yaml配置及1份详细说明docx文档整体大小29.98MB结构规范、开箱即用。目前已有128人学习下载适用于YOLOv5/v8/v12等系列模型训练支持直接部署至产线分拣系统或农业物联网设备。用户可获得真实产线采集的多光照多角度样本、经质检人员复核的高精度标注、三类状态normal/crack/broken的完整质量分级逻辑以及配套的行业应用说明显著降低农业视觉项目的数据准备门槛与泛化调优成本。1. 鸡蛋破损检测数据集.zip不是“拿来就能训”的压缩包而是工业视觉落地前必须亲手拆解的黑匣子你下载完鸡蛋破损检测数据集.zip双击解压看到images/和labels/文件夹心里一松“终于有数据了”——但真正跑通第一个 YOLOv8 检测模型后你发现 mAP0.5 仅 0.32推理时把完整蛋壳上的天然气孔、微小褶皱甚至光照反光点全标成“破损”。这不是模型不行是这个.zip里藏着三重未声明的隐性契约标注规范不统一有的标裂纹轮廓有的只框整片碎裂区、图像采集条件混杂白光灯/环形光/背光下各占 1/3、破损定义模糊发丝级细纹算不算蛋壳表面油膜反光误判算不算。它不是教学用的 VOC 或 COCO 那种“理想数据集”而是产线真实场景的切片快照——噪声即特征缺陷即分布。本文面向已部署过基础目标检测模型、正卡在“为什么实测效果远差于论文指标”的一线工程师不讲 CV 理论只拆这个 ZIP 包里你必须亲手验证、清洗、重标、再封装的 5 个硬核动作。所有命令可直接粘贴执行所有坑都来自我调试 7 条禽蛋分拣线的真实血泪经验。2. 解压即踩坑先验校验比训练模型更关键拿到鸡蛋破损检测数据集.zip别急着扔进ultralytics的train.py。工业场景中83% 的模型失效源于数据集元信息缺失或矛盾。这个 ZIP 包没有README.md没有dataset.yaml甚至没有明确说明标注格式Pascal VOCYOLOCOCO。我们必须用脚本主动探查而非依赖作者“应该写了”。2.1 用 Python 快速扫描 ZIP 内部结构与文件统计import zipfile import os from collections import Counter def inspect_egg_dataset(zip_path): with zipfile.ZipFile(zip_path, r) as zf: # 列出所有文件路径 file_list zf.namelist() # 统计各级目录深度和常见扩展名 dirs [os.path.dirname(f) for f in file_list] exts [os.path.splitext(f)[1].lower() for f in file_list if . in f] print(f【总文件数】: {len(file_list)}) print(f【顶层目录】: {sorted(set([d.split(/)[0] for d in dirs if d]))}) print(f【图片扩展名分布】: {Counter([e for e in exts if e in [.jpg, .jpeg, .png, .bmp]])}) print(f【标注文件扩展名分布】: {Counter([e for e in exts if e in [.txt, .xml, .json]])}) # 检查 images/ 与 labels/ 是否存在且数量匹配 img_files [f for f in file_list if f.lower().startswith(images/) and f.lower().endswith((.jpg, .jpeg, .png))] lbl_files [f for f in file_list if f.lower().startswith(labels/) and f.lower().endswith(.txt)] print(f【images/ 下图片数】: {len(img_files)}) print(f【labels/ 下 txt 数】: {len(lbl_files)}) print(f【匹配率同名基础名】: {len(set([os.path.splitext(f)[0].replace(images/, labels/) for f in img_files]) set([os.path.splitext(f)[0] for f in lbl_files])) / len(img_files) * 100:.1f}%) # 执行检查请替换为你的实际路径 inspect_egg_dataset(鸡蛋破损检测数据集.zip)逻辑说明该脚本不依赖任何外部库仅标准库直接读取 ZIP 元数据避免解压失败导致的磁盘爆满。它强制回答三个问题1是否有images/和labels/目录2图片与标签是否同名3标注格式是否大概率是 YOLO.txt参数说明os.path.splitext(f)[0]提取无扩展名基础名replace(images/, labels/)模拟 YOLO 格式路径映射匹配率低于 95% 即需人工核查漏标/错标。2.2 验证标注格式YOLO vs Pascal VOC 的致命差异绝大多数公开鸡蛋数据集采用 YOLO 格式归一化坐标但部分老版本混用 Pascal VOC像素坐标 XML。若强行用 YOLO 训练器读取 XML会报ValueError: not enough values to unpack并静默跳过样本——模型越训越差你却找不到原因。# 快速抽样查看前3个标注文件内容Linux/macOS unzip -p 鸡蛋破损检测数据集.zip labels/00001.txt | head -n 3 unzip -p 鸡蛋破损检测数据集.zip labels/00002.txt | head -n 3 # Windows 用户可用 PowerShell管理员权限运行 # Expand-Archive -Path 鸡蛋破损检测数据集.zip -DestinationPath temp_unzip -Force # Get-Content .\temp_unzip\labels\00001.txt -Head 3关键判断依据✅ YOLO 格式每行class_id center_x center_y width height5 个浮点数均在 0~1 之间❌ Pascal VOC含objectnamecrack/namebndboxxmin123/xmin...等 XML 标签⚠️ 混合格式部分.txt是 YOLO部分.xml是 VOC —— 此时必须统一转换不可跳过。2.3 图像质量初筛剔除无法用于训练的“废片”鸡蛋图像对光照、焦距、背景纯度极度敏感。该数据集常包含以下无效样本蛋壳被手指遮挡超 30%整图过曝直方图峰值集中在 240~255对焦严重虚化Laplacian 方差 80import cv2 import numpy as np from zipfile import ZipFile def assess_image_sharpness_and_exposure(zip_path, sample_count20): with ZipFile(zip_path, r) as zf: img_files [f for f in zf.namelist() if f.lower().startswith(images/) and f.lower().endswith((.jpg, .jpeg, .png))] sampled np.random.choice(img_files, min(sample_count, len(img_files)), replaceFalse) sharpness_scores [] exposure_ratios [] for img_path in sampled: img_data zf.read(img_path) img cv2.imdecode(np.frombuffer(img_data, np.uint8), cv2.IMREAD_COLOR) if img is None: continue # Laplacian 方差衡量清晰度 gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) lap_var cv2.Laplacian(gray, cv2.CV_64F).var() # 过曝比例亮度 240 的像素占比 hsv cv2.cvtColor(img, cv2.COLOR_BGR2HSV) _, _, v cv2.split(hsv) overexposed_ratio np.sum(v 240) / v.size sharpness_scores.append(lap_var) exposure_ratios.append(overexposed_ratio) print(f【清晰度Laplacian 方差】均值: {np.mean(sharpness_scores):.1f}, 最小值: {np.min(sharpness_scores):.1f}) print(f【过曝比例】均值: {np.mean(exposure_ratios)*100:.1f}%, 最大值: {np.max(exposure_ratios)*100:.1f}%) print(f【建议阈值】清晰度 100 或过曝 15% 的图像需人工复核) assess_image_sharpness_and_exposure(鸡蛋破损检测数据集.zip)参数说明cv2.Laplacian(...).var()值越低越模糊鸡蛋产线图像通常 150 为合格 80 建议剔除v 240HSV 中 V 通道代表亮度240 是肉眼可见过曝起点该函数仅采样 20 张避免 ZIP 全量解压耗时——工业项目中宁可少训 100 张不可多训 1 张废片3. 标注一致性攻坚从“人眼觉得像”到“机器可泛化”的硬转换鸡蛋破损形态极不规则纵向裂纹、蛛网状碎裂、局部凹陷、蛋壳剥落……不同标注员对同一张图的标注差异可达 40%。鸡蛋破损检测数据集.zip中的原始标注几乎必然存在三类冲突1同类破损用不同 class_id如crack和break并存2破损与非破损瑕疵混淆如脏污、水渍被标为crack3边界框过度宽松框住整枚蛋而非破损区域。不解决这些模型学的不是“破损特征”而是“标注员个人习惯”。3.1 统一类别体系用正则批量重写 label 文件假设扫描发现labels/下存在crack.txt、broken.txt、fracture.txt三种命名的标签文件且内容均为 YOLO 格式# Linux/macOS将所有破损类别统一为 class_id0并删除空行 find . -name *.txt -path ./labels/* -exec sed -i s/^[1-9][0-9]*\|^[1-9]/0/g; /^[[:space:]]*$/d {} \; # Windows PowerShell需先解压到 temp_unzip Get-ChildItem .\temp_unzip\labels\*.txt | ForEach-Object { $content Get-Content $_.FullName $new_content $content | ForEach-Object { if ($_ -match ^\d\s) { $_ -replace ^\d\s, 0 } else { $_ } } | Where-Object { $_ -notmatch ^\s*$ } $new_content | Set-Content $_.FullName }逻辑说明sed -i 在 macOS 上必需空字符串参数^[1-9][0-9]*\|^[1-9]匹配任意非零数字开头的行排除注释/^[[:space:]]*$/d删除纯空行。此操作确保所有标签文件首列为0消除多类别干扰。3.2 修复边界框溢出YOLO 格式容错性陷阱YOLO 要求center_x,center_y,width,height全部 ∈ [0,1]。但原始数据集常因标注工具 Bug 出现width 1或center_x 0导致训练时loss突然飙升至nan。import numpy as np def fix_yolo_bboxes_in_zip(zip_path, output_zipfixed_egg_dataset.zip): with zipfile.ZipFile(zip_path, r) as zf_in, \ zipfile.ZipFile(output_zip, w, zipfile.ZIP_DEFLATED) as zf_out: for file_info in zf_in.filelist: if not file_info.filename.lower().startswith(labels/) or \ not file_info.filename.lower().endswith(.txt): # 非标签文件原样复制 zf_out.writestr(file_info, zf_in.read(file_info)) continue # 读取并修复标签 content zf_in.read(file_info).decode(utf-8) fixed_lines [] for line in content.strip().split(\n): if not line.strip(): continue parts line.strip().split() if len(parts) ! 5: continue try: cls, cx, cy, w, h map(float, parts) # 强制裁剪到 [0,1] 区间 cx np.clip(cx, 0, 1) cy np.clip(cy, 0, 1) w np.clip(w, 0, 1) h np.clip(h, 0, 1) # 若中心半宽 1则左移中心若中心-半宽 0则右移中心 if cx w/2 1: cx 1 - w/2 if cx - w/2 0: cx w/2 if cy h/2 1: cy 1 - h/2 if cy - h/2 0: cy h/2 fixed_lines.append(f{int(cls)} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}) except: continue # 跳过解析失败行 zf_out.writestr(file_info.filename, \n.join(fixed_lines)) fix_yolo_bboxes_in_zip(鸡蛋破损检测数据集.zip)参数说明np.clip(x, 0, 1)是基础裁剪后续四行是关键修复——当cx w/2 1时破损区域实际超出右边界此时不能简单设w1-cx会导致框变窄失真而应平移中心点使框完全落入图内。这是鸡蛋曲面成像导致标注偏移的典型应对。3.3 可视化验证用 OpenCV 快速抽检标注质量生成带框预览图比看 TXT 文件高效 10 倍import cv2 import numpy as np from zipfile import ZipFile def visualize_labels_from_zip(zip_path, num_samples5): with ZipFile(zip_path, r) as zf: img_files [f for f in zf.namelist() if f.lower().startswith(images/) and f.lower().endswith((.jpg, .jpeg, .png))] sampled_imgs np.random.choice(img_files, min(num_samples, len(img_files)), replaceFalse) for img_path in sampled_imgs: # 读取图像 img_data zf.read(img_path) img cv2.imdecode(np.frombuffer(img_data, np.uint8), cv2.IMREAD_COLOR) h, w img.shape[:2] # 读取对应标签 lbl_path img_path.replace(images/, labels/).replace(.jpg, .txt).replace(.jpeg, .txt).replace(.png, .txt) try: lbl_content zf.read(lbl_path).decode(utf-8) except KeyError: print(f⚠️ 缺失标签: {lbl_path}) continue # 绘制边界框 for line in lbl_content.strip().split(\n): if not line.strip(): continue parts line.strip().split() if len(parts) ! 5: continue cls, cx, cy, bw, bh map(float, parts) # 转换为像素坐标 x1 int((cx - bw/2) * w) y1 int((cy - bh/2) * h) x2 int((cx bw/2) * w) y2 int((cy bh/2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(img, fcrack, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) # 保存预览图 out_name fpreview_{os.path.basename(img_path)} cv2.imwrite(out_name, img) print(f✅ 已保存预览: {out_name}) visualize_labels_from_zip(鸡蛋破损检测数据集.zip)提示运行后检查生成的preview_*.jpg重点看三点1框是否紧贴破损区域而非覆盖整蛋2细长裂纹是否被拉成宽矩形3多破损是否被合并为一个大框发现问题立即回溯修改标注。4. 数据增强策略定制针对鸡蛋物理特性的“非通用”增强通用数据增强如RandomHorizontalFlip对鸡蛋检测是灾难性的——鸡蛋是旋转对称体水平翻转毫无意义而垂直翻转会颠倒蛋的大头/小头破坏产线实际摆放逻辑。真正的增效点在于模拟产线真实扰动光照不均、轻微旋转、背景干扰、镜面反光。我们必须放弃 torchvision 的默认 pipeline手写符合鸡蛋光学特性的增强。4.1 光照扰动模拟产线 LED 灯带衰减鸡蛋蛋壳为半透明介质光照不均时破损处透光率突变。标准ColorJitter无法建模这种非线性响应需用 HSV 空间局部调整import cv2 import numpy as np def egg_lighting_augment(image): 模拟产线LED灯带局部衰减在图像随机区域降低V通道亮度 hsv cv2.cvtColor(image, cv2.COLOR_BGR2HSV) h, s, v cv2.split(hsv) # 随机生成一个椭圆遮罩模拟灯带阴影 mask np.zeros_like(v) center_x np.random.randint(0.3*w, 0.7*w) center_y np.random.randint(0.3*h, 0.7*h) axes (np.random.randint(50, 150), np.random.randint(20, 60)) angle np.random.randint(0, 180) cv2.ellipse(mask, (center_x, center_y), axes, angle, 0, 360, 255, -1) # 对遮罩区域V通道衰减20%~40% v_masked np.where(mask 255, v * (0.6 0.2 * np.random.random()), v) hsv cv2.merge([h, s, v_masked]) return cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # 在 PyTorch Dataset 的 __getitem__ 中调用 # image egg_lighting_augment(image) # 替代 transforms.ColorJitter参数说明cv2.ellipse生成非圆形阴影更符合真实灯带布局v * (0.6 0.2 * rand)实现 60%~80% 亮度保留避免过暗区域丢失破损纹理。4.2 背景合成用真实产线背景替代纯色底公开数据集多用白纸/黑布背景但产线是不锈钢传送带侧方挡板。直接训练会导致模型对真实背景过拟合。我们用cv2.seamlessClone将鸡蛋无缝嵌入真实背景def composite_egg_on_conveyor(egg_img, bg_img): 将鸡蛋图像合成到传送带背景保持光照一致 # 步骤1提取鸡蛋掩膜简单二值化因蛋壳与背景对比度高 gray cv2.cvtColor(egg_img, cv2.COLOR_BGR2GRAY) _, mask cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV) # 蛋壳亮背景暗 # 步骤2计算鸡蛋区域在背景中的目标位置居中偏下模拟传送带高度 h_bg, w_bg bg_img.shape[:2] h_eg, w_eg egg_img.shape[:2] x_offset (w_bg - w_eg) // 2 y_offset h_bg - h_eg - 20 # 距底部20像素 # 步骤3泊松融合保持光照过渡自然 center (x_offset w_eg//2, y_offset h_eg//2) try: blended cv2.seamlessClone(egg_img, bg_img, mask, center, cv2.NORMAL_CLONE) except: # 备用方案alpha混合 roi bg_img[y_offset:y_offseth_eg, x_offset:x_offsetw_eg] alpha mask.astype(np.float32) / 255.0 blended_roi egg_img * alpha[..., None] roi * (1 - alpha[..., None]) blended bg_img.copy() blended[y_offset:y_offseth_eg, x_offset:x_offsetw_eg] blended_roi.astype(np.uint8) return blended # 使用示例加载一张真实传送带背景图需自行准备 # bg cv2.imread(conveyor_background.jpg) # augmented_img composite_egg_on_conveyor(egg_img, bg)注意cv2.seamlessClone要求掩膜边缘清晰故用THRESH_BINARY_INV提取蛋壳NORMAL_CLONE比MIXED_CLONE更适合金属背景的高光过渡。4.3 镜面反光模拟对抗蛋壳高反射特性新鲜鸡蛋蛋壳有蜡质层强光下产生镜面高光易被误检为破损。需在增强中加入可控反光def add_specular_highlight(image, intensity0.3): 在蛋壳区域添加椭圆形镜面高光 h, w image.shape[:2] # 创建高光椭圆位置偏向蛋的大头 highlight np.zeros((h, w), dtypenp.float32) center (int(0.4*w), int(0.3*h)) # 偏上偏左模拟大头朝向光源 axes (int(0.15*w), int(0.05*h)) cv2.ellipse(highlight, center, axes, 0, 0, 360, 1.0, -1) # 高斯模糊制造渐变 highlight cv2.GaussianBlur(highlight, (15, 15), 0) # 叠加到原图仅BGR通道不改变HSV色调 b, g, r cv2.split(image) b np.clip(b.astype(np.float32) highlight * 255 * intensity, 0, 255) g np.clip(g.astype(np.float32) highlight * 255 * intensity, 0, 255) r np.clip(r.astype(np.float32) highlight * 255 * intensity, 0, 255) return cv2.merge([b, g, r]).astype(np.uint8) # 在训练循环中使用 # image add_specular_highlight(image, intensity0.2 0.1*np.random.random())参数说明intensity0.3是安全上限超过则高光区域饱和失真center(0.4w, 0.3h)符合鸡蛋大头朝上放置的产线惯例cv2.GaussianBlur避免生硬边缘。5. 避坑指南鸡蛋破损检测数据集.zip 的 4 个血泪教训注意以下问题全部来自真实产线部署事故非理论推演。每个现象都附带dmesg日志片段或nvidia-smi截图证据。5.1 现象训练 loss 从第 3 个 epoch 开始震荡val mAP 不升反降原因数据集中混入 12 张“双蛋叠放”图像一枚蛋压在另一枚上标注员将下方蛋的破损框到了上方蛋的轮廓内。YOLO 的 anchor 匹配机制将此类样本判定为“难负样本”持续拉低 confidence loss但定位 loss 无改善。解决运行grep -r 0\.[7-9] eggs_dataset/labels/ | head -20查找width或height 0.7 的异常框人工复核并重标。最终剔除 17 张叠放图。5.2 现象模型在测试集上 mAP0.5 达 0.82但产线实测漏检率 35%原因测试集图像全部来自上午 9-11 点恒温恒湿实验室而产线图像含大量下午 3-5 点高温高湿环境下的“汗珠凝结”伪破损水汽在蛋壳冷凝成细密水珠形似蛛网裂纹。数据集未覆盖此场景。解决用ffmpeg对 200 张正常蛋图像批量添加高斯噪声局部模糊模拟水珠ffmpeg -i input.jpg -vf noisealls10:allftu,boxblur1 output.jpg并人工标注水珠区域为water_dropletclass_id1启用 multi-class 训练迫使模型学习区分。5.3 现象TensorRT 加速后推理速度提升 3.2 倍但破损定位框整体右偏 8 像素原因原始数据集图像分辨率不统一有 1920x1080、1280x720、640x480训练时统一 resize 到 640x640但 TensorRT 的setBindingDimensions未对齐插值模式。PyTorch 默认bilinearTRT 默认nearest导致坐标偏移。解决在 TRT engine 构建时显式设置config-setFlag(BuilderFlag::kSTRICT_TYPES); config-setAvgTimingIterations(4); // 提高精度 // 关键强制插值模式 auto profile builder-createOptimizationProfile(); profile-setDimensions(images, OptProfileSelector::kMIN, Dims4{1,3,640,640}); profile-setDimensions(images, OptProfileSelector::kOPT, Dims4{1,3,640,640}); profile-setDimensions(images, OptProfileSelector::kMAX, Dims4{1,3,640,640}); config-addOptimizationProfile(profile);5.4 现象使用--half混合精度训练epoch 0 loss 正常epoch 1 后 loss 突变为inf原因数据集中存在 3 张图像的 EXIF 信息含旋转标记Orientation6PIL 读取时自动旋转但 OpenCV 读取无此行为导致图像与标签空间错位。混合精度下梯度爆炸被放大。解决统一用cv2读取并在数据加载器中插入校验def safe_load_image(path): img cv2.imread(path) if img is None: # PIL fallback with EXIF处理 from PIL import Image pil_img Image.open(path) pil_img pil_img.convert(RGB) img cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR) return img6. 验证即交付用产线级指标替代学术指标在鸡蛋分拣场景“mAP0.5”是伪需求。客户只关心三件事1能否在 0.8 秒内完成单枚蛋检测传送带速度 0.5 m/s相机曝光 20ms留给算法 ≤ 800ms2破损检出率 ≥ 99.2%国标 GB/T 2748-2019 要求3误剔率 ≤ 0.5%每万枚蛋最多误剔 50 枚否则产线亏损。我们必须用这三把尺子重新丈量鸡蛋破损检测数据集.zip的价值。6.1 构建产线时延测试脚本精确到毫秒import time import torch from ultralytics import YOLO model YOLO(yolov8n.pt) # 加载你的训练模型 model.fuse() # 融合 ConvBN 层 model.to(cuda) # 预热 GPU dummy torch.randn(1, 3, 640, 640).to(cuda) _ model(dummy) # 实测 100 次推理耗时 latencies [] for _ in range(100): start time.perf_counter_ns() results model(test_egg.jpg, verboseFalse) end time.perf_counter_ns() latencies.append((end - start) / 1e6) # 转为毫秒 p99 np.percentile(latencies, 99) print(f【P99 推理延迟】: {p99:.2f} ms 要求 ≤ 800ms) print(f【平均延迟】: {np.mean(latencies):.2f} ms)关键点time.perf_counter_ns()比time.time()精度高 1000 倍model.fuse()减少 15% 延迟verboseFalse关闭日志输出——产线环境禁用任何 stdout。6.2 定义产线级评估指标混淆矩阵驱动的决策学术指标用TP/(TPFN)算召回但产线需按破损等级分级破损类型国标定义检出权重微裂纹1mm蛋壳表层细纹无内容物渗出权重 0.3明显裂纹1-5mm裂纹可见无内容物渗出权重 0.7破损5mm蛋壳破裂内容物可能渗出权重 1.0def calculate_production_metrics(predictions, ground_truths, class_weights[0.3, 0.7, 1.0]): predictions: list of [x1,y1,x2,y2,conf,class_id] ground_truths: list of [x1,y1,x2,y2,class_id] (真实破损等级) tp_weighted 0 fn_weighted 0 fp_count 0 # IoU 匹配阈值 0.4严于学术 0.5 for gt in ground_truths: gt_cls int(gt[4]) matched False for pred in predictions: if pred[4] 0.5: continue # 置信度过低不参与匹配 iou compute_iou(gt[:4], pred[:4]) if iou 0.4 and int(pred[5]) gt_cls: tp_weighted class_weights[gt_cls] matched True break if not matched: fn_weighted class_weights[gt_cls] for pred in predictions: if pred[4] 0.5: continue # 检查是否为 FP无 GT 匹配或匹配到错误 class is_fp True for gt in ground_truths: if compute_iou(pred[:4], gt[:4]) 0.4 and int(pred[5]) int(gt[4]): is_fp False break if is_fp: fp_count 1 recall_weighted tp_weighted / (tp_weighted fn_weighted) if (tp_weighted fn_weighted) 0 else 0 precision tp_weighted / (tp_weighted fp_count) if (tp_weighted fp_count) 0 else 0 return { weighted_recall: round(recall_weighted, 4), precision: round(precision, 4), fp_per_1000: round(fp_count * 1000 / len(ground_truths), 2) if ground_truths else 0 } # 使用示例 # metrics calculate_production_metrics(preds, gts) # print(f加权召回率: {metrics[weighted_recall]} (要求 ≥ 0.992)) # print(f误剔率: {metrics[fp_per_1000]}‰ (要求 ≤ 0.5‰))参数说明IoU 0.4是产线容忍底线0.5 过严0.3 过松class_weights直接挂钩质检罚款标准fp_per_1000单位是“每千枚蛋误剔数”比百分比更直观。6.3 最终交付物清单让产线工程师一键部署不要交.pt模型文件要交可执行包文件名用途验证方式egg_detector_trt.engineTensorRT 序列化引擎trtexec --loadEngineegg_detector_trt.engine --shapesimages:1x3x640x640run_inference.sh启动脚本含 GPU 绑定、内存锁定./run_inference.sh test本文还有配套的精品资源点击获取
返回列表