基于YOLOv8与PyQt5的密集人群人体检测识别计数系统设计
2026/9/6 23:49:14 网站建设 项目流程

基于深度学习YOLOv8+PyQt5的密集人群人体检测识别计数系统设计

如果你正在做一个“摄像头画面里到底有多少人”的桌面应用,你会发现一个尴尬的现实:目标检测模型跑通了,但离“能交给别人用”还差得很远。模型输出的只是坐标框和置信度,用户想要的是“当前画面人数”“密度预警”“自动统计结果”。这个从算法到产品的中间地带,正是 PyQt5 这类桌面 GUI 框架的价值所在。

本文要解决的问题很具体:如何把 YOLOv8 人体检测模型封装成一个带界面的密集人群计数系统,支持图片、视频和摄像头实时画面输入,并且在界面上直接看到检测框、人数信息和告警结果。文章涉及模型选型、数据集标注、训练配置、PyQt5 界面设计、推理线程优化、计数逻辑实现以及常见报错排查,读完可以直接对照落地。

项目不会要求你从零训练一个神经网络。YOLOv8 提供了足够好的预训练权重,COCO 数据集里也有 person 这个类别。你要做的核心工作,是把这个开源模型用对、用稳,再用 PyQt5 把它包装成非技术用户也能操作的软件。换句话说,你写的不只是一个算法 Demo,而是一个可交付的桌面工具。

1. 这篇文章真正要解决的问题

人群计数听起来是个小众需求,但在实际工程里出现频率比想象中高很多。商场需要统计各楼层客流,景区需要监控游客密度,校园需要管理食堂和图书馆的人流,安防项目需要判断某个区域是否过度拥挤。这些场景的共同特点是:不能只靠人眼看监控,需要软件自动给出一个可量化的数字,并在人数超过阈值时发出提示。

传统的解决方案大致有两条路。一条是红外对射或闸机方案,能计数但无法感知密度分布,也不知道人群在画面中的具体位置。另一条是纯手工统计,准确率全凭责任心,完全不具备实时性。深度学习目标检测模型出现后,这个问题有了更自然的解法:直接检测画面里的每一个人,画框、计数、定位,一次完成。

但算法只是第一步。很多初学者拿到 YOLOv8 之后跑通了命令行推理,便以为项目已经结束。真正接手实际项目时会发现,模型推理和产品交付之间还隔着好几层:图片路径是写死的,没有交互界面;算法参数改起来要动代码;视频流处理时界面卡死;人数统计结果没有导出;非技术用户根本不会用命令行。这些问题,恰恰是 PyQt5 能解决的。

所以本文的技术路线是:用 YOLOv8 做人体的目标检测,用 PyQt5 构建桌面交互界面,通过 OpenCV 处理图像与视频流,把“检测框叠加展示”和“实时人数统计”串成完整链路。读完这篇文章,你应该能够搭建一个这样的人体检测识别计数系统,理解每个环节为什么这样设计,并且能针对自己的业务场景做替换和修改。

2. YOLOv8 与 PyQt5 的核心概念

2.1 YOLOv8 的检测机制

YOLOv8 是 Ultralytics 团队在 2023 年初推出的目标检测框架,沿用了 YOLO 系列“单阶段、端到端”的设计思路。所谓单阶段,指的是它在一次前向推理中直接回归出目标的类别和位置,而不像传统两阶段检测器那样先产生候选区域再逐个分类。这种做法换来了极快的推理速度,配合 GPU 可以做到实时分析视频流。

YOLOv8 的网络结构大体上可以拆成三个部分:Backbone 负责提取图像特征,Neck 负责融合多尺度特征,Head 负责输出检测结果。Backbone 沿用了 C2f 结构,比 YOLOv5 的 C3 模块拥有更丰富的梯度流,对小目标的特征表达更好;Head 部分采用了 Anchor-Free 的 Decoupled Head,分类和回归分支各自独立,训练收敛更稳定。通俗理解,就是“眼睛”看得更细,“大脑”分工更清晰。

对于人体检测这个具体任务,YOLOv8 的 COCO 预训练模型已经包含了 person 类别。你不需要从随机初始化开始训练,而是可以在预训练权重的基础上做迁移学习,让模型更快地适配自己的数据分布。这里也正好回答一个很多人关心的问题:YOLOv8 跑检测需要 GPU 吗?答案是看场景,用 CPU 也能跑,但实时视频流建议用 GPU。GTX 1660Ti 这类显卡已经能满足 640 分辨率下的实时推理需求,部署时按自己的显存和精度需求选择合适的模型规格就好。

2.2 PyQt5 在视觉系统里的角色

PyQt5 是 Qt5 应用框架的 Python 绑定,常被用来开发带有图形界面的桌面工具。在视觉检测项目里,它承担的职责不只是“画几个按钮和窗口”,还包括:显示视频画面、更新检测框、接收用户参数输入、触发文件选择、管理算法的启停状态。把模型推理和 GUI 放在同一个进程时,最容易出现的问题是画面卡死。

原因在于 PyQt5 的主线程负责事件循环和界面刷新,如果在主线程里直接执行耗时的视频推理循环,界面就失去了响应。解决办法是把推理任务放到 QThread 子线程里,推理完成后通过信号把结果传回主线程更新界面。这是视觉 GUI 开发中最值得重视的架构点,后文会有完整代码演示。

2.3 人体检测和计数的逻辑边界

关于“检测”和“计数”,需要先做一个概念区分。人体检测的目标是找出画面中每个人的包围框,输出形式是 [x1, y1, x2, y2, conf, class_id]。计数则是把检测结果按业务规则汇总成一个数字,例如“当前画面人数”“某个区域内人数”或“一段时间内累计通过人数”。

如果只看静态图片或单帧视频,计数就是统计当前帧检测框的数量。如果要做跨帧累计计数,比如统计一个时间段内经过某个区域的人数,就要引入目标跟踪,比如 YOLOv8 内置的 ByteTrack 或 BoT-SORT。本文先以单帧计数为主,因为这是“识别计数系统”中最基础也最常用的能力;跨帧跟踪会在工程建议中补充说明。

3. 环境准备与前置条件

3.1 操作系统与硬件选择

从项目可行性出发,推荐在 Windows 10/11 或 Ubuntu 20.04 以上系统完成开发,两者在依赖安装上没有本质区别。硬件方面,如果只是验证算法流程,CPU 即可运行,但推理速度会明显偏慢;如果后续要实时处理摄像头画面,建议准备一张 NVIDIA 显卡,并安装与 CUDA 匹配的 PyTorch 版本。关于具体版本,建议以实际安装时 PyTorch 官网给出的 CUDA 对应关系为准。

3.2 创建虚拟环境

新建一个独立的 Python 虚拟环境是必要的。这里推荐 Python 3.8 到 3.10 的版本区间,因为 YOLOv8 和 PyQt5 在这个区间兼容性最成熟。如果系统已经安装了 Anaconda,可以用 conda 创建:

conda create -n crowd_count python=3.9 conda activate crowd_count

如果不使用 Anaconda,也可以用 venv:

python -m venv crowd_count_env crowd_count_env\Scripts\activate

3.3 安装依赖库

激活虚拟环境后,依次安装 PyQt5、OpenCV、Ultralytics、NumPy 以及其他辅助库:

pip install pyqt5 pip install opencv-python pip install ultralytics pip install numpy pip install pillow

这里说明一下各库的用途。PyQt5 用于构建桌面界面;OpenCV 负责读取图片、视频和摄像头画面,也负责在图像上画检测框;Ultralytics 提供 YOLOv8 模型的加载和推理接口;NumPy 是 OpenCV 和 PyTorch 之间图像数据转换的基础;Pillow 则方便在 Qt 界面中转换图像格式。

安装完成后,建议先跑一个最简单的版本确认 YOLOv8 可用:

python -c "from ultralytics import YOLO; model = YOLO('yolov8n.pt'); print(model.names)"

首次执行会自动下载 yolov8n.pt 预训练权重。打印出类别字典后,环境就说明已经通了一半。

4. 整体系统架构与核心流程拆解

一个完整的密集人群检测计数系统,在逻辑上可以拆成三层:输入层、算法层、展示层。输入层解决“图像从哪里来”的问题,支持图片文件、视频文件和摄像头实时画面;算法层负责加载 YOLOv8 模型,对每一帧图像执行推理,筛选出 person 类别,并统计人数;展示层通过 PyQt5 窗口显示原始画面、检测结果叠加画面以及人数信息。

这套架构的推荐调用流程如下:

  1. 用户在 PyQt5 界面中选择输入源:图片、视频或摄像头。
  2. 系统读取一帧图像,转换为 YOLOv8 推理所需的格式。
  3. 模型执行前向推理,返回检测框、置信度和类别 ID。
  4. 程序过滤出类别 ID 等于 person(COCO 中为 0)的目标框。
  5. 在图像上绘制检测框和人数标签,更新界面显示。
  6. 如果人数超过设定阈值,界面给出告警提示。
  7. 用户可随时停止检测,或切换输入源。

这里特别要强调“类别过滤”这一步。YOLOv8 的 COCO 预训练模型能检测 80 类目标,如果不加过滤,画面里的椅子、背包、手机都会出现在检测结果里。项目里要做人体识别,就必须通过类别 ID 只保留 person 类别。

4.1 为什么使用 QThread 而不是在主线程推理

前面已经提到,PyQt5 主线程负责事件循环,如果在主线程里执行 while True 的视频推理循环,窗口会失去响应。哪怕用户只是想把窗口拖一下位置,操作系统也会提示“程序未响应”。

正确的做法是把视频处理放到继承自 QThread 的工作线程中。工作线程每处理完一帧,就通过 Qt 信号把格式转换好的 QImage 和人数结果传递回主线程。主线程只负责接收信号并更新 Label 控件,不执行任何耗时操作。这个模式在 PyQt 图像项目中是最基础也最实用的架构。

5. 完整示例与代码实现

5.1 模型推理工具类

在实际工程中,推荐把模型加载和推理封装成一个独立的模块,方便界面和命令行共用。以下代码定义了一个 PersonDetector 类:

# 文件路径:person_detector.py from ultralytics import YOLO class PersonDetector: def __init__(self, weights_path="yolov8n.pt", conf_thres=0.5): self.model = YOLO(weights_path) self.conf_thres = conf_thres self.person_class_id = 0 # COCO 数据集中 person 的类别 ID 为 0 def detect(self, frame): results = self.model.predict(frame, conf=self.conf_thres, verbose=False)[0] person_boxes = [] for box in results.boxes: cls_id = int(box.cls[0].item()) if cls_id != self.person_class_id: continue x1, y1, x2, y2 = box.xyxy[0].tolist() conf = float(box.conf[0].item()) person_boxes.append({ "bbox": [int(x1), int(y1), int(x2), int(y2)], "conf": round(conf, 3) }) return person_boxes

这段代码的要点有两个。第一,通过cls_id != self.person_class_id过滤非人体目标;第二,把每个检测结果整理成字典列表,后续界面绘制和人数统计都基于这个列表展开。

5.2 使用 OpenCV 画检测框与人数标签

拿到检测框之后,下一步是在原始图像上画出矩形框和文字。建议单独封装函数,让界面代码保持精简:

# 文件路径:draw_utils.py import cv2 def draw_detections(frame, person_boxes): result_frame = frame.copy() for box in person_boxes: x1, y1, x2, y2 = box["bbox"] conf = box["conf"] cv2.rectangle(result_frame, (x1, y1), (x2, y2), (0, 255, 0), 2) label = f"person {conf:.2f}" cv2.putText(result_frame, label, (x1, max(y1 - 10, 0)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) total_count = len(person_boxes) cv2.putText(result_frame, f"Person Count: {total_count}", (15, 40), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 255), 2) return result_frame

如果业务上只需要一个总数,统计len(person_boxes)就够了。如果要求分区计数,可以在绘制函数里增加区域判断逻辑,后续工程建议部分会再展开。

5.3 PyQt5 主窗口设计

主窗口的核心元素包括:显示图像的 QLabel、输入源选择按钮、人数选择阈值、启动停止按钮,以及一个文本区域显示当前人数和状态。以下是一个可运行的主界面代码结构:

# 文件路径:main_window.py import sys import cv2 from PyQt5.QtWidgets import (QApplication, QMainWindow, QLabel, QPushButton, QVBoxLayout, QHBoxLayout, QWidget, QFileDialog, QSpinBox, QTextEdit, QMessageBox) from PyQt5.QtCore import QTimer, Qt from PyQt5.QtGui import QImage, QPixmap from person_detector import PersonDetector from draw_utils import draw_detections class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("人群检测识别计数系统 - YOLOv8 + PyQt5") self.setMinimumSize(960, 640) self.detector = PersonDetector(weights_path="yolov8n.pt", conf_thres=0.5) self.cap = None self.timer = QTimer() self.timer.timeout.connect(self.process_frame) self.video_label = QLabel("请选择图片、视频或摄像头开始检测") self.video_label.setAlignment(Qt.AlignCenter) self.video_label.setStyleSheet("border: 1px solid #ccc; background: #000;") self.btn_image = QPushButton("选择图片") self.btn_video = QPushButton("选择视频") self.btn_camera = QPushButton("打开摄像头") self.btn_stop = QPushButton("停止检测") self.spin_conf = QSpinBox() self.spin_conf.setRange(10, 95) self.spin_conf.setValue(50) self.spin_conf.setSuffix(" %") self.text_log = QTextEdit() self.text_log.setReadOnly(True) self.text_log.setMaximumHeight(120) self._init_ui() self._connect_events() def _init_ui(self): central = QWidget() layout = QVBoxLayout(central) btn_layout = QHBoxLayout() btn_layout.addWidget(self.btn_image) btn_layout.addWidget(self.btn_video) btn_layout.addWidget(self.btn_camera) btn_layout.addWidget(self.btn_stop) btn_layout.addWidget(QLabel("置信度阈值:")) btn_layout.addWidget(self.spin_conf) btn_layout.addStretch() layout.addWidget(self.video_label) layout.addLayout(btn_layout) layout.addWidget(self.text_log) self.setCentralWidget(central) def _connect_events(self): self.btn_image.clicked.connect(self.open_image) self.btn_video.clicked.connect(self.open_video) self.btn_camera.clicked.connect(self.open_camera) self.btn_stop.clicked.connect(self.stop_detection) def update_log(self, message): self.text_log.append(message) def open_image(self): file_path, _ = QFileDialog.getOpenFileName( self, "选择图片", "", "Image Files (*.jpg *.png *.jpeg *.bmp)") if not file_path: return self.stop_detection() frame = cv2.imread(file_path) if frame is None: QMessageBox.warning(self, "错误", "图片读取失败") return self.detector.conf_thres = self.spin_conf.value() / 100.0 person_boxes = self.detector.detect(frame) result_frame = draw_detections(frame, person_boxes) self.show_frame(result_frame) self.update_log(f"图片检测完成,画面人数: {len(person_boxes)}") def open_video(self): file_path, _ = QFileDialog.getOpenFileName( self, "选择视频", "", "Video Files (*.mp4 *.avi *.mov *.mkv)") if not file_path: return self.stop_detection() self.cap = cv2.VideoCapture(file_path) if not self.cap.isOpened(): QMessageBox.warning(self, "错误", "视频打开失败") return self.timer.start(30) self.update_log(f"开始处理视频: {file_path}") def open_camera(self): self.stop_detection() self.cap = cv2.VideoCapture(0) if not self.cap.isOpened(): QMessageBox.warning(self, "错误", "摄像头打开失败,请检查设备") return self.timer.start(30) self.update_log("摄像头已打开") def process_frame(self): ret, frame = self.cap.read() if not ret: self.stop_detection() self.update_log("视频读取完毕或读取失败") return self.detector.conf_thres = self.spin_conf.value() / 100.0 person_boxes = self.detector.detect(frame) result_frame = draw_detections(frame, person_boxes) self.show_frame(result_frame) self.update_log(f"当前画面人数: {len(person_boxes)}") def show_frame(self, frame): rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) h, w, ch = rgb_frame.shape bytes_per_line = ch * w qimg = QImage(rgb_frame.data, w, h, bytes_per_line, QImage.Format_RGB888) pixmap = QPixmap.fromImage(qimg) pixmap = pixmap.scaled(self.video_label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.video_label.setPixmap(pixmap) def stop_detection(self): self.timer.stop() if self.cap is not None: self.cap.release() self.cap = None

这个界面已经具备最基本的功能闭环:选择图片立刻得到检测结果,选择视频或摄像头后定时逐帧处理,停止按钮负责释放资源。show_frame方法里值得注意的一个细节是,OpenCV 的图像格式是 BGR,而 Qt 的 QImage 默认使用 RGB,所以必须先用cv2.cvtColor转换,否则画面中的红色和蓝色会颠倒。

5.4 程序入口

最后提供一个入口文件,便于直接启动:

# 文件路径:main.py import sys from PyQt5.QtWidgets import QApplication from main_window import MainWindow if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())

按照上面的文件结构,person_detector.pydraw_utils.pymain_window.pymain.py放在同一目录即可运行。运行后选择一张包含多人的图片,应该能在界面上看到绿色检测框和红色人数统计文本。

6. 运行结果与效果验证

6.1 运行命令

在激活虚拟环境的前提下执行:

python main.py

6.2 验证流程

第一,验证模型加载。程序启动后,控制台应出现 Ultralytics 的版本信息,且没有报错退出。

第二,验证图片检测。点击“选择图片”,选择一张拍摄于商场、车站或街道的多人照片。预期结果是画面中的人物被绿色矩形框标出,左上角或对应位置显示 person 标签和置信度,画面左上角显示总人数。

第三,验证视频检测。选择一段人流视频,窗口应持续刷新画面,每一帧的人数标签随画面内容变化。如果视频帧率较低,可以调节 QTimer 的间隔,从 30 毫秒调整为 50 毫秒,降低处理频率。

第四,验证置信度阈值。把滑块从 50% 调整到 80%,检测框数量通常会减少,因为低置信度的预测结果被过滤掉了。这一步可以直观体会置信度阈值对结果的影响。

如果运行失败,第一步应该看的不是界面代码,而是命令行窗口中的异常堆栈。常见的几类问题会在下一节集中说明。

7. 常见问题与排查思路

问题现象可能原因排查方式解决方案
启动时提示找不到 ultralytics虚拟环境未激活或依赖未安装执行pip list检查包列表重新执行pip install ultralytics
程序提示找不到 model weights当前目录没有 yolov8n.pt检查项目目录文件列表首次运行会自动下载,或手动下载放入项目目录
界面打开后立即无响应推理被放在主线程,或视频分辨率过高检查代码是否使用了 QTimer 子线程处理确保推理逻辑通过 QTimer 回调执行,而不是在主线程中死循环
图片颜色异常,红色和蓝色对调没有把 BGR 转换为 RGB检查 show_frame 方法添加cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
摄像头打不开摄像头被其他程序占用关闭其他视频软件再试释放摄像头设备后重新打开
检测框覆盖了大量非人体目标没有按类别 ID 过滤 person检查 person_detector.py 中的过滤逻辑确认person_class_id = 0
视频处理很卡CPU 推理速度不足,或图像尺寸过大观察任务管理器的 CPU 占用率降低检测输入尺寸,或使用 GPU 推理
计数结果总是比实际人数多置信度阈值偏低引入误检逐步提高置信度阈值观察结果变化在检测器中设置更高的 conf_thres

8. 最佳实践与工程建议

8.1 数据集准备与模型微调

如果使用 COCO 预训练权重在常规场景下行得通,可以先用默认权重上线。但如果面对的密集人群场景比较特殊,比如俯拍视角的候车大厅,或者光照条件特殊的夜间监控,建议用自己的数据做微调。准备数据时,每一张图片对应一个同名的 txt 文件,每行格式为class_id x_center y_center width height,坐标是相对图片宽高的归一化数值。标注完成后,把数据集按 8:1:1 划分为训练集、验证集和测试集,并准备好 data.yaml 文件:

train: datasets/crowd/images/train val: datasets/crowd/images/val test: datasets/crowd/images/test nc: 1 names: ['person']

训练时可以在 terminal 中执行一条命令:

yolo detect train data=data.yaml model=yolov8s.pt epochs=100 imgsz=640 batch=16

这里选择 yolov8s 而不是 yolov8m 或 yolov8l,是一个偏工程的判断:在人群计数场景中,检测速度的重要性通常不亚于精度。训练完成后,检查 runs/detect/train 目录下的结果曲线,重点关注验证集上的 mAP50 和 Precision、Recall 变化。如果 mAP50 已经超过 0.85,模型基本可以用于试点。

8.2 模型选择与速度权衡

YOLOv8 官方提供了 n、s、m、l、x 五种规格。在人群检测项目里,如果只是希望在普通电脑上跑通 Demo,yolov8n 是最稳妥的选择,体积小、速度快,CPU 也能勉强跑出每秒几帧的效果。如果使用 GPU,且画面里人群密度较高,推荐 yolov8s 或 yolov8m,检测框定位会更准。显存有限时,可以适当降低推理尺寸,比如把 imgsz 从 640 降到 480,速度提升明显,精度损失通常可接受。

另外,YOLOv8 也可以直接在推理时指定设备:

results = self.model.predict(frame, conf=self.conf_thres, device="0", verbose=False)

device="0"表示使用第一张 GPU。

8.3 计数逻辑增强

“检测到人”不等于“统计到人”。如果只是统计当前画面人数,直接数检测框数量即可;但业务常常追问的是“某个区域人数”“某段时间通过多少人”,这就涉及两种增强方案。

第一种是区域计数。在界面上预先设定不计区域或警戒区域,判断检测框中心是否落在目标区域内,只统计区域内的目标。OpenCV 的cv2.pointPolygonTest可以判断一个点是否在多边形内部。

第二种是跨帧计数。画面中同一人连续出现在多帧里,如果每帧都计一次,数字会虚高。解决方案是引入跟踪算法,给每个目标分配一个稳定的 ID,然后根据 ID 去重统计。YOLOv8 的model.track()方法内置了 ByteTrack 跟踪器,可以返回持续的目标 ID,适合做闸机或通道通行统计。

8.4 卡顿优化与线程安全

在实际使用中,视频流卡顿最常见的根源不是模型推理,而是“推理 + 绘制 + 控件更新”挤在主循环里。即便是 QTimer 的定时回调,也不代表所有逻辑都在子线程中。更严格的做法是使用 QThread:工作线程只负责读帧和推理,通过信号发出 QImage 和人数结果;主线程只负责接收信号刷新界面。

在高帧率视频场景下,还要避免“处理速度跟不上显示速度”导致队列积压。简单做法是设定标志位:如果上一帧尚未处理完成,则丢弃当前帧,确保界面显示的是最新结果而不是滞后结果。

8.5 打包发布

如果目标是交付给非技术用户,可以用 PyInstaller 打包成 exe:

pip install pyinstaller pyinstaller -w -F main.py

打包需要注意的是模型文件路径问题。PyInstaller 会把项目文件打包进单文件,但运行时模型文件不会自动解压到程序目录。更稳妥的方式是使用--add-data把权重文件打进包中,并在代码中用相对路径配合sys._MEIPASS动态获取路径。这部分细节比较多,建议在实际部署时单独测试。

9. 总结与后续学习方向

密集人群人体检测识别计数,看起来是个以“检测”为核心的项目,但真正决定系统好用程度的,是工程化能力。YOLOv8 负责看得准,PyQt5 负责交互逻辑,OpenCV 负责图像处理,而把这些组件稳定串在一起的,是对线程模型、数据格式转换、资源释放和错误处理的把握。

从实践角度,建议你按三步走:第一步,跑通本文的完整代码,理解 PyQt5 界面与 YOLOv8 推理的协作关系;第二步,尝试微调模型或优化计数逻辑,让系统更贴合自己的业务场景;第三步,考虑把系统接入真实视频源,比如局域网摄像头 RTSP 流,替换掉当前代码中的本地文件路径。项目发展到这个阶段,你已经不再只是“会用模型”,而是具备了把模型落成产品的能力。

最后补充一个选型判断:本文选择 YOLOv8 而不是更新版本的模型,核心原因在于生态成熟。YOLOv8 在文档、社区案例、TensorRT 部署支持方面都比较完整,适合作为“人体检测识别计数系统”的稳健底座。如果你之后想追求更高精度,可以关注 YOLO11 或引入多头注意力机制等改进思路,但迁移之前,先确保现有的数据、标注和评估流程已经跑通,否则模型换得再快,也很难回答“你的系统到底准不准”这个问题。

如果有条件,建议你把本文示例保存下来,用自己的图片或视频试一次完整的“选择文件 → 检测 → 计数 → 调整阈值”流程。一次实际跑通,胜过十次阅读代码。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询