YOLOv26 鱼类目标检测与计数任务实现与优化
基于 YOLOv26 实现智慧渔业场景下的鱼类目标检测与自动计数:从数据集构建与增强、训练配置与优化(K-Means 锚框、多尺度训练、量化与 TensorRT 加速),到检测计数系统实现与性能评估的完整技术方案。
YOLOv26 鱼类目标检测与计数任务实现与优化
一、项目背景
在智慧渔业和海洋生态研究中,鱼类目标检测与计数是一项关键任务。传统的人工计数方式依赖肉眼观察,效率低、误差大,难以满足规模化养殖和科研监测的需求。借助深度学习目标检测技术,可以实现对水下摄像头、养殖池监控画面的自动分析,实时识别鱼群并统计数量,为养殖管理、投喂决策和生态评估提供数据支撑。
YOLOv26 作为 YOLO 系列的最新目标检测模型,以高精度和实时性能见长。它在 YOLOv5 的基础上进行了多项改进:更高效的特征融合网络、更精准的注意力机制以及更轻量化的模型结构。这些改进使模型在保持高精度的同时显著降低计算资源需求,非常适合在嵌入式设备上部署,实现渔业现场的实时监测。
二、技术方案:整体流程
本项目的完整技术链路分为五个阶段:
- 数据集构建与预处理:采集标注鱼类图像,统一尺寸、归一化、数据增强;
- 模型训练与优化:配置超参数训练 YOLOv26,通过锚框优化、多尺度训练提升精度;
- 检测与计数实现:基于训练好的模型开发检测与计数模块;
- 性能评估:用 mAP、Precision/Recall 等指标量化模型效果;
- 部署与应用:量化 + TensorRT 加速,落地智能养殖监控场景。
三、系统架构:核心模块设计
3.1 数据集构建
鱼类目标检测的数据集通常包含多种鱼类的图像,每张图像都标注了鱼类的位置和类别。一个高质量的数据集应具备:
- 多样性:包含不同光照、角度、背景下的鱼类图像;
- 标注准确性:确保边界框标注准确、类别分类正确;
- 平衡性:各类别样本数量相对均衡,避免模型偏向某些类别。
数据集的构建通常经过图像采集、标注、清洗和增强等步骤。对于小型数据集,数据增强尤为重要,可以显著提升模型泛化能力。
YOLO 格式的标注文件为每张图像对应一个 txt 文件,每行一个目标:
<class_id> <x_center> <y_center> <width> <height>
坐标均为归一化到 [0,1] 的相对值。数据集按 7:2:1 划分为训练集、验证集和测试集(split_dataset 脚本自动完成目录创建与文件复制)。
3.2 数据预处理与增强
归一化公式:将原始像素值 x 映射到 [0,1] 区间,帮助模型更快收敛:
x_norm = (x - x_min) / (x_max - x_min)
增强策略(针对鱼类检测场景):
- 随机水平翻转:模拟不同视角下的鱼类图像;
- 色彩抖动:调整亮度、对比度和饱和度,适应不同光照条件;
- 随机裁剪:聚焦于鱼类区域,减少背景干扰;
- 旋转、缩放、剪切、高斯噪声、高斯模糊:增强模型鲁棒性。
使用 imgaug 库实现自动化增强流水线:
import cv2
import numpy as np
from imgaug import augmenters as iaa
# 定义数据增强序列
augmentation_seq = iaa.Sequential([
iaa.Fliplr(0.5), # 水平翻转
iaa.Affine(
scale={"x": (0.8, 1.2), "y": (0.8, 1.2)}, # 缩放
rotate=(-20, 20), # 旋转
shear=(-10, 10), # 剪切
mode='reflect'
),
iaa.AdditiveGaussianNoise(scale=(0, 0.1 * 255)), # 高斯噪声
iaa.Multiply((0.8, 1.2)), # 亮度调整
iaa.LinearContrast((0.8, 1.2)), # 对比度调整
iaa.AddToHueAndSaturation((-20, 20)), # 色调调整
iaa.Sometimes(0.5, iaa.Grayscale(3)), # 转为灰度
iaa.Sometimes(0.5, iaa.GaussianBlur(sigma=(0, 3.0))) # 高斯模糊
])
对于需要同步修改边界框的增强(翻转、裁剪),可自定义 FishAugmentation 类,确保图像与标注框保持一致变换。
四、实施过程:训练、优化与计数实现
4.1 环境搭建
pip install torch torchvision
pip install ultralytics
pip install numpy opencv-python pillow
pip install tqdm tensorboard pyyaml
4.2 训练配置
数据集配置文件 fish.yaml 与模型配置文件核心参数如下:
# 模型配置
model: yolov26s.pt # 使用预训练模型
data: fish.yaml # 数据集配置文件
# 训练参数
epochs: 300 # 训练轮次
batch_size: 16 # 批次大小
img_size: 640 # 输入图像尺寸
workers: 8 # 数据加载线程数
# 优化器参数
optimizer: SGD # 优化器
lr0: 0.01 # 初始学习率
lrf: 0.01 # 最终学习率比例
momentum: 0.937 # 动量
weight_decay: 0.0005 # 权重衰减
# 学习率调度
scheduler: cosine # 余弦退火调度
# 数据增强
hsv_h: 0.015 # 色调增强比例
hsv_s: 0.7 # 饱和度增强比例
hsv_v: 0.4 # 明度增强比例
fliplr: 0.5 # 水平翻转概率
mosaic: 1.0 # Mosaic增强概率
mixup: 0.1 # Mixup增强概率
模型结构配置(backbone 采用 CSPDarknet 风格,neck 采用 PAN-FPN 特征融合,head 为 YOLO 检测头),类别数 nc: 1(鱼类单类别)。
学习率策略:采用 Cosine Annealing 平滑调整,避免训练震荡;也可以自定义 CosineAnnealingWarmupLR,先线性 warmup 再余弦退火,提升训练稳定性。
4.3 训练过程监控
使用 TensorBoard 实时记录训练与验证指标:
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter()
for epoch in range(epochs):
# 训练代码...
# 记录训练损失
writer.add_scalar('Train/total_loss', loss.item(), epoch)
writer.add_scalar('Train/obj_loss', obj_loss.item(), epoch)
writer.add_scalar('Train/cls_loss', cls_loss.item(), epoch)
writer.add_scalar('Train/box_loss', box_loss.item(), epoch)
# 记录验证指标
writer.add_scalar('Val/mAP_0.5', map_50, epoch)
writer.add_scalar('Val/mAP_0.5:0.95', map_50_95, epoch)
4.4 模型优化策略
1. 改进的锚框生成(K-Means)
鱼类目标长宽比差异大,使用标准锚框效果欠佳。对标注框的宽高取对数后做 K-Means 聚类,得到贴合数据分布的锚框:
def improved_anchors_kmeans(annotations, n_clusters=9, random_state=None):
"""
改进的锚框生成算法,特别适合鱼类检测
annotations: 标注数据列表,每个元素为[x_center, y_center, width, height]
"""
annotations = np.array(annotations)
wh = annotations[:, 2:]
log_wh = np.log(wh) # 对宽高取对数,降低尺度差异影响
kmeans = KMeans(n_clusters=n_clusters, random_state=random_state)
kmeans.fit(log_wh)
anchors = np.exp(kmeans.cluster_centers_) # 还原为实际尺寸
# 按面积排序
areas = anchors[:, 0] * anchors[:, 1]
sorted_indices = np.argsort(areas)
anchors = anchors[sorted_indices]
return anchors
2. 多尺度训练
在 [640, 800, 960] 多种输入尺寸间轮换训练,增强模型对不同目标尺度的适应能力:
multi_scale_config = {
'img_size_range': [640, 800, 960], # 多种输入尺寸
'stride_range': [8, 16, 32], # 不同步长
'anchor_sizes': [[10, 13, 16], [30, 61, 62], [116, 90, 156]] # 不同尺度的锚框
}
3. 损失函数改进
针对鱼类目标小、样本不均衡的特点,可引入 Focal Loss(缓解难易样本不平衡)或 Varifocal Loss(提升密集场景下高质量锚框的权重)。
4. 模型量化与 TensorRT 加速
部署阶段先做动态量化压缩模型体积:
from torch.quantization import quantize_dynamic
quantized_model = quantize_dynamic(
model,
{nn.Conv2d, nn.Linear}, # 量化卷积与全连接层
dtype=torch.qint8 # 8位量化
)
torch.save(quantized_model.state_dict(), 'yolov26_quantized.pth')
再导出 ONNX 并用 TensorRT 构建推理引擎,实现 GPU 上的极致加速:
import tensorrt as trt
logger = trt.Logger(trt.Logger.WARNING)
builder = trt.Builder(logger)
network = builder.create_network(1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH))
parser = trt.OnnxParser(network, logger)
with open('yolov26.onnx', 'rb') as model:
if not parser.parse(model.read()):
print('ERROR: Failed to parse the ONNX file.')
for error in range(parser.num_errors):
print(parser.get_error(error))
sys.exit(1)
config = builder.create_builder_config()
config.max_workspace_size = 1 << 30 # 1GB
engine = builder.build_engine(network, config)
with open('yolov26.trt', 'wb') as f:
f.write(engine.serialize())
4.5 检测与计数实现
检测器封装推理全流程:预处理(resize 到 640×640、归一化、CHW 转置)→ 模型推理 → 后处理(置信度过滤 + NMS)→ 可视化:
class FishDetector:
def __init__(self, model_path, device='cpu'):
self.model = Model('models/yolov6s.yaml').to(device)
self.model.load_state_dict(torch.load(model_path, map_location=device))
self.model.eval()
self.class_names = ['fish']
def preprocess(self, img):
img = cv2.resize(img, (640, 640))
img = img.transpose((2, 0, 1)) # HWC to CHW
img = np.ascontiguousarray(img)
img = torch.from_numpy(img).float() / 255.0
if img.ndimension() == 3:
img = img.unsqueeze(0)
return img
def detect(self, img, conf_thres=0.25, iou_thres=0.45):
# 预处理 -> 推理 -> 后处理(NMS) -> 返回框/分数/类别
...
计数模块在检测基础上引入跨帧跟踪去重,避免同一尾鱼被重复计数:
class SmartAquacultureSystem:
def __init__(self, model_path, device='cpu'):
self.detector = FishDetector(model_path, device)
self.fish_count = 0
self.counted_fish = set()
self.tracking_history = {}
self.max_track_length = 30
self.cap = cv2.VideoCapture(0)
def process_frame(self, frame):
count, result_img = self.detector.count_fish(frame)
current_fish = self.detect_and_track_fish(frame) # 跟踪当前帧鱼群
# 新增鱼进入画面才计数
new_fish = current_fish - self.counted_fish
self.fish_count += len(new_fish)
self.counted_fish.update(new_fish)
cv2.putText(result_img, f"Total Count: {self.fish_count}", (10, 60),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
return result_img
4.6 性能评估
使用 Precision、Recall、mAP@0.5、mAP@0.5:0.95 等指标评估模型:
- Precision(精确率):预测为正的样本中实际为正的比例;
- Recall(召回率):实际为正的样本中被正确预测的比例;
- mAP:多类别下 AP 的均值,mAP@0.5:0.95 为 IoU 阈值从 0.5 到 0.95 步进 0.05 的平均值,是衡量检测器综合精度的核心指标。
评估代码通过 precision_recall_curve 计算 PR 曲线,再对预测框做置信度过滤与 NMS 后与标注比对,统计各指标。
五、应用价值
- 智慧养殖:实时统计养殖池鱼群数量,辅助投喂决策、存活率评估与病害预警,替代人工计数,降低人力成本;
- 海洋生态研究:对水下影像自动识别鱼类种类与数量,支撑种群密度调查与生态监测;
- 嵌入式部署:模型轻量化 + 量化 + TensorRT 加速后,可在边缘设备上实时运行,满足养殖现场的长期在线监测需求;
- 可复制方案:从数据集构建到部署的完整链路可直接迁移到其他水产目标(虾、蟹、贝类)检测场景。
六、SEO关键词
YOLOv26、鱼类检测、目标计数、智慧渔业、深度学习、目标检测、YOLO、数据增强、TensorRT、模型量化、水产养殖、实时监测
