YOLOv26药品铝塑板缺粒检测实战:Python训练、验证与推理完整代码
药品铝塑板 YOLOv26 缺粒检测实战教程:从项目目标、Python 虚拟环境搭建、数据集目录设计、类别与 data.yaml 配置,到 train.py 训练、val.py 验证、predict.py 单张推理与检测框提取的完整 Python 代码,并讲解位置模板、ROI 颜色检测、分阶段开发顺序与最终工程架构,可直接照抄运行。
一、项目目标
针对药品铝塑板视觉检测,本项目使用:
500万彩色工业相机 + 穹顶漫射光 + YOLOv26
实现药品铝塑板的:
- 药粒有无检测
- 药粒缺失检测
- 药粒破损检测
- 药粒异常检测
- 药粒位置检测
- 后续扩展颜色检测
整体流程:
工业相机
↓
采集铝塑板图片
↓
人工标注
↓
YOLO数据集
↓
YOLOv26训练
↓
模型验证
↓
单张图片测试
↓
实时相机检测
↓
OK / NG
二、Python环境
建议单独建立虚拟环境:
conda create -n yolo26_drug python=3.11 -y
conda activate yolo26_drug
安装 Ultralytics:
pip install -U ultralytics
检查版本:
python -c "import ultralytics; print(ultralytics.__version__)"
检查 YOLO:
yolo checks
如果使用 NVIDIA GPU,还需要根据 CUDA 环境安装对应版本的 PyTorch。
三、项目目录
建议先建立一个非常简单的项目:
drug_yolo26/
│
├── datasets/
│ └── blister/
│ ├── images/
│ │ ├── train/
│ │ ├── val/
│ │ └── test/
│ │
│ ├── labels/
│ │ ├── train/
│ │ ├── val/
│ │ └── test/
│ │
│ └── data.yaml
│
├── train.py
├── val.py
├── predict.py
└── test_camera.py
四、建立YOLO数据集
例如采集 1000 张铝塑板图片。建议:
- 训练集:80%
- 验证集:10%
- 测试集:10%
最终 images/train、images/val、images/test 分别对应 labels/train、labels/val、labels/test。例如:
images/train/
000001.jpg
000002.jpg
000003.jpg
labels/train/
000001.txt
000002.txt
000003.txt
图片和标签必须一一对应。
五、检测类别设计
第一阶段建议不要把类别设计得过于复杂。例如:
0 normal
1 missing
2 damaged
对应:
names:
0: normal
1: missing
2: damaged
后期如果增加颜色检测,可以扩展:
0 normal
1 missing
2 damaged
3 color_error
4 foreign_object
不过实际项目中,我仍然推荐:YOLO 负责目标和缺陷,Lab 负责精确颜色评价。不要一开始就让 YOLO 承担所有颜色判断。
六、data.yaml
创建 datasets/blister/data.yaml,内容:
path: ./datasets/blister
train: images/train
val: images/val
test: images/test
names:
0: normal
1: missing
2: damaged
如果数据集使用绝对路径,也可以:
path: D:/AI/drug_yolo26/datasets/blister
train: images/train
val: images/val
test: images/test
names:
0: normal
1: missing
2: damaged
七、YOLO标签格式
YOLO 标签一行表示一个目标:
class x_center y_center width height
例如:
0 0.215 0.318 0.085 0.092
所有坐标都是 0~1 归一化坐标。例如图片 2448 × 2048,药粒中心 x=600、y=700,那么:
x_center = 600 / 2448
y_center = 700 / 2048
八、Python训练程序
创建 train.py,代码尽量保持简单,方便调试:
from ultralytics import YOLO
def main():
# 加载YOLOv26模型
model = YOLO("yolo26n.pt")
# 开始训练
results = model.train(
data="datasets/blister/data.yaml",
# 输入尺寸
imgsz=640,
# 训练轮数
epochs=100,
# Batch
batch=16,
# GPU
device=0,
# 工作线程
workers=4,
# 项目名称
project="runs/drug",
# 实验名称
name="yolo26n_blister",
# 保存周期
save_period=10,
# 预训练
pretrained=True,
# 训练完成后进行验证
val=True,
)
print("训练完成")
if __name__ == "__main__":
main()
运行:
python train.py
九、第一次调试不要直接训练几百轮
第一次建议 epochs=5,例如:
model.train(
data="datasets/blister/data.yaml",
imgsz=640,
epochs=5,
batch=4,
device=0,
workers=2,
)
目的不是获得最终模型,而是检查:
- 数据集是否正确
- 标签是否正确
- 模型是否能正常训练
- GPU 是否正常
- 类别是否正确
- 图片是否能够读取
如果 5 轮可以正常完成,再增加到 50、100、200,甚至 200~300 轮。
十、CPU调试
如果电脑没有 GPU,可以 device="cpu":
model.train(
data="datasets/blister/data.yaml",
imgsz=640,
epochs=5,
batch=2,
device="cpu",
workers=2,
)
CPU 主要用于验证程序能不能跑通,正式训练还是建议使用 GPU。
十一、训练结果
训练完成后通常可以看到:
runs/
└── drug/
└── yolo26n_blister/
├── weights/
│ ├── best.pt
│ └── last.pt
│
├── results.csv
├── results.png
├── confusion_matrix.png
└── ...
其中 best.pt 是后续推理最重要的模型。
十二、Python验证模型
创建 val.py:
from ultralytics import YOLO
def main():
model = YOLO(
"runs/drug/yolo26n_blister/weights/best.pt"
)
results = model.val(
data="datasets/blister/data.yaml",
imgsz=640,
batch=16,
device=0,
)
print(results)
if __name__ == "__main__":
main()
运行:
python val.py
重点关注 Precision、Recall、mAP50、mAP50-95。但是工业检测不能只看 mAP,真正应该重点关注:缺粒有没有漏检。
十三、为什么工业检测不能只看mAP?
例如正常药粒 10000 个、缺粒 100 个,模型可能获得非常漂亮的整体 mAP。但是如果缺粒漏检 20 个,对于药品包装来说,仍然可能是无法接受的。
所以实际项目应该单独统计:
- 缺粒 Recall
- 破损 Recall
- 颜色异常 Recall
特别是缺陷漏检率。
十四、单张图片推理
创建 predict.py:
from ultralytics import YOLO
def main():
model = YOLO(
"runs/drug/yolo26n_blister/weights/best.pt"
)
results = model.predict(
source="test.jpg",
# 输入尺寸
imgsz=640,
# 置信度
conf=0.25,
# IoU
iou=0.45,
# GPU
device=0,
# 保存结果
save=True,
# 保存标签
save_txt=True,
# 显示结果
show=True,
)
for result in results:
print("检测结果:")
for box in result.boxes:
cls_id = int(box.cls[0])
conf = float(box.conf[0])
print(
f"class={cls_id}, "
f"confidence={conf:.3f}"
)
if __name__ == "__main__":
main()
运行:
python predict.py
十五、获取YOLO检测框
实际工业软件开发时,我们通常不只是需要画框,而是需要获得 X、Y、W、H、Class、Confidence。例如:
for result in results:
boxes = result.boxes
for box in boxes:
cls_id = int(box.cls[0])
conf = float(box.conf[0])
x1, y1, x2, y2 = box.xyxy[0].tolist()
print(
cls_id,
conf,
x1,
y1,
x2,
y2,
)
这样就可以继续做:颗粒定位、模板匹配、颜色分析、完整度分析、PLC 控制。
十六、建立铝塑板颗粒位置模板
这是实际项目中非常重要的一步。假设一板药有 20 颗,可以建立:
P01
P02
P03
...
P20
例如:
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
○ ○ ○ ○ ○
YOLO 识别以后:
P01 → normal
P02 → normal
P03 → missing
P04 → normal
...
最终:P03 = 缺粒,整板 NG。
十七、颜色检测
YOLO 检测到药粒以后,取得对应 ROI:
x1, y1, x2, y2 = map(int, box.xyxy[0])
roi = image[y1:y2, x1:x2]
然后:
ROI
↓
RGB
↓
Lab
↓
颜色特征
↓
ΔE
↓
颜色是否异常
Python 可以使用 OpenCV:
import cv2
lab = cv2.cvtColor(
roi,
cv2.COLOR_BGR2LAB,
)
注意:OpenCV 读取图片默认是 BGR,而不是 RGB,所以程序中一定要注意通道顺序。
十八、为什么使用Lab?
RGB 更适合图像显示,Lab 更适合颜色差异评价。因此:
相机
↓
BGR
↓
Lab
↓
L*
a*
b*
↓
ΔE
可以建立正常药粒颜色标准,例如:
正常颜色中心:
L = 72
a = 8
b = 31
当前药粒:
L = 70
a = 11
b = 21
计算颜色距离,超过设定阈值即为 Color NG。
十九、完整检测逻辑
最终建议使用下面的判断流程:
彩色工业相机
↓
图像
↓
YOLOv26
↓
┌────────┴────────┐
↓ ↓
药粒检测 异常检测
↓ ↓
位置模板匹配 缺粒/破损
↓
获得ROI
↓
Lab颜色分析
↓
ΔE
↓
┌─────┴─────┐
↓ ↓
完整度OK 颜色异常
↓ ↓
└─────┬─────┘
↓
颗粒级结果
↓
整板OK / NG
二十、建议第一阶段先不要做颜色训练
这是实际调试时非常重要的一点。第一阶段只训练:
normal
missing
damaged
先解决:药粒有没有、位置对不对、是否破损。等模型稳定以后,再加入 Lab + ΔE 处理颜色。这样调试会简单很多。
二十一、推荐的开发顺序
整个项目不要一次性全部开发,建议按照以下阶段推进:
第一阶段:图片读取 → YOLOv26 训练 → 单张图片推理
第二阶段:药粒位置模板 → 缺粒判断 → 整板 OK/NG
第三阶段:ROI 提取 → Lab 颜色分析 → ΔE
第四阶段:工业相机实时采集 → YOLOv26 实时推理
第五阶段:PLC → 剔除机构
第六阶段:MES → 批次 → 产品 → 检测结果
二十二、最终工程架构
最终 Python 调试程序可以形成:
drug_yolo26/
│
├── datasets/
│ └── blister/
│
├── models/
│ └── best.pt
│
├── train.py
├── val.py
├── predict.py
│
├── vision/
│ ├── color.py
│ ├── completeness.py
│ └── template.py
│
└── camera/
└── camera.py
其中:
train.py:负责训练predict.py:负责 YOLO 推理color.py:负责颜色检测completeness.py:负责颗粒完整度template.py:负责铝塑板颗粒位置判断
最终可以进一步将 Python 算法迁移到 C#、Qt/C++、OpenVINO、Intel NPU、NVIDIA GPU 进行工业部署。
二十三、总结
本项目最终采用:500万像素彩色工业相机 + 穹顶漫射光 + YOLOv26。其中:
- 相机负责获得高质量彩色图像
- 穹顶漫射光负责降低铝塑板反光和光照不均
- YOLOv26 负责药粒定位、缺粒和破损检测
- 位置模板负责判断每一个规定位置是否存在药粒
- Lab + ΔE 负责药粒颜色检测
最终输出:颗粒数量、缺粒数量、破损数量、颜色异常数量、完整度、整板 OK/NG。
