红外视频瞳孔检测:Hough变换与轮廓匹配实战
简介这份资源面向图像处理与计算机视觉领域的研究人员和工程师针对红外视频中瞳孔直径检测精度偏低的痛点提出结合Hough变换与轮廓匹配的Hough-Contour算法。算法先对每帧图像灰度化并滤波去噪再用改进的Hough梯度法初步定位瞳孔随后在瞳孔附近做圆形轮廓匹配精确计算瞳孔中心坐标与直径通过将候选圆心按累积值降序排序改为直接搜索最大值来降低耗时并借助累积值阈值自动排除闭眼帧。实验表明轮廓移动与拉伸范围取初始半径的十分之一、点对数取40时精确匹配率由OpenCV圆变换的约10%提升至99.8%低端设备处理320×240视频、高端设备处理640×480视频均可实时检测。资源包为1个PDF文件约1.04MB完整呈现算法步骤、参数设置与实验对比已有170人学习适合希望深入掌握红外瞳孔高精度检测实现细节的读者研读。1. 红外视频里瞳孔检测为什么总在“最后一公里”翻车做过红外眼动或者疲劳监测的同行大概都有体会在可见光下跑得好好的瞳孔检测一换到红外视频就各种玄学问题。红外成像本身对比度低、噪声大眼睑和睫毛在 850nm 附近反光弱瞳孔和虹膜灰度差被压缩再加上人眼频繁眨眼、头部微动单靠阈值或者单靠边缘检测基本都会在“最后一公里”翻车。标题里这套“Hough 变换 轮廓匹配”的组合本质上是想解决两件事一是用 Hough 在候选圆里快速定位瞳孔的几何中心二是用轮廓匹配把误检的圆比如虹膜外沿、眼镜框反光、眼睑弧线筛掉。它适合做嵌入式眼动仪、驾驶疲劳监测、VR/AR 眼动追踪的团队也适合手里已经有红外相机、想先把瞳孔坐标稳定拿到的开发者。下面我按自己踩过的路径把选型、参数、代码和坑一条条拆开。2. 从红外帧到瞳孔候选圆预处理与 Hough 参数怎么定2.1 红外瞳孔成像的三个物理约束先别急着写 Hough。红外视频里瞳孔之所以难搞根子在三个物理约束上。第一瞳孔在 850nm 附近反射率极低但角膜和眼睑会形成高光斑这些高光斑在二值化后经常和瞳孔连成一片导致质心偏移。第二红外 LED 环形光源会在角膜上留下一个亮环这个亮环的半径和瞳孔半径接近Hough 很容易把它当成瞳孔。第三红外相机的自动增益会随环境光变化同一段视频里瞳孔区域的灰度均值可能漂移 20 到 40 个灰度级固定阈值必然失效。我一般会先做一次 ROI 粗定位把搜索区域压到眼睛附近再在 ROI 内做自适应直方图均衡。注意不要用全局直方图均衡红外视频里背景占了大半全局均衡会把瞳孔对比度拉低。用 CLAHEclipLimit 设 2.0 到 3.0tileGridSize 设 8×8这个组合在 640×480 的红外眼图里比较稳。2.2 预处理链高斯滤波、CLAHE 与形态学开运算下面这段 Python 是我常用的预处理链依赖 OpenCV 和 NumPy。输入是单帧红外灰度图输出是二值化后的瞳孔候选区域。import cv2 import numpy as np def preprocess_ir_eye(frame_gray): # 1) 轻度高斯滤波抑制红外传感器的高频噪声 blur cv2.GaussianBlur(frame_gray, (5, 5), 1.2) # 2) CLAHE 局部对比度增强clipLimit 控制过增强 clahe cv2.createCLAHE(clipLimit2.5, tileGridSize(8, 8)) enhanced clahe.apply(blur) # 3) 自适应阈值blockSize 取奇数C 为常数偏移 binary cv2.adaptiveThreshold( enhanced, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, blockSize31, C8 ) # 4) 形态学开运算去掉睫毛和孤立噪点 kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) opened cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations1) return opened逻辑说明高斯核 5×5、sigma 1.2 是为了在保留瞳孔边缘的同时压掉红外噪点核再大瞳孔边缘会糊。CLAHE 的 clipLimit 超过 3.0 会把眼睑纹理也拉出来后面 Hough 会多出一堆假圆。adaptiveThreshold 的 blockSize 必须大于瞳孔直径31 在 640×480 下对应约 30 像素如果瞳孔在画面里超过 60 像素blockSize 要跟着加到 51 或 61。C 值越大二值化越保守瞳孔区域越小我一般从 8 开始调瞳孔缺失就降到 5噪点多就升到 12。2.3 HoughCircles 的四个关键参数与取值区间预处理完直接上cv2.HoughCircles。这个函数在红外瞳孔检测里最容易被滥用的就是param2很多人默认 30结果要么漏检要么满屏假圆。我的经验是dp设 1.0 到 1.2minDist设瞳孔半径的 1.5 倍param1设 80 到 120param2设 15 到 25。下面是一个可复现的调用示例。def detect_pupil_candidates(binary_img, min_radius8, max_radius40): # HoughCircles 对输入灰度图更敏感这里用二值图也可以 circles cv2.HoughCircles( binary_img, cv2.HOUGH_GRADIENT, dp1.2, minDistmin_radius * 1.5, param1100, # Canny 高阈值 param218, # 累加器阈值越小越容易出假圆 minRadiusmin_radius, maxRadiusmax_radius ) if circles is None: return [] circles np.round(circles[0, :]).astype(int) return circles参数说明dp1.2表示累加器分辨率是图像分辨率的 1/1.2比 1.0 略粗但抗噪更好。minDist如果设得太小同一个瞳孔会出多个同心圆设得太大双眼瞳孔距离近时会漏掉一只。param1是 Canny 边缘检测的高阈值红外图边缘弱设 100 比默认 200 更合适。param2是累加器阈值它和候选圆数量成反比我一般先设 18 跑一遍看假圆数量再微调。minRadius和maxRadius必须根据实际成像距离标定不要照搬。提示如果红外视频里瞳孔半径变化超过 2 倍建议把 Hough 跑两遍第一遍用大范围粗筛第二遍在粗筛结果附近用小范围精筛比一次性设大范围更稳。3. 轮廓匹配怎么把假圆筛掉特征、匹配与打分3.1 为什么 Hough 之后还需要轮廓匹配Hough 只关心“像不像圆”不关心“是不是瞳孔”。红外视频里角膜反光、眼镜框、眼睑弧线都可能被 Hough 检成圆。轮廓匹配的作用是引入形状和灰度分布的先验瞳孔轮廓应该是近似圆形、面积在合理区间、内部灰度均值低于周围环形区域。我一般把 Hough 输出的每个候选圆当作一个 ROI在 ROI 内提取轮廓再和理想瞳孔模板做匹配打分。3.2 轮廓提取与 Hu 矩匹配的代码实现下面这段代码对每个候选圆提取最大轮廓计算 Hu 矩并与理想圆模板做匹配。cv2.matchShapes返回值越小越相似我一般设阈值 0.15超过就丢弃。def extract_contour_score(binary_img, circle): x, y, r circle # 扩展 ROI留出边缘余量 pad int(r * 0.3) x1, y1 max(0, x - r - pad), max(0, y - r - pad) x2, y2 min(binary_img.shape[1], x r pad), min(binary_img.shape[0], y r pad) roi binary_img[y1:y2, x1:x2] contours, _ cv2.findContours(roi, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return 999.0, None # 取面积最大的轮廓作为瞳孔候选 cnt max(contours, keycv2.contourArea) area cv2.contourArea(cnt) if area 20: return 999.0, None # 与理想圆模板做 Hu 矩匹配 ideal_circle np.zeros_like(roi) cv2.circle(ideal_circle, (roi.shape[1] // 2, roi.shape[0] // 2), r, 255, -1) ideal_cnts, _ cv2.findContours(ideal_circle, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not ideal_cnts: return 999.0, None score cv2.matchShapes(cnt, ideal_cnts[0], cv2.CONTOURS_MATCH_I1, 0) return score, cnt逻辑说明pad取半径的 0.3 倍是为了让轮廓完整落在 ROI 内太小会截断瞳孔边缘太大引入眼睑干扰。cv2.RETR_EXTERNAL只取外轮廓避免瞳孔内部反光造成的孔洞干扰。matchShapes的第三个参数用CONTOURS_MATCH_I1它对尺度不敏感适合瞳孔半径变化的情况。阈值 0.15 是我在多个红外数据集上试出来的经验值低于 0.1 会漏掉部分真实瞳孔高于 0.25 假圆明显增多。3.3 灰度分布校验瞳孔暗区与环形亮区的对比光靠形状还不够红外瞳孔有一个稳定特征瞳孔内部灰度均值明显低于周围虹膜环形区域。我一般再算一个对比度分数公式是(ring_mean - pupil_mean) / (ring_mean pupil_mean 1e-6)这个分数大于 0.15 才认为是真瞳孔。下面是对应的代码片段。def gray_contrast_score(gray_img, circle): x, y, r circle mask_pupil np.zeros(gray_img.shape, dtypenp.uint8) cv2.circle(mask_pupil, (x, y), int(r * 0.8), 255, -1) mask_ring np.zeros(gray_img.shape, dtypenp.uint8) cv2.circle(mask_ring, (x, y), int(r * 1.4), 255, -1) cv2.circle(mask_ring, (x, y), int(r * 1.1), 0, -1) pupil_mean cv2.mean(gray_img, maskmask_pupil)[0] ring_mean cv2.mean(gray_img, maskmask_ring)[0] score (ring_mean - pupil_mean) / (ring_mean pupil_mean 1e-6) return score参数说明瞳孔掩膜取 0.8r 是为了避开边缘过渡带环形掩膜取 1.1r 到 1.4r 是为了避开虹膜外沿。如果红外光源角度偏环形区域可能一边亮一边暗这时可以把环形掩膜拆成上下左右四个扇区取中位数而不是均值抗偏光更好。4. 避坑与排查红外瞳孔检测里最常见的五类翻车4.1 瞳孔被高光斑“吃掉”一半现象Hough 检出的圆心明显偏向高光斑一侧瞳孔轮廓缺了一块。原因红外 LED 在角膜上的反光斑和瞳孔区域在二值化后连在一起形态学开运算去不掉。解决先做高光抑制用cv2.inpaint或者简单的灰度截断把灰度大于 240 的像素用周围均值替换再走预处理链。我一般用 3×3 邻域均值替换比 inpaint 快嵌入式上也能跑。4.2 param2 设太低导致满屏假圆现象一帧里检出十几个圆瞳孔只是其中之一。原因param2默认或手动设成了 10 以下累加器阈值太低。解决先把param2提到 20 以上跑一遍确认真瞳孔还在再逐步降到刚好不漏检的值。如果真瞳孔和假圆混在一起降不下来说明预处理没做好回去检查 CLAHE 和自适应阈值的参数。4.3 眨眼帧导致轮廓匹配分数突变现象连续视频里瞳孔坐标在眨眼前后跳变十几像素。原因眨眼时眼睑遮挡瞳孔轮廓变成半圆或月牙形matchShapes分数飙升被误判为假圆丢弃下一帧又恢复坐标就跳了。解决加一个简单的帧间连续性校验如果当前帧没有通过匹配的候选就用上一帧的圆心和半径做预测用卡尔曼滤波或者简单的线性外推补一帧。注意补帧不要超过 3 帧否则会掩盖真实丢失。4.4 红外相机自动增益导致阈值漂移现象同一段视频前 10 秒检测正常后面瞳孔突然检不到。原因相机自动增益把整体灰度拉高自适应阈值的 C 值相对变小二值化后瞳孔区域被压缩。解决关掉相机自动增益或者每 30 帧重新估计一次瞳孔区域灰度均值动态调整 C 值。我一般把 C 值设成max(5, int(0.15 * pupil_mean))让阈值跟着瞳孔灰度走。4.5 轮廓匹配阈值在不同人种上失效现象深色虹膜的被试检测稳定浅色虹膜的被试假圆多。原因浅色虹膜在红外下反射率更高瞳孔和虹膜的灰度对比度下降gray_contrast_score低于 0.15 被误杀。解决把对比度阈值从固定值改成自适应用当前帧 ROI 内灰度直方图的双峰间距来定间距小于 20 灰度级时把阈值降到 0.08。这个改动在浅色虹膜上召回率能提上来但假圆也会略增需要配合轮廓分数一起用。5. 把检测串成视频流水线帧间滤波与精度验证5.1 帧间卡尔曼滤波的轻量实现单帧检测再准视频里也会有抖动。我一般加一个匀速卡尔曼滤波状态量是[x, y, r, vx, vy, vr]观测是 Hough 轮廓匹配输出的[x, y, r]。过程噪声协方差 Q 设 1e-2观测噪声 R 设 5e-1这个组合在 30fps 红外视频里比较跟手。如果不想引入卡尔曼用滑动平均也行窗口取 5 帧但对快速眼跳会有延迟。下面是一个简化的卡尔曼更新片段。import numpy as np class PupilKalman: def __init__(self): self.x np.zeros((6, 1)) # [x, y, r, vx, vy, vr] self.P np.eye(6) * 500 self.F np.eye(6) self.F[0, 3] self.F[1, 4] self.F[2, 5] 1.0 # 匀速模型 self.H np.zeros((3, 6)) self.H[0, 0] self.H[1, 1] self.H[2, 2] 1.0 self.Q np.eye(6) * 1e-2 self.R np.eye(3) * 5e-1 def predict(self): self.x self.F self.x self.P self.F self.P self.F.T self.Q return self.x[:3].flatten() def update(self, z): z np.array(z).reshape(3, 1) y z - self.H self.x S self.H self.P self.H.T self.R K self.P self.H.T np.linalg.inv(S) self.x self.x K y self.P (np.eye(6) - K self.H) self.P return self.x[:3].flatten()逻辑说明F矩阵把速度项耦合到位置项实现匀速预测。Q越小滤波越信任模型眼跳时会滞后Q越大越信任观测抖动会回来。R越大越信任预测适合检测噪声大的场景。我一般先用Q1e-2, R5e-1跑如果眼跳跟踪滞后就把 Q 提到 5e-2。5.2 精度验证用标注数据算中心误差和半径误差验证不要只看“看起来稳不稳”要算指标。我一般手工标注 200 到 500 帧的瞳孔圆心和半径然后算平均中心误差和半径误差。中心误差用欧氏距离半径误差用绝对差。下面是一个批量评估的代码框架。def evaluate_pupil(pred_list, gt_list): center_errors [] radius_errors [] for (px, py, pr), (gx, gy, gr) in zip(pred_list, gt_list): center_errors.append(np.sqrt((px - gx) ** 2 (py - gy) ** 2)) radius_errors.append(abs(pr - gr)) return { center_mae: float(np.mean(center_errors)), center_p95: float(np.percentile(center_errors, 95)), radius_mae: float(np.mean(radius_errors)), radius_p95: float(np.percentile(radius_errors, 95)), }参数说明center_mae反映整体精度center_p95反映最差 5% 帧的稳定性。红外视频里如果center_p95超过center_mae的 3 倍说明有离群帧回去查眨眼和高光斑。半径误差的p95如果超过 3 像素说明 Hough 的minRadius和maxRadius范围设宽了收窄再跑。5.3 一个我常犯的错过度依赖单帧最优早期我总想把单帧检测调到完美param2和匹配阈值反复拧结果换一段视频就崩。后来才明白红外瞳孔检测的稳定性一半来自单帧一半来自帧间。与其把单帧阈值卡到极限不如留一点余量让卡尔曼和连续性校验去补。我现在的习惯是单帧召回率调到 90% 左右就停剩下的交给帧间滤波整体精度反而更高。这个方向值得做但别指望一套参数打天下按场景标定才是正路。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

多通道神经电生理信号的电刺激效应系统性分析详解

多通道神经电生理信号的电刺激效应系统性分析详解

脑电信号处理系列写到第13篇,我打算认真聊一次基于多通道神经电生理信号的电刺激效应系统性分析。这个题目乍一看很学术,实际上你在任何一家做神经调控、脑机接口或者康复医学的实验室里都能碰到同样的问题:给被试施加了某种电刺激之后&#…

2026/10/14 2:11:20 阅读更多 →
Vuls 漏洞扫描器完全指南:Agent-less 架构、多模式扫描与多平台漏洞检测实战

Vuls 漏洞扫描器完全指南:Agent-less 架构、多模式扫描与多平台漏洞检测实战

漏洞扫描网络安全运维 【免费下载链接】vuls Agent-less vulnerability scanner for Linux, FreeBSD, Container, WordPress, Programming language libraries, Network devices 项目地址: https://gitcode.com/gh_mirrors/vu/vuls 点击查看 免费下载 Vuls&#xf…

2026/10/14 2:10:20 阅读更多 →
Nexent 零代码智能体平台部署与核心机制解析:Docker/Kubernetes 私有化部署实战

Nexent 零代码智能体平台部署与核心机制解析:Docker/Kubernetes 私有化部署实战

人工智能AI AgentAgent 编排低代码AI 技能RAG 【免费下载链接】nexent Nexent 是一个开源智能体SDK和平台,能够将描述流程的自然语言转化为完整的多模态服务 —— 无需编排,无需复杂拖拉拽。基于 MCP 工具生态系统构建,Nexent 提供灵活的模型…

2026/10/14 2:10:20 阅读更多 →

最新新闻

VLP平台与重组蛋白:新一代生物技术工具

VLP平台与重组蛋白:新一代生物技术工具

VLP平台的基本概念与技术原理病毒样颗粒(VLP)平台是一种新兴的生物技术工具,它利用重组蛋白自组装形成在结构上模拟天然病毒颗粒的空心颗粒。这些颗粒不含病毒遗传物质,因此不具备复制和感染能力,但保留了病毒的免疫原…

2026/10/14 2:56:30 阅读更多 →
情感表达的艺术:正经话如何撩动人心

情感表达的艺术:正经话如何撩动人心

1. 情感表达的艺术:如何用正经话撩动人心"句句正经,句句撩到心巴"这个标题让我想起十年前刚做情感博主时的一个发现:最动人的情话往往藏在最日常的对话里。当时有位读者留言说,她男朋友在讨论周末买菜时随口说了句"…

2026/10/14 2:56:30 阅读更多 →
不天天开会也能掌握项目进展:异步同步机制设计指南

不天天开会也能掌握项目进展:异步同步机制设计指南

不少团队都卡在这个问题上:不开会怕失控,天天开会又浪费大量时间。尤其项目节奏快的时候,每天固定站会十分钟,看起来不长,但算上打断、切换、延期,实际成本远不止这些。再加上有人请假、有人在外出差、有人…

2026/10/14 2:56:30 阅读更多 →
高企申报里研发费用归集和辅助账总是对不上,我们用一套数据规则解决了

高企申报里研发费用归集和辅助账总是对不上,我们用一套数据规则解决了

做高企申报材料管理的人大概都遇到过这个问题:财务那边出的研发费用归集表,和申报专员手上的辅助账,两边数字对不上。等到申报节点临近,才发现要回头翻几个月的凭证,时间根本来不及。 这不是财务不专业,也…

2026/10/14 2:56:30 阅读更多 →
枚举类型在编程中的核心应用与最佳实践

枚举类型在编程中的核心应用与最佳实践

1. 枚举类型的概念与价值在编程实践中,我们经常会遇到需要定义一组相关常量的场景。比如表示星期几、订单状态、错误码等。传统做法是使用独立的常量定义:public static final int MONDAY 1; public static final int TUESDAY 2; // ... public static…

2026/10/14 2:56:30 阅读更多 →
t3code实战:基于T3 Stack打造端到端类型安全的全栈脚手架

t3code实战:基于T3 Stack打造端到端类型安全的全栈脚手架

t3code这个项目,是我这一年多来投入时间最多、也最满意的一个作品。如果你是个前端或者全栈工程师,大概率已经听说过目前圈子里讨论度很高的 T3 Stack 这一套组合拳——Next.js 打底、TypeScript 贯穿、tRPC 做接口层、Tailwind 写样式、Prisma 管数据库…

2026/10/14 2:55:30 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →