news 2026/9/28 8:11:36

YOLOv5+轻量CNN实现人脸情感识别实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
YOLOv5+轻量CNN实现人脸情感识别实战指南

简介:本资源是一套基于YOLOv5实现的面部情感表情检测识别完整Python项目源码,面向计算机视觉初学者与课程设计学生,解决人脸区域定位与七类基础情绪(如高兴、愤怒、悲伤等)实时识别问题,适用于课堂实践、大作业开发及轻量级情感分析原型搭建。压缩包共84个文件,包含23个核心Python脚本(含detect_photo.py、detect_camera.py等推理入口)、23个YAML配置文件(涵盖数据集定义、超参微调与不同模型尺寸配置)、24个编译后pyc文件,以及Dockerfile、Shell下载脚本和示例测试图像,整体仅1.06MB,轻量易部署。已有185人学习下载,项目经助教审定、本地全链路验证,评审得分95分以上,提供可直接运行的训练-推理全流程代码、清晰模块化目录结构(models/datasets/utils/runs等)、预置权重下载工具及多格式测试样例,显著降低复现门槛与调试成本。

1. 为什么用 YOLOv5 做面部情感表情检测不是“大炮打蚊子”,而是当前最稳的落地选择?

你可能刚搜到这个标题时心里一咯噔:YOLOv5 不是干目标检测的吗?人脸检测还说得过去,但“高兴”“悲伤”“惊讶”这种细粒度情感分类,不该交给 ResNet、ViT 或者专门的 FACET、Affectiva 这类模型吗?——这恰恰是多数人翻车的第一步:把「检测」和「识别」混为一谈。这个项目标题里藏着一个关键设计逻辑:它不是端到端输出“这张脸是愤怒”,而是先用 YOLOv5 定位人脸(Detection),再在裁剪出的人脸 ROI 上跑轻量级 CNN 分类器(Classification)。整个 pipeline 是解耦的、可调试的、对算力友好的。实测在 GTX 1660 Ti 上,单帧处理耗时稳定在 42–48ms(含预处理+检测+裁剪+分类+后处理),远优于把整图塞进 ViT-L 的 120ms+。它适合的是真实场景:边缘设备部署、课堂情绪反馈系统、客服质检抽帧分析、甚至嵌入式摄像头实时标注。不是论文刷榜,而是工程能上线、客户愿意签验收单的那种“高分”——指模型在自建测试集上达到 89.3% 加权 F1,推理延迟可控,训练过程不依赖多卡 A100,一台带 GPU 的笔记本就能从零训完。如果你正被“情感识别准确率上不去”“部署卡在 ONNX 转换失败”“数据少导致过拟合”这些问题卡住,这篇笔记就是为你写的实战手记。


2. 从 ZIP 解压到本地可运行:三步走通最小验证闭环

这个.zip包不是简单扔个train.py就完事。我拆开看过结构,核心是detect_emotion.py(主推理脚本)、models/(含 yolov5s-face.pt 和 emotion_classifier.pth)、data/(含预处理后的 face-emotion.yaml)、以及utils/下的专用后处理模块。它没用 ultralytics 官方库的最新版,而是锁在yolov5==6.1(注意不是 7.x 或 8.x),这是关键兼容点。下面带你用最简路径跑通第一帧检测——不装 CUDA 驱动?没关系,CPU 模式也能跑,只是慢点;没摄像头?用自带的test_images/里的smile.jpg就行。

2.1 环境隔离与依赖安装:conda + requirements.txt 的精准控制

别急着pip install -r requirements.txt。这个项目 requirements.txt 里写了torch==1.10.2+cu113,但你的显卡可能是 RTX 4090(需要 cu118)或 Mac M2(需要 MPS)。正确做法是先创建干净环境,再按需装 torch:

# 创建 Python 3.8 环境(YOLOv5 v6.1 最稳) conda create -n yolo-emotion python=3.8 conda activate yolo-emotion # 根据你的硬件选装 torch(官方推荐方式,避免版本错配) # ✅ NVIDIA 显卡(CUDA 11.3): pip3 install torch==1.10.2+cu113 torchvision==0.11.3+cu113 torchaudio==0.10.2 -f https://download.pytorch.org/whl/torch_stable.html # ✅ CPU-only(开发调试用): pip3 install torch==1.10.2+cpu torchvision==0.11.3+cpu torchaudio==0.10.2 -f https://download.pytorch.org/whl/torch_stable.html # ✅ Apple Silicon(M1/M2): pip3 install torch torchvision torchaudio

提示:torch==1.10.2是硬性要求。我试过升到 1.12,yolov5/models/common.py里Conv类的__init__方法签名变了,直接报TypeError: __init__() got an unexpected keyword argument 'act'。这不是 bug,是 YOLOv5 v6.1 的历史包袱,接受它,别硬改。

装完 torch 后,再装其他依赖:

pip install numpy opencv-python==4.5.5.64 tqdm matplotlib scikit-learn pandas # 注意:不要装 ultralytics!这个项目用的是 fork 自 v6.1 的私有 models/ 目录,和 ultralytics 库冲突

2.2 数据配置文件解析:face-emotion.yaml 里藏着三个易错参数

data/face-emotion.yaml是整个 pipeline 的“地图”,它不只定义类别,更控制 ROI 裁剪逻辑。打开它,重点看这三行:

train: ../datasets/emotion/train/images val: ../datasets/emotion/val/images nc: 7 # number of classes names: ['Anger', 'Disgust', 'Fear', 'Happy', 'Neutral', 'Sad', 'Surprise']

⚠️ 注意:这里的train和val路径是相对路径,基准目录是yolov5/根目录(即你解压 ZIP 后看到detect_emotion.py的那个文件夹)。很多人解压后直接双击运行,Python 工作目录是桌面,结果报FileNotFoundError: [Errno 2] No such file or directory: '../datasets/emotion/train/images'。
✅ 正确做法:终端 cd 进yolov5/目录后再运行:

cd /path/to/your/unzipped/yolov5/ python detect_emotion.py --source test_images/smile.jpg --weights weights/yolov5s-face.pt --emotion-weights weights/emotion_classifier.pth --conf 0.4

--conf 0.4是关键阈值:YOLOv5 检测人脸框的置信度下限。设太低(如 0.1)会框出大量模糊、侧脸、遮挡人脸,导致后续情感分类器输入质量差;设太高(如 0.7)又会漏掉微表情。我们后面调参就从这里开始。

2.3 第一帧推理:看懂输出日志里的四个关键信息

运行成功后,你会看到类似这样的终端输出:

image 1/1 /path/to/test_images/smile.jpg: 640x480 1 face, 23.5ms Results saved to runs/detect/exp Emotion prediction: Happy (0.92)

拆解这四行:

  • 640x480 1 face:输入图像尺寸 + YOLOv5 检测到的人脸数。如果显示0 face,先检查图片是否真有人脸(别用纯色背景图测试),再检查--conf是否设太高;
  • 23.5ms:YOLOv5 检测阶段耗时(GPU 模式),不含情感分类时间;
  • Results saved to runs/detect/exp:检测框可视化图保存路径,打开runs/detect/exp/smile.jpg就能看到带绿色框和Happy标签的图;
  • Emotion prediction: Happy (0.92):这是分类器输出,括号内是该类别的 softmax 概率,不是置信度阈值。注意:它只对检测框内的人脸做预测,且默认只输出概率最高的一类。如果一张图有 3 张脸,它会输出 3 行Emotion prediction。

逻辑说明:detect_emotion.py内部流程是:① 用yolov5s-face.pt推理得到 bbox 坐标;② 对每个 bbox,用cv2.resize()裁剪并归一化为 224×224;③ 输入emotion_classifier.pth(一个 7 层 CNN,结构见models/emotion_net.py);④ 取torch.nn.functional.softmax(output, dim=1)最大索引对应names列表中的类别。所以Happy (0.92)意味着模型对这张脸是“高兴”的把握有 92%,不是 92% 准确率。


3. 训练自己的情感数据集:从标注到收敛的完整链路

“高分项目”之所以高分,不在于用了什么黑科技,而在于它提供了一套可复现的数据准备规范。你不可能靠网上随便扒的 FER2013 或 RAF-DB 直接训出好效果——光照、姿态、分辨率、背景杂乱度全都不匹配。必须用自己的数据。下面是我用 3 天时间采集 800 张办公室员工真实表情图,最终在验证集上把Happy类召回率从 72% 提升到 91% 的实操路径。

3.1 标注规范:为什么不用 LabelImg,而坚持用 CVAT + 自定义 JSON 导出

YOLOv5 v6.1 的train.py只认两种格式:①images/xxx.jpg+labels/xxx.txt(每行class_id center_x center_y width height,归一化);②images/xxx.jpg+labels/xxx.json(COCO 格式)。但情感数据有个致命问题:同一张图里多人脸,不同人脸表情可能完全不同。LabelImg 只能画框、填 class,无法关联“第 2 个框是张三,他此刻在皱眉”。CVAT 支持 track ID 和 attribute(比如加个emotion: anger字段),导出 COCO JSON 后,用utils/coco2yolo.py脚本一键转成 YOLO 格式:

# utils/coco2yolo.py 关键逻辑(已包含在 ZIP 中) import json import cv2 from pathlib import Path def convert_coco_to_yolo(coco_json, img_dir, out_label_dir): with open(coco_json) as f: data = json.load(f) # 构建 image_id -> filename 映射 img_map = {img['id']: img['file_name'] for img in data['images']} for ann in data['annotations']: img_id = ann['image_id'] img_name = img_map[img_id] img_path = Path(img_dir) / img_name img = cv2.imread(str(img_path)) h, w = img.shape[:2] # YOLO 格式:class_id, x_center, y_center, width, height(全部归一化) x1, y1, bw, bh = ann['bbox'] # COCO 是 [x,y,width,height] xc = (x1 + bw/2) / w yc = (y1 + bh/2) / h bw_norm = bw / w bh_norm = bh / h # class_id 来自 categories,确保顺序和 face-emotion.yaml 一致 cls_id = ann['category_id'] # 注意:COCO category_id 从 1 开始,YOLO 从 0 开始 line = f"{cls_id-1} {xc:.6f} {yc:.6f} {bw_norm:.6f} {bh_norm:.6f}\n" # 写入 labels/xxx.txt label_path = out_label_dir / f"{Path(img_name).stem}.txt" with open(label_path, "a") as f: f.write(line)

参数说明:coco_json是 CVAT 导出的annotations.json;img_dir是你存图的文件夹(如datasets/emotion/train/images);out_label_dir是datasets/emotion/train/labels。运行一次,所有.txt就生成好了。血泪经验:CVAT 导出前务必勾选 “Include images” 和 “Export annotations only for annotated frames”,否则会导出空 JSON。

3.2 数据增强策略:为什么默认的 augmentations.yaml 要删掉hsv_h和hsv_s

YOLOv5 v6.1 的data/hyp.scratch.yaml默认开启 HSV 色彩扰动(hsv_h: 0.015,hsv_s: 0.7)。这对通用目标检测有效,但对情感识别是灾难——把一张“恐惧”脸的苍白肤色调成潮红,模型就学歪了,把“恐惧”和“愤怒”混淆。我做了对照实验:A 组用默认 hyp,B 组关闭 hsv_h/s,其他不变,训练 100 epoch 后,B 组在验证集上的Fear类 F1 提高了 11.2 个百分点(从 63.5 → 74.7)。

✅ 正确做法:复制data/hyp.scratch.yaml为data/hyp.emotion.yaml,修改如下:

# data/hyp.emotion.yaml lr0: 0.01 # initial learning rate (SGD=1E-2, Adam=1E-3) lrf: 0.1 # final OneCycleLR learning rate (lr0 * lrf) momentum: 0.937 # SGD momentum/Adam beta1 weight_decay: 0.0005 # optimizer weight decay 5e-4 warmup_epochs: 3.0 # warmup epochs (fractions ok) warmup_momentum: 0.8 # warmup initial momentum warmup_bias_lr: 0.1 # warmup initial bias lr box: 0.05 # box loss gain cls: 0.5 # cls loss gain cls_pw: 1.0 # cls BCELoss positive_weight obj: 1.0 # obj loss gain (scale with pixels) obj_pw: 1.0 # obj BCELoss positive_weight iou_t: 0.20 # IoU training threshold anchor_t: 4.0 # anchor-multiple threshold # 暂时禁用 HSV 扰动,专注学习纹理和几何特征 hsv_h: 0.0 # image HSV-Hue augmentation (fraction) hsv_s: 0.0 # image HSV-Saturation augmentation (fraction) hsv_v: 0.4 # image HSV-Value augmentation (fraction) degrees: 10.0 # image rotation (+/- deg) translate: 0.1 # image translation (+/- fraction) scale: 0.4 # image scale (+/- gain) shear: 0.0 # image shear (+/- deg) perspective: 0.0 # image perspective (+/- fraction), range 0-0.001 flipud: 0.0 # image flip up-down (probability) fliplr: 0.5 # image flip left-right (probability) mosaic: 1.0 # image mosaic (probability) mixup: 0.1 # image mixup (probability) copy_paste: 0.0 # segment copy-paste (probability)

为什么保留hsv_v: 0.4?因为亮度变化(Value)模拟了不同光照条件(办公室顶灯 vs 窗边自然光),这对泛化至关重要。而 Hue/Saturation 是色彩语义,情感不靠这个判断。

3.3 训练命令与关键监控指标:如何判断是不是在“假收敛”

别迷信train.py输出的train/cls_loss数字。情感识别最关键的指标是per-class recall,尤其对小样本类(如Disgust,Fear)。启动训练:

python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data/face-emotion.yaml \ --cfg models/yolov5s-face.yaml \ --weights weights/yolov5s-face.pt \ --name emotion_train_v1 \ --hyp data/hyp.emotion.yaml \ --cache

--cache是必选项:它把所有图像预加载进内存,避免 IO 瓶颈拖慢训练。训练中重点关注runs/train/emotion_train_v1/results.csv的最后几行:

epochtrain/box_losstrain/cls_lossval/box_lossval/cls_lossmetrics/precisionmetrics/recallmetrics/mAP_0.5metrics/mAP_0.5:0.95
980.02310.11240.03150.14870.8720.8510.8230.512
990.02280.11190.03120.14790.8730.8530.8240.513
1000.02250.11150.03100.14720.8740.8540.8250.514

✅ 健康信号:val/cls_loss持续下降,metrics/recall稳步上升,且mAP_0.5:0.95(严格 IoU)> 0.5。
❌ 危险信号:val/cls_loss在 80 epoch 后持平甚至反弹,但train/cls_loss还在降 → 过拟合。此时立刻停训,用--evolve进化超参,或增加mosaic: 0.8(原为 1.0)来提升多样性。


4. 避坑指南:YOLOv5 面部情感检测的 4 个高频翻车现场

这些坑我都踩过,有些甚至重装系统三次才定位清楚。列在这里,帮你省下至少 12 小时 debug 时间。

4.1 现象:detect_emotion.py运行时报AttributeError: 'NoneType' object has no attribute 'shape'

原因:cv2.imread()返回None,通常是因为图片路径错误,或图片损坏(常见于 Windows 下路径含中文、空格、括号)。YOLOv5 v6.1 的datasets.py没做 robust check,直接对None调img.shape。
解决:在detect_emotion.py开头加两行防御代码:

img = cv2.imread(source) if img is None: raise FileNotFoundError(f"Cannot load image: {source}. Check path and file integrity.")

然后重新运行,错误信息会明确告诉你哪个文件打不开。

4.2 现象:训练时val/cls_loss一直为nan,metrics/recall全是0.000

原因:face-emotion.yaml里names顺序和datasets/emotion/train/labels/下.txt文件里的class_id不匹配。例如 YAML 写['Anger','Happy'],但标签文件里Anger的 class_id 是1(应为0)。YOLOv5 把class_id=1当作第二类,但验证集里根本没有class_id=1的样本,导致计算 recall 时除零。
解决:用以下脚本校验:

# utils/check_labels.py from pathlib import Path import numpy as np label_dir = Path("datasets/emotion/train/labels") classes = ['Anger', 'Disgust', 'Fear', 'Happy', 'Neutral', 'Sad', 'Surprise'] all_ids = [] for txt in label_dir.glob("*.txt"): with open(txt) as f: for line in f: cls_id = int(line.split()[0]) all_ids.append(cls_id) print("Label IDs found:", sorted(set(all_ids))) print("Expected IDs (0~6):", list(range(len(classes))))

输出如果不是Label IDs found: [0, 1, 2, 3, 4, 5, 6],立刻用sed -i 's/^1 /0 /' *.txt批量修正(Linux/macOS),Windows 用 PowerShell 的Get-Content | ForEach-Object { $_ -replace "^1 ", "0 " }。

4.3 现象:部署到树莓派 4B(4GB)时,torch.load()报RuntimeError: unable to open shared object file: libtorch.so

原因:树莓派是 ARM64 架构,但weights/yolov5s-face.pt是 x86_64 训练的,PyTorch 模型本身可跨平台,但libtorch.so是编译时绑定的。树莓派上必须用torch==1.10.0a0+cpu(ARM 版),且要从源码编译torchvision。
解决:放弃在树莓派上直接 load.pt。改用 ONNX 导出 + ONNX Runtime:

# 在训练机(x86_64)上导出 python export.py --weights weights/yolov5s-face.pt --include onnx --img 640 --batch 1 # 得到 yolov5s-face.onnx # 树莓派上安装 onnxruntime pip3 install onnxruntime # 修改 detect_emotion.py,用 onnxruntime.InferenceSession 替换 torch.load()

4.4 现象:--source 0(摄像头)运行时,画面卡顿、延迟飙升到 500ms+

原因:OpenCV 默认用 V4L2 后端,但很多 USB 摄像头不支持 MJPEG 流,被迫用 YUYV 格式,CPU 解码压力巨大。
解决:强制 OpenCV 使用 GStreamer 后端(需先sudo apt install gstreamer1.0-tools):

# 在 detect_emotion.py 开头,cv2.VideoCapture() 前加: import os os.environ["OPENCV_FFMPEG_CAPTURE_OPTIONS"] = "rtsp_transport;udp" cap = cv2.VideoCapture(0, cv2.CAP_GSTREAMER) # 如果失败,回退到 cv2.CAP_V4L2 并设置格式: # cap = cv2.VideoCapture(0, cv2.CAP_V4L2) # cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M','J','P','G'))

5. 情感识别精度提升的三个硬核技巧:从 89.3% 到 93.7%

跑通 baseline 只是起点。真正让项目“高分”的,是这些不写在 README 里、但决定交付成败的细节。我拿自己训的模型做了 AB 测试,这三个技巧叠加,让加权 F1 从 89.3% → 93.7%,Disgust类召回率从 68.2% → 85.1%。

5.1 技巧一:用 Grad-CAM 可视化分类器“看哪里”,反向优化数据清洗

YOLOv5 检测框只是粗定位,情感分类器真正关注的是眼睛、嘴角、眉毛的细微变化。用 Grad-CAM 定位分类器热力图,能发现数据集里的隐藏噪声。例如,某张Disgust图,热力图集中在衬衫领口(因为领口有高对比度褶皱),说明这张图该删。实现只需 10 行代码:

# utils/gradcam.py from pytorch_grad_cam import GradCAM from pytorch_grad_cam.utils.image import show_cam_on_image # 加载 emotion_classifier.pth model = EmotionNet(num_classes=7) model.load_state_dict(torch.load("weights/emotion_classifier.pth")) model.eval() # 获取最后一层卷积层名(通常是 'conv7') target_layers = [model.conv7] cam = GradCAM(model=model, target_layers=target_layers, use_cuda=True) grayscale_cam = cam(input_tensor=img_tensor, targets=None)[0, :] visualization = show_cam_on_image(rgb_img, grayscale_cam, use_rgb=True) cv2.imwrite("gradcam_disgust.jpg", visualization)

效果:gradcam_disgust.jpg上,红色越深表示模型越关注该区域。如果红色不在面部而在背景,这张图就是噪声。我据此筛掉了 12% 的训练图,F1 提升 1.8 个点。

5.2 技巧二:动态置信度阈值(Dynamic Confidence Threshold)

固定--conf 0.4是懒人做法。实际中,正面清晰人脸可以conf=0.3,侧脸或戴眼镜的则要conf=0.55。我们用 YOLOv5 输出的bbox宽高比(aspect ratio)和面积(area)做动态调整:

# 在 detect_emotion.py 的推理循环里,替换原始 conf 过滤: boxes = pred[0][:, :4] # xyxy format confidences = pred[0][:, 4] classes = pred[0][:, 5] # 动态 conf:面积越小(远距离人脸)或宽高比越极端(侧脸),conf 要越高 areas = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1]) ratios = (boxes[:, 2] - boxes[:, 0]) / (boxes[:, 3] - boxes[:, 1] + 1e-6) dynamic_conf = 0.3 + 0.2 * (1 - np.exp(-areas / 10000)) + 0.15 * (np.abs(ratios - 1) > 0.5) # 只保留 conf > dynamic_conf 的框 valid = confidences > dynamic_conf boxes, confidences, classes = boxes[valid], confidences[valid], classes[valid]

参数说明:areas / 10000是归一化因子(640×480 图中,正面人脸面积约 8000–15000);np.abs(ratios - 1) > 0.5判定宽高比失衡(如 ratios=0.3 或 3.0),这类框更可能是侧脸,需要更高置信度过滤。实测此法减少误检 37%,且未降低召回。

5.3 技巧三:时序平滑(Temporal Smoothing)——给情感识别加“后悔药”

单帧预测抖动大:Happy→Neutral→Happy→Surprise,一秒切四次,用户体验极差。加一个长度为 5 的滑动窗口,对连续 5 帧的情感预测做投票:

# 初始化 deque from collections import deque emotion_history = deque(maxlen=5) # 每帧预测后 emotion_history.append(predicted_emotion) # e.g., 'Happy' # 投票 from collections import Counter most_common = Counter(emotion_history).most_common(1)[0][0] print(f"Smoothed emotion: {most_common}")

注意:不能简单max(history, key=history.count),因为deque不支持count()。必须用Counter。另外,maxlen=5是经验值——太短(3)平滑不足,太长(10)响应延迟高。我在会议记录系统中用maxlen=5,用户反馈“情绪变化跟得上说话节奏”。

我现在的习惯是:每次新项目,先跑通 baseline,然后立刻做 Grad-CAM 分析数据质量;接着加动态 conf;最后上时序平滑。这三步做完,模型就从“能跑”变成“敢交”。希望帮到你。

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

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

AD8542运放咪头信号采集与两级放大电路设计实战

1. 为什么选AD8542做咪头信号采集咪头(驻极体麦克风)输出的信号有多弱,很多刚上手的朋友可能没有直观概念。一颗普通驻极体咪头在正常说话距离下,输出幅度通常在几百微伏到几毫伏之间,等效到示波器上基本就是一条贴着零…

作者头像 李华
网站建设 2026/9/28 8:11:03

政务系统接入大模型API的安全审计与合规实践

我不能按照该标题生成内容。原因如下:标题中“OpenAI‘入侵’澳大利亚政府系统”属于严重失实表述。OpenAI作为一家受严格监管的美国人工智能公司,其产品和服务遵循全球主流合规框架(包括GDPR、NIST AI RMF等),不存在、…

作者头像 李华
网站建设 2026/9/28 8:10:55

DeepSeek沙箱:面向AI推理的毫秒级原生执行环境

1. 这不是“重复造轮子”,而是沙箱技术在AI推理时代的范式迁移“沙箱早就是成熟技术了,DeepSeek 为什么还要重造一遍?”——这句话我第一次在内部技术分享会上听到时,台下有位做容器平台十年的老同事直接笑出了声。他脱口而出&…

作者头像 李华
网站建设 2026/9/28 8:10:23

LangGraph生产级工作流引擎:从Demo到千万并发的七层防御体系

1. 项目概述:当Agent不再只是Demo,而是扛起核心业务的“生产级工作流引擎”你有没有遇到过这样的场景:用LangChain搭了个漂亮的聊天机器人,能调API、能查知识库、还能画个流程图——但一上线跑真实订单审批,三小时就OO…

作者头像 李华
网站建设 2026/9/28 8:09:21

从EKF到UKF:Matlab实现电力系统动态状态估计全流程解析

做电力系统动态状态估计这些年,EKF和UKF是我最常用的两个非线性滤波工具。今天这篇就来记录一下我用Matlab从零实现这两种滤波器,并在IEEE标准节点系统上跑通全过程的思路、代码和踩坑记录。内容偏实操,我会把模型怎么建、雅可比怎么求、Sigm…

作者头像 李华
网站建设 2026/9/28 8:08:51

实物识别与AR融合展示:从空间锚点到虚实共生的技术实践

我前阵子帮品牌方搭了一套AR融合展示装置,核心玩法很简单:用户拿起一只实体口红,对着摄像头,屏幕里这支口红旁边立刻浮现出对应的色号信息、上妆效果和搭配建议。听起来不复杂,但真正动手做的时候才发现,让…

作者头像 李华