news 2026/10/1 20:54:25

OpenPose+OpenCV人体形态识别:跌倒检测与动作计数实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenPose+OpenCV人体形态识别:跌倒检测与动作计数实战

简介:面向计算机视觉开发者的完整人体姿态识别项目,基于 Python、OpenCV 与 OpenPose 实现从摄像头或视频流中实时检测人体关键点。资源包为 7z 格式,共 40 个文件,大小约 8.12MB,其中包含 19 个 Python 脚本、12 个 pyc 编译文件、2 个 Markdown 文档、2 个示例图片以及 1 个演示视频。Python 脚本覆盖数据预处理、模型训练、推理检测、关键点提取与可视化全流程,包括train.py、demo.py、val.py等可直接运行的入口,以及models、modules、scripts等子模块;Markdown 文档提供环境配置与在自定义数据集上训练 OpenPose 模型的详细指南,示例图片与演示视频便于直观查看效果。项目还附带 COCO 数据准备脚本、关键点滤波、损失函数、模型定义等模块,可帮助深入理解网络训练与推理机制。已有 7028 人浏览学习,适合运动分析、健身指导、虚拟现实、人机交互和医疗康复等场景,例如教练可通过姿态关键点判断运动员动作是否标准,或用于智能健身设备实现实时动作反馈。

1. 视频和摄像头里识别人体形态:OpenPose 不是终点,形态要靠自己算

养老院走廊尽头有个摄像头,凌晨三点多,老人从床边站起来时身影歪斜了一下。你要在连续几帧里判断出他是不是要跌倒,这就是“视频+摄像头”场景下用 Python、OpenCV、OpenPose 做人体形态算法识别最典型的需求。这套方案的核心不是让 OpenPose 直接输出“跌倒”两个字,而是从视频帧里提取 18 个骨骼关键点,再按几何关系算出躯干倾角、包围盒宽高比、重心移动速度这些形态指标。适合做行为分析、动作计数、安防巡检的小团队快速落地一个低成本原型。

2. 人体形态识别的底层逻辑:从 OpenPose 关键点到形态指标

2.1 OpenPose 输出了什么:关键点顺序与两个模型怎么选

OpenPose 是一个人体姿态估计模型,输出不是“这个人站得好不好”这种结论,而是一组关键点热图。网络有两条分支:一支预测每个关节的置信度热图,另一支预测 PAF(Part Affinity Fields,部位亲和域),用于判断两个关键点之间是不是同一条肢体、属于同一个人。在大多数实际项目里,我们消费的是热图分支,PAF 主要帮官方后处理做多人骨架拼装。用 OpenCV DNN 加载模型时,PAF 分支同样会在 forward 里输出,但分组效果不如官方 C++ 后处理完整,后面避坑章节会专门讲。

最常用的模型是 COCO 18 点,关键点顺序是固定的,索引顺序直接影响后续所有几何计算,贴在这里方便对照查表:

索引部位索引部位
0鼻子9右膝
1脖子10右踝
2右肩11左髋
3右肘12左膝
4右手腕13左踝
5左肩14右眼
6左肘15左眼
7左手腕16右耳
8右髋17左耳

OpenPose 还提供 BODY_25 模型,在 COCO 基础上多了中髋点(索引 8)和脚部关键点,比如大脚趾、小脚趾、脚跟。对步态分析和站立重心判断更有用,但推理量更大,CPU 上会更吃力,模型文件也更大。如果是做跌倒检测、蹲起计数这类以躯干姿态为核心的需求,COCO 18 点已经够用,而且它在 OpenCV DNN 里加载更快、参数更少。

2.2 形态指标不是模型直接给的:角度、倾角、包围盒比例怎么定义

把关键点变成“形态”这一步才是人体形态算法识别真正的工程量。常用的形态指标有三个,全部用几何公式从关键点坐标推算。

第一个是躯干倾角。取左右肩的平均点作为肩部中点,左右髋的平均点作为髋部中点,连线这个向量和图像竖直方向的夹角就是躯干倾角。站直的时候接近 0 度,人慢慢倒向地面时角度增大,躺平时肩和髋处于同一水平线,夹角接近 90 度。跌倒检测最核心的指标就是它。第二个是髋膝角。同一侧的髋、膝、踝三个点,在膝关节处形成的夹角,正常站立接近 180 度,坐下或者屈膝时小于 150 度,这个指标用来区分站立、坐下和倒地。第三个是包围盒宽高比。把所有可见关键点的最小外接矩形算出来,宽度除以高度。站姿宽高比通常小于 0.5,躺姿一般大于 1。

实际写代码时,夹角用向量点积和 atan2 计算,图像坐标系 y 轴向下,计算出的正负号还能表达向左倒还是向右倒。这些几何计算本质上跟 OpenCV 里的直线拟合、角度测量是一套东西,很多做过 opencv 检测直线、骨架提取的同学应该不陌生。关键认知是:模型的输出只是坐标点,形态语义完全由这些后处理公式定义,阈值工程决定最终效果。

2.3 为什么用 OpenCV DNN 加载模型而不是编译官方 OpenPose

网上很多教程会让直接装官方 OpenPose,但那个编译链在 Windows 上非常容易翻车。我最早照着官方文档去编译,卡在 CMake 和 Caffe 依赖链上耗了一整天,最后发现 OpenCV DNN 模块可以直接加载同一个 Caffe 模型文件,代码量反而更少。两套路径对比如下:

方式依赖调试成本CPU 实时性部署体积
官方 OpenPose APICaffe、CMake、cuDNN,推荐 GPU高,编译链长差代码库庞大
OpenCV DNN + caffemodelopencv-python 即可低,改参数方便可接受,降分辨率后能跑两个模型文件加脚本

对环境的要求是 opencv>=4.2,这不是玄学,而是 4.2 之后 DNN 模块对 Caffe 模型的解析更完整,旧版本遇到 prototxt 里的 Reshape 层可能直接崩。OpenCV DNN 的代价是多人场景的关键点分组不如官方后处理精细,所以方案适用边界要提前想清楚:室内单人或者稀疏人群场景,这套组合性价比很高;密集人群且要求精确的多人骨架归属,还是得回到官方推理链路。

3. 环境与模型准备:用 OpenCV DNN 把 OpenPose 模型跑起来

3.1 Python 与 OpenCV 安装:别急着装最新版

很多 Python 入门教程里只会说“pip install opencv-python”,但直接装最新版经常踩坑:新版本 DNN 输出布局可能有调整,opencv-python 和 opencv-contrib-python 混装还会导致 cv2 包冲突。我一般在项目里固定一个已经验证过的组合,而不是追新版本。

# Python 3.9 或 3.10 下跑过的组合 pip install opencv-python==4.8.0.74 pip install opencv-contrib-python==4.8.0.74 pip install numpy

contrib 和主包版本必须保持一致,不然以后想用 cv2.Tracker 之类的扩展模块会出现导入异常。其实只做 DNN 推理不装 contrib 也能跑,但后续目标跟踪、图像处理项目里要加功能时又得补,干脆一次装齐。装完先在命令行里验证一下:

import cv2 print(cv2.__version__)

在 VS Code 里跑的时候还要注意解释器路径,Python 环境配置最常见的问题就是终端里 pip install 装好了,F5 运行时 import cv2 仍然报 no module named 'cv2',原因是 VS Code 选中的解释器和终端里的 Python 不是同一个。检查方法很简单:在 VS Code 右下角看解释器路径,确保和 pip 安装时用的是同一个环境。Windows 上同时装多个 Python 版本时尤其容易出这种问题,报错信息看起来像包没装,实际是解释器选错了。

3.2 模型文件放哪里:pose.prototxt 和 pose.caffemodel 的准备

OpenCV DNN 加载 OpenPose 只需要两个文件:一个描述网络结构的 prototxt,一个保存训练权重的 caffemodel。prototxt 在 OpenPose 开源仓库的 models/pose/coco 目录下可以找到,caffemodel 来自 CMU 官方的 pose_iter_440000 模型发布页。下载后的目录结构建议这样组织:

openpose_cpu/ ├── models/ │ ├── pose.prototxt │ └── pose_iter_440000.caffemodel └── run.py

下载完先看文件大小是否正常,caffemodel 是几百 MB 的文件,如果只有几十 KB 那就是下载被中断或者拿到了网页文件。prototxt 要用文本编辑器打开确认里面有 input_dim 字段,并且网络层名称和 caffemodel 对应。有一个很容易踩的坑是 prototxt 和 caffemodel 不配套,网上能找到各种修改版结构,混用会导致 readNetFromCaffe 不报错但 forward 输出形状异常。验证方式就是直接读一次:

net = cv2.dnn.readNetFromCaffe("models/pose.prototxt", "models/pose_iter_440000.caffemodel") print(net)

这一步不报错才继续往下走。另外路径里尽量不要有中文和空格,readNetFromCaffe 在部分系统上对中文路径支持不好,报错时很难想到是这个原因。

3.3 先跑通单张图片:最小关键点检测脚本

单张图片跑通是整条链路的里程碑,后面所有摄像头逻辑都复用这一段。下面是完整的最小脚本:

import cv2 import numpy as np # 加载模型 proto = "models/pose.prototxt" weights = "models/pose_iter_440000.caffemodel" net = cv2.dnn.readNetFromCaffe(proto, weights) net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV) net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU) # 读图并构建 blob frame = cv2.imread("person.jpg") h, w = frame.shape[:2] blob = cv2.dnn.blobFromImage(frame, 1.0, (368, 368), (127.5, 127.5, 127.5), swapRB=False, crop=False) net.setInput(blob) outs = net.forward() # outs 形状:(1, 18, 46, 46),46 是 368 的 1/8 num_points = outs.shape[1] points = [] for i in range(num_points): heatmap = outs[0, i] _, conf, _, pt = cv2.minMaxLoc(heatmap) if conf > 0.1: x = int(pt[0] * w / heatmap.shape[1]) y = int(pt[1] * h / heatmap.shape[0]) points.append((x, y, conf)) cv2.circle(frame, (x, y), 4, (0, 255, 0), -1) cv2.imwrite("out.jpg", frame)

逻辑说明:blobFromImage 的第二个参数 1.0 表示不对像素做缩放,第三个参数 (368, 368) 是网络输入尺寸,mean 传 (127.5, 127.5, 127.5) 是 OpenPose 训练时用的标准化方式,千万不要用 ImageNet 那套均值,否则热图响应值会整体偏低。swapRB=False 是因为 Caffe 模型按 BGR 顺序训练,crop=False 表示图片直接拉伸到 368,而不是中心裁剪。

forward 之后 outs 的形状是 (1, 18, 46, 46),46 是输入尺寸 368 经过网络步长 8 下采样得到的。每个通道是一张关键点热图,cv2.minMaxLoc 找出热图里响应最强的位置和置信度 conf。坐标缩放要用原图尺寸除以热图尺寸,即 w/46 和 h/46,不能直接乘固定倍数,因为原图到 368 是等比拉伸,但不同帧的宽高比不同,固定倍数会偏。

阈值 0.1 是经验值。近距离单人场景建议提到 0.3 减少乱跳,远景小人保持 0.1 仍然可能漏检。如果所有关键点都检不出来,先检查 mean 和 swapRB 设置,再看输入图片是不是被过度压缩。

3.4 把摄像头和视频文件统一成一个数据源

视频文件和摄像头在 OpenCV 里是同一个接口,只需改 VideoCapture 的入参。这块代码可以直接套用:

source = 0 # 0 是默认摄像头;改成 "test.mp4" 就是视频文件 cap = cv2.VideoCapture(source, cv2.CAP_DSHOW) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720) cap.set(cv2.CAP_PROP_FPS, 30) while True: ok, frame = cap.read() if not ok: break # 复用 3.3 的模型 forward 逻辑 points = detect_pose_points(net, frame) # 后续接形态指标计算 cv2.imshow("pose", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release()

代码说明:Windows 下第二个参数传 cv2.CAP_DSHOW 可以绕过系统默认的 MSMF 后端,解决一部分摄像头打不开或延迟高的问题。Linux 下不用传这个参数,V4L2 是默认后端。source 传 0 是默认摄像头,插了多个 USB 摄像头时可以试 1、2、3。

设置分辨率时要注意,很多 UVC 摄像头只认固定档位,设置 1280x720 后最好读回来确认:

print(cap.get(cv2.CAP_PROP_FRAME_WIDTH))

如果设置不生效,画面会以默认档位输出。还有局域网 RTSP 拉流中断的问题,摄像头地址突然断流时 cap.read() 会持续返回 False,常见做法是轮询 cap.isOpened(),检测到断开就重新创建 VideoCapture,同时设置 CAP_PROP_OPEN_TIMEOUT_MSEC 和 CAP_PROP_READ_TIMEOUT_MSEC 两个超时参数,避免拉流卡死。这个坑在接网络摄像头时几乎一定会遇到,提前写成重连逻辑能省很多事。

4. 人体形态算法识别实战:跌倒判定和动作计数怎么做

4.1 关键点的几何计算函数:夹角与重心

拿到关键点之后,首要任务是封装几何工具函数。下面是两个最常用的计算函数:

import math import numpy as np def calc_angle(a, b, c): """关键点 a-b-c,返回 b 点处的张角(度)""" v1 = (a[0] - b[0], a[1] - b[1]) v2 = (c[0] - b[0], c[1] - b[1]) dot = v1[0] * v2[0] + v1[1] * v2[1] cross = abs(v1[0] * v2[1] - v1[1] * v2[0]) return math.degrees(math.atan2(cross, dot)) def center_of(points, indexes): """多个可见关键点取平均中心,返回 (x, y) 或 None""" pts = [points[i] for i in indexes if i < len(points) and points[i][2] > 0.1] if not pts: return None return (int(np.mean([p[0] for p in pts])), int(np.mean([p[1] for p in pts])))

calc_angle 用 atan2(cross, dot) 而不是直接用 acos(dot / norm),原因是 dot 在浮点计算下可能超出 [-1, 1] 范围,导致 acos 报 nan。atan2 对接近 0 度和 180 度都更安全。center_of 里的置信度过滤 0.1 跟前面热图阈值保持一致,如果某些关键点置信度低,直接丢弃而不是参与平均,否则会把中心点拉偏。

这两个函数是后面所有形态指标的地基。只要 points 数组结构统一为 (x, y, conf),无论换 BODY_25 还是换其他姿态模型,上层计算逻辑都可以复用。我现在做姿态相关项目,第一步永远是先把这两个函数放进一个 geom_utils.py,后面所有业务逻辑都从这里面调。

4.2 跌倒检测判定:阈值组合与生效条件

跌倒判定不能靠单帧,必须用时间窗口。单帧躯干倾角大可能是弯腰捡东西,也可能是伸懒腰。所以需要组合指标加上持续帧数确认。下面是一段可运行的判定核心:

from collections import deque def trunk_angle(points): """躯干与竖直方向的夹角""" mid_shoulder = center_of(points, [2, 5]) # 左右肩 mid_hip = center_of(points, [8, 11]) # 左右髋 if mid_shoulder is None or mid_hip is None: return None dx = mid_shoulder[0] - mid_hip[0] dy = mid_shoulder[1] - mid_hip[1] norm = math.hypot(dx, dy) + 1e-6 # 与竖直方向 (0, 1) 的夹角 return math.degrees(math.acos(max(-1.0, min(1.0, dy / norm)))) def bbox_ratio(points): """关键点包围盒宽高比""" xs = [p[0] for p in points if p[2] > 0.1] ys = [p[1] for p in points if p[2] > 0.1] if len(xs) < 3: return None return (max(xs) - min(xs)) / (max(ys) - min(ys) + 1e-6)

判定逻辑建议这样组织:维护一个最近 5 帧的 deque,存储每一帧的 trunk_angle、bbox_ratio 和身体中心点。身体中心点可以用肩髋四个点的均值。当连续 3 帧中至少 2 帧满足下面三个条件时,进入“可疑跌倒”状态,再持续 1 秒确认报警:

参数建议值说明
躯干倾角大于 45 度躯干接近水平
包围盒宽高比大于 1.0身体宽度超过高度
中心点下移速度大于 20 像素/帧720p 下的快速倒地速度

三个条件里,倾角负责描述“身体歪了”,宽高比负责描述“已经接近水平”,速度负责描述“快速发生”。单独用任何一个都会产生大量误报。比如弯腰捡东西时倾角可能大于 45 度,但宽高比不会反转;人躺在沙发上睡觉时宽高比大于 1,但速度接近 0。组合判断加时间确认,误报率能压到可接受范围。

阈值不是固定的,要根据摄像头安装高度和视角调整。俯视摄像头和水平视角的摄像头,同一个动作的躯干倾角差异很大。我一般先把阈值调宽松,录一段包含正常活动的视频离线跑,统计误报后再逐步收紧。

4.3 动作计数和形态识别的通用套路:状态机

跌倒本质上是一个状态变化过程:站立、正在倾倒、倒地。动作计数比如深蹲,也是一样的状态机套路,用一维指标的时间曲线切分状态。

state = "STAND" count = 0 stand_y = None for points in frame_stream: hip = center_of(points, [8, 11]) if hip is None: continue hip_y = hip[1] if stand_y is None: stand_y = hip_y if state == "STAND" and hip_y > stand_y + 60: state = "DOWN" elif state == "DOWN" and hip_y < stand_y + 10: state = "UP" count += 1 stand_y = hip_y

这里的逻辑是:用髋部高度做相位。深蹲时髋部下降超过 60 像素进入 DOWN 状态,回到接近站立基准时认为完成一次并计数。stand_y 会动态更新,适应人在画面里缓慢移动造成的高度漂移。相对距离而不是绝对像素,能容忍人离摄像头远近不同。

这个套路可以平移到很多动作计数需求上,比如引体向上用下巴高度做相位,走路步数用髋部垂直振荡做相位。形态识别的现场需求大部分用状态机就能解决,不需要一上来就上 LSTM。时间序列模型在数据量不够时反而容易过拟合,状态机至少你能解释每一帧的判定依据。

5. 摄像头视频识别实操避坑:从打不开摄像头到关键点乱飘

5.1 摄像头打不开或画面花屏

现象:cv2.VideoCapture(0) 返回 False,或者画面出现撕裂、偏色、只有一半能显示。

原因:设备索引不对是最大的可能。笔记本自带摄像头、外接 USB 摄像头、采集卡各自占用一个索引,你以为的 0 不一定是摄像头。另一个是 Windows 默认的 MSMF 后端和部分 UVC 设备的兼容性差,表现为能打开但帧率为 0。此外多个 USB 摄像头同时插在同一个 USB 2.0 口上,带宽会被瓜分,出现画面撕裂。

解决:先写一个枚举脚本,循环打开 0 到 9 的索引,打印每个索引的 isOpened 结果和分辨率。Windows 下创建 VideoCapture 时显式传 cv2.CAP_DSHOW。多摄像头需求优先用 USB 3.0 接口,或者走采集卡,并且在代码里把分辨率统一降到 720p,带宽压力会明显减小。

提示:摄像头的“花屏”问题,先换一根短一点的 USB 线试试,线材质量差会导致数据错误,这类问题经常和代码无关。

5.2 关键点乱飘:热图阈值和分辨率的关系

现象:人站着不动,手腕和脚踝关键点却在身体附近抖动,置信度数字忽高忽低,画出来的骨架像得了帕金森。

原因:一是输入分辨率不够。网络输入是 368,远景小人在缩放后可能只占十几个像素,关键点热图根本分不清关节还是背景。二是热图阈值设得太低,背景噪声被当成关键点。三是运动模糊,摄像头帧率低时快速挥手,边缘糊成一片,热图峰值位置不稳定。

解决:优先提高输入分辨率,从 368 提到 432,关键点稳定性有明显改善,代价是推理时间增加。其次把阈值从 0.1 提到 0.3,宁可漏检也不乱检,漏检可以通过时间平滑补回来。如果画面里人比较小,先做人形检测框,把 ROI 裁剪出来放大再送 OpenPose,比直接全图检测效果好得多。这是我在 opencv 图像处理项目里最常用的优化手段。

5.3 CPU 掉帧严重:先降分辨率再降什么

现象:720p 摄像头接入后,处理帧率不到 5 帧,画面看起来像 PPT,关键点动画一顿一顿。

原因:OpenPose 的前向推理在 CPU 上是主要开销。输入图 720p 要缩放成 368,网络本身有 18 层 VGG 风格的卷积,每帧都要算 18 张热图,单帧推理在普通桌面 CPU 上要几百毫秒。

解决:第一个动作是降输入尺寸,368 降到 256,帧率能提升接近一倍,形态判定用的倾角、宽高比对分辨率不敏感,损失不大。第二个动作是跳帧,每处理一帧就跳 2 到 3 帧,配合上一章的时间窗口,判定效果比强行追求每帧都算更平滑。第三个动作是换带 CUDA 的 OpenCV 构建,打开 DNN_BACKEND_CUDA,但这需要显卡和配套的预编译包。不要急着上多线程,OpenCV DNN 的 forward 在多线程上如果没有 OpenMP 支持,收益很有限,还容易把帧率搞得更乱。

5.4 多人目标张冠李戴:关键点归属错乱

现象:两个人交叉走过,骨架突然左右互换,A 的左手接到了 B 的肩膀上,形态指标瞬间跳变。

原因:OpenCV DNN 加载 OpenPose 的 caffemodel 时,拿到的是热图和 PAF 的原始输出,多人骨架的分组匹配没有官方 C++ 后处理那么完整。当两个人距离近、肢体交错时,关键点归属关系很容易错。

解决:给每个人做中心关联。用上一帧的颈部和髋部中心预测当前帧位置,然后和当前帧检测到的人做最近邻匹配,贪心匹配就能在大多数场景下维持 ID 稳定。更稳一点是改用 BODY_25 模型,利用中髋点作为人体根节点,归属关系比 COCO 模型更可靠。如果业务场景允许,最省事的办法是限制单人场景,用一个人体检测框把最大的人框出来,其他人直接忽略。很多室内监控场景本来就是单人活动,没必要为不存在的多人需求增加复杂度。

6. 效果验证与进阶:时间平滑、CUDA 加速和回归测试

6.1 用同一段录制视频做回归测试

形态识别的效果不能靠盯着画面看感觉,要靠漏报率和误报率说话。我现在每个项目都会保留一段 regress.mp4,里面固定包含站立、走路、弯腰捡东西、坐下、倒地这几个动作,每次改完阈值就重跑同一段视频,把结果逐帧写入 JSON:

{ "frame_id": 102, "trunk_angle": 48.3, "bbox_ratio": 1.1, "falling": true }

跑完用播放器逐帧对照,统计该报警没报的有几帧,不该报警报了的又有几帧。改阈值后重新跑一遍,数值变差了就说明改法有问题。没有这个回归流程,调参基本靠玄学,今天改好了明天又坏。

6.2 关键点时间平滑与 CUDA 加速

关键点乱飘的最后一层防线是时间平滑。最简单的是 EMA 指数平滑:新值 = alpha * 观测值 + (1 - alpha) * 旧值。alpha 取 0.3 到 0.5 之间,太小跟随慢,太大会让抖动直接透传。对每个关键点的 x 和 y 分别平滑,骨架动画立刻稳下来。

更正式的做法是用 OpenCV 自带的 cv2.KalmanFilter,状态设为四维 (x, y, dx, dy),测量噪声和过程噪声需要现场调。多数场景 EMA 够用,卡尔曼的优势是能预测下一帧位置,对多人做目标关联时有额外价值。

加速方面,先确认当前 OpenCV 是否带 CUDA 支持:

print(cv2.buildInformation())

如果编译选项里没有 CUDA,可以找带 CUDA 的预编译 wheel 或自己用 CMake 编译,然后再设置:

net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)

显存占用方面,4GB 的显卡跑 368 输入没有问题,再往上调输入尺寸就会吃紧。没有显卡也不要强求,CPU 方案把分辨率降到 256 加跳帧,在单人或稀疏人群场景下也能支撑形态识别这类慢业务。

这套方案我前后用在两个项目上,一个是老人活动状态监测,一个是康复训练动作计数。最大的体会是 OpenPose 决定的是天花板,你能从它那里拿到关键点坐标;而形态识别的下限全部在指标定义、阈值组合、时间平滑这三件事上。先跑通单张图,再做时间域处理,最后才接摄像头实时流。不要一上来就对着摄像头调参数,那样分不清是成像问题还是算法问题。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 20:51:38

Herringbone节点:分布式系统中的高可靠容错拓扑模式

1. Herringbone节点的基本概念与设计思路1.1 什么是Herringbone节点先直接说结论&#xff1a;Herringbone节点并不是某个特定软件里的固定组件&#xff0c;而是一种在分布式系统中被反复验证过的节点组织模式。名字来源于人字形编织纹样——如果你把多个节点按照交错、斜向连接…

作者头像 李华
网站建设 2026/10/1 20:49:47

亚远景-ASPICE评估实践:工作产物评审,分清评审、会商、技术研讨,避免把研讨记录充当正式评审证据

ASPICE GP 通用实践当中明确对工作产物评审提出要求&#xff0c;各类需求、架构、测试等工作产物&#xff0c;需要开展正式评审&#xff0c;留存对应的证据。项目里技术研讨、方案沟通非常频繁&#xff0c;很多工程师分不清研讨和正式评审的边界。技术会上大家讨论方案可行性、…

作者头像 李华
网站建设 2026/10/1 20:49:30

办公效率神器 OpenClaw:用 TaoToken 统一 Key 打通文件与浏览器自动化

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

作者头像 李华