首页/新闻资讯/正文详情

Python+CNN实现道路坑洼识别:含数据集与PyTorch训练指南

发布时间:2026/9/24 19:11:08 来源:云帆数科 栏目:资讯中心
Python+CNN实现道路坑洼识别:含数据集与PyTorch训练指南
简介基于Python CNN深度学习的道路坑洼识别项目面向计算机视觉入门者、路面检测项目开发者以及课程设计/毕业设计学生利用卷积神经网络对道路图像进行正常路面与坑洼二分类识别。压缩包共252个文件以246张jpg标注图像含normal正常、pothole坑洼两个类别为主辅以3个txt数据清单和3个py源码文件整体仅10.19MB轻量易下载。已有133人浏览学习便于快速上手体验完整流程。代码按数据准备、模型训练、界面展示三阶段组织01脚本读取图像并自动生成路径与标签02脚本基于PyTorch训练CNN模型并保存权重03脚本提供PyQt交互界面。数据预处理通过短边补灰边转为正方形、并按角度旋转扩充样本增强模型泛化能力训练过程自动输出日志记录每轮验证集损失与准确率方便监控调优。附带环境依赖清单配置好环境后可依次运行脚本直接复现坑洼识别效果。1. 道路坑洼识别这个 python-cnn 项目能解决什么市政巡检车每天拍回来的路面视频几百 GB 素材靠人眼一帧帧找坑洼看半小时眼睛就花了。这正是基于 python-cnn 深度学习的道路坑洼识别要解决的问题用 CNN 卷积神经网络对路面图像做二分类或三分类把「正常路面」和「坑洼/破损」自动区分开。标题里「含数据集」四个字很关键——路面样本不好凑网上公开的坑洼数据集要么脏要么小一个整理过的数据集能让你把精力放在训练和调参上而不是花两周去标数据。我见过不少搞土木养护、智慧城市和安防监控的团队卡在这个需求上——他们不是不懂水泥沥青而是被深度学习的环境配置、数据集格式和模型训练绕晕。这篇文章从数据集整理、预处理、CNN 选型、训练调参到推理部署一条线走完新手能照着跑通熟手能直接拿来改自己的数据。2. 数据集与预处理路面样本这样准备CNN 才不会学歪2.1 先看数据集目录分类任务的文件是怎么组织的拿到这个带数据集的压缩包第一步不是解压就开训而是先摸清目录结构。常见的图像分类数据集一般按「类别文件夹」组织比如train/pothole/和train/normal/每个文件夹里放对应类别的图片。这种结构的好处是 PyTorch 的ImageFolder和 TensorFlow 的image_dataset_from_directory都能直接读取不需要自己写解析器。我一般会先跑一段 Python 脚本把目录结构和每个类别的图片数打印出来确认没有空文件夹、没有读不出来的损坏图片import os from collections import Counter data_root dataset/ # 根据你解压后的实际路径修改 exts (.jpg, .jpeg, .png, .bmp) for split in [train, val, test]: split_path os.path.join(data_root, split) if not os.path.isdir(split_path): print(f【警告】找不到 {split} 目录) continue counter Counter() for cls_name in os.listdir(split_path): cls_path os.path.join(split_path, cls_name) if not os.path.isdir(cls_path): continue n sum(1 for f in os.listdir(cls_path) if f.lower().endswith(exts)) counter[cls_name] n print(f{split}: {dict(counter)})这段代码做了三件事遍历 train、val、test 三个目录、按类别统计图片数量、并打印出来。逻辑上没什么高深的地方但它能在训练前就暴露两个最容易翻车的问题——类别严重不均衡、目录文件损坏。如果发现train里坑洼类 800 张而正常类只有 120 张后面就必须做数据增强或类别加权否则模型会学成「永远预测正常路面」。2.2 预处理参数为什么统一缩放到 224×224CNN 要求输入尺寸固定因为全连接层的维度不能变。224×224 是 ImageNet 时代的标准尺寸ResNet、VGG 这类经典网络都按这个尺寸设计。你的数据集里图片可能是 1920×1080 的行车记录仪截图也可能是 500×500 的手机拍摄图如果不统一缩放模型训练和推理时都会报维度错误。常见的预处理流程是「解码 → 缩放 → 中心裁剪或直接拉伸 → 归一化」。直接拉伸到 224×224 会把路面纹理压扁但坑洼识别通常不受太大影响因为坑洼的形状是相对局部的不像人脸那样整体变形就崩。数据增强方面翻转、旋转、亮度扰动对路面识别都有帮助from torchvision import transforms train_transform transforms.Compose([ transforms.Resize((224, 224)), # 统一尺寸通道数由图片格式决定 transforms.RandomHorizontalFlip(p0.5), # 路面左右对称翻转不改变语义 transforms.RandomRotation(10), # 小角度旋转模拟拍摄角度偏差 transforms.ColorJitter(brightness0.3, contrast0.3), # 光照变化 transforms.ToTensor(), # HWC转CHW并归一化到[0,1] transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) # ImageNet统计值 ]) val_transform transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ])RandomHorizontalFlip对路面是安全的因为左右翻转不改变「有没有坑」这个事实RandomRotation旋转角度我控制在 10 度以内旋转过大容易把路面上的车道线、标志线扭曲成奇怪形状Normalize用的三个 mean/std 是 ImageNet 的统计值这个不是为了「标准化」本身而是因为你要用 ImageNet 预训练权重输入分布必须对齐。2.3 验证集不是摆设划分比例和顺序很多刚接触深度学习的同学会犯一个错误把所有数据丢进训练最后用同一批数据算准确率。这种做法在分类任务上会给你一个虚高的分数比如 98%但真实场景一推就崩。正确做法是把数据集分成三份训练集训练权重、验证集调超参、做早停、测试集最终效果评估比例一般按 8:1:1 或 7:2:1且必须保证三个集合之间没有图片重复。划分时注意一个细节如果采集的视频连续帧抽出的图不能简单随机切分否则同一段路面的相邻帧会被分到训练集和测试集造成数据泄漏。我一般按「视频片段」或「拍摄时间」分组划分而不是按单张图片随机打乱。这个操作没有标准库直接支持通常是自己维护一个 index 列表按视频文件名分组后切分。你拿到数据集时如果标注文件里带了来源信息建议优先按来源分组。3. CNN 模型与训练参数从 VGG16 到轻量化的选型逻辑3.1 图像处理为什么用 CNN而不是前馈神经网络很多人问过我这个问题特别是刚从传统机器学习转过来的。全连接网络处理图像时要把每个像素当成独立特征输入一张 224×224 的 RGB 图就是 15 万个输入维度第一层全连接的参数量就爆炸了。更关键的是全连接网络没有「局部性」概念——它看不到像素之间的空间邻接关系。CNN 的两个核心机制——卷积核共享和局部感受野——正好解决这个问题。一个 3×3 卷积核在整张图上滑动提取的是局部的边缘、纹理模式不管这个坑洼出现在画面中心还是角落卷积核都能捕捉到。坑洼识别的关键特征裂缝边缘、路面凹陷阴影、破损碎块恰恰是典型的局部纹理特征所以 CNN 是这类任务最自然的起点。另一个实际原因是图像分类任务的预训练模型ImageNet 上训好的基本都是 CNN 架构迁移学习有着成熟的生态支持你用 ResNet 还是 EfficientNet 都有现成代码可拉。3.2 迁移学习和小数据集不要一上来就从头训练如果你的坑洼数据集只有几千张图我强烈建议别从头训 CNN。深度学习模型动辄上千万参数几千张图根本撑不起这么大规模的权重学习结果就是过拟合——训练集准确率 99%验证集只有 70%。常见做法是加载 ImageNet 预训练权重把最后一层全连接换掉然后微调。我用 PyTorch 的话是这样实现的import torchvision.models as models import torch.nn as nn def build_model(num_classes2, pretrainedTrue): model models.resnet18(weightsmodels.ResNet18_Weights.IMAGENET1K_V1 if pretrained else None) # ResNet18 最后一层是 fc输入 512 维输出改成你的类别数 model.fc nn.Linear(model.fc.in_features, num_classes) return model model build_model(num_classes2, pretrainedTrue)ResNet18_Weights.IMAGENET1K_V1是 PyTorch 推荐的加载方式比传pretrainedTrue更明确。替换model.fc是因为 ImageNet 预训练模型原本输出 1000 类你的任务只需要 2 类坑洼/正常或 3 类坑洼/裂纹/正常。训练时有两种策略一是冻结 backbone 只训练全连接层适合数据量特别小几百张的情况二是全部参与训练但把 backbone 学习率设小一点适合几千张以上。你可以在requires_grad上做控制这里先记住结论数据少就冻结数据多就微调。3.3 训练超参数学习率、batch size、轮数怎么定超参数不是拍脑袋定的但也不是玄学有经验取值范围。学习率在迁移学习场景下我的起步值是 0.001 Adam 优化器如果训练集准确率完全不涨就降到 0.0001batch size 根据显存来6GB 显存跑 ResNet18 用 32 没问题如果显存紧张就用 16。轮数不要一上来设 100 轮先跑 20 轮看验证集准确率曲线如果还在涨就续跑如果 10 轮之后验证集不再提升就开始过拟合了应该做早停。优化器方面SGD 加 momentummomentum0.9在图像分类上收敛慢但泛化往往更好Adam 收敛快但偶有验证集波动大的情况。我的习惯是快速看效果用 Adam追求最终精度换成 SGD 再训一轮。有一点容易被忽略学习率调度器Learning Rate Scheduler。用一个StepLR每 10 个 epoch 把学习率乘以 0.1能帮模型在后期做更精细的权重更新验证集准确率往往能再涨 12 个点。4. 在本地跑通完整训练流程数据加载到权重保存4.1 环境准备与数据加载器开始之前先确认你的 Python 环境。PyTorch 是当前做 CNN 分类最顺手的框架坑洼识别项目里用torchtorchvisionopencv-python三个包就够了。我习惯在 VSCode 里建一个虚拟环境避免把系统 Python 搞乱python -m venv venv source venv/bin/activate # Windows 下使用 venv\Scripts\activate pip install torch torchvision opencv-python安装时注意PyTorch 的 CPU 版本和 GPU 版本命令不同有 NVIDIA 显卡就去 PyTorch 官网选对应的 CUDA 版本没有显卡就用 CPU 版本但训练速度会慢 10 倍以上ResNet18 跑一个 epoch 可能需要几分钟。接下来把数据集通过ImageFolder加载它会根据子目录名自动生成类别标签from torch.utils.data import DataLoader from torchvision import datasets train_dataset datasets.ImageFolder(dataset/train, transformtrain_transform) val_dataset datasets.ImageFolder(dataset/val, transformval_transform) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue, num_workers4, pin_memoryTrue) val_loader DataLoader(val_dataset, batch_size32, shuffleFalse, num_workers4, pin_memoryTrue) print(类别映射:, train_dataset.class_to_idx) print(训练集样本数:, len(train_dataset))ImageFolder要求目录必须是「一级类别文件夹、二级图片文件」的结构如果你的压缩包组织结构不是这样需要先调整目录。shuffleTrue只在训练集用验证集不能打乱否则每次评估的样本顺序随机导致验证指标不稳定。num_workers是数据加载的进程数Windows 上可能遇到多进程报错这时把它改成 0 最省事。4.2 训练循环损失、反向传播、模型保存训练循环的骨架在所有分类任务里几乎一样前向传播算损失、反向传播算梯度、优化器更新权重。坑洼识别用的是交叉熵损失适合多分类。完整脚本如下import torch import torch.nn as nn import torch.optim as optim model build_model(num_classes2, pretrainedTrue) device torch.device(cuda if torch.cuda.is_available() else cpu) model model.to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) scheduler optim.lr_scheduler.StepLR(optimizer, step_size10, gamma0.1) num_epochs 30 best_acc 0.0 for epoch in range(num_epochs): # 训练阶段 model.train() running_loss 0.0 for images, labels in train_loader: images, labels images.to(device), labels.to(device) optimizer.zero_grad() outputs model(images) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() * images.size(0) # 验证阶段不需要计算梯度 model.eval() correct 0 total 0 with torch.no_grad(): for images, labels in val_loader: images, labels images.to(device), labels.to(device) outputs model(images) _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() val_acc 100.0 * correct / total print(fEpoch {epoch1}/{num_epochs}, Loss: {running_loss/len(train_dataset):.4f}, fVal Acc: {val_acc:.2f}%) # 保存验证集准确率最高的权重 if val_acc best_acc: best_acc val_acc torch.save(model.state_dict(), best_pothole_model.pth) print(f模型已保存验证集准确率 {best_acc:.2f}%) scheduler.step()model.train()和model.eval()之间的切换很关键因为 BatchNorm 和 Dropout 在训练和推理时行为不同漏掉这行会导致验证集结果忽高忽低。torch.no_grad()告诉 PyTorch 验证阶段不需要构建计算图省内存也提速。保存模型时只保存state_dict权重而不是整个模型对象这样换机器加载时只要重建模型结构再load_state_dict就行。30 个 epoch 训完后best_pothole_model.pth就是验证集上表现最好的权重最终测试集评估要单独跑不能拿验证集当测试集自欺欺人。4.3 训练曲线怎么看损失下降说明学到了东西训练结束后不要急着收工看一眼每个 epoch 打印的 loss 和验证集准确率。典型的好趋势是训练 loss 从 1.0 附近一路降到 0.2 以下验证集准确率从 60% 爬升到 90% 以上并趋于平稳。如果训练 loss 下降但验证集准确率停滞可能过拟合靠增强数据和正则化解决如果训练 loss 一开始就不动检查学习率是否设置过大或数据加载是否出错。我个人会在训练结束后单独跑一次测试集评估用test_loader走一遍同样的验证代码输出最终准确率。这一步节省不了因为验证集在训练过程中已经被用来做早停和选模型了测试集才是模型没见过的数据它的准确率才是你敢报给业务方的数字。5. 道路坑洼识别避坑实录4 个最容易翻车的细节5.1 验证集 95%一上真实视频就到处乱报现象训练时验证集准确率已经 95% 了觉得自己模型很棒结果把行车记录仪视频抽帧一测路边的井盖、减速带、树影全被判成坑洼。原因数据集太「干净」了。训练样本里的坑洼基本都是晴天拍摄、目标在画面中央、背景是沥青路面但真实道路上有井盖、修补痕迹、阴影、积水和轮胎磨损印这些在灰度纹理上很像坑洼。解决给负样本加难例。井盖、减速带、刚修补的黑色补丁、积水反光、树影都要收集进normal类别数量最好占到正常样本的三成以上。数据增强里加RandomGrayscale和更强的亮度扰动模拟阴天和逆光场景。这一步是坑洼识别项目里最花时间的部分但也是决定模型能否落地的关键。5.2 训练时 loss 降到 0.4 就再也下不去了现象训练集和验证集的 loss 都在 0.4 左右徘徊准确率卡在 85% 上不去怎么调学习率都没用。原因类别不均衡加难样本分布问题。坑洼和裂纹这类破损样本长得不像一拨有的坑洼是深坑有的只是表层龟裂模型试图用一个线性边界把多模态的坑洼类拟合出来很吃力。另一个常见原因是分类边界上存在大量「长得像坑但实际是纹理噪声」的样本。解决先统计类别分布如果坑洼样本明显偏少就用WeightedRandomSampler做样本加权或者直接在损失函数里传class_weight。更彻底的做法是换损失函数比如 Focal Loss它对难分类样本给更大梯度权重在目标检测和像素级识别里常用做图像分类也能有效把 loss 压下去。我通常先试class_weight效果不明显再换 Focal Loss。5.3 图片格式问题JPG 压缩痕迹成了模型学到的特征现象训练集用无损 PNG测试集用行车记录仪导出的 JPG准确率掉 10 个百分点以上。原因JPG 在压缩时会产生 8×8 像素块的块效应和高频噪声CNN 对这种高频伪影很敏感。训练集用 PNG模型把这些伪影当成了判断依据一换到 JPG 输入就翻车。这个问题在路面识别上特别隐蔽因为沥青路面本身纹理复杂JPG 噪声混进路面纹理里肉眼根本看不出来。解决训练和推理尽量保持图片格式一致。如果你的落地场景就是 JPG 视频帧那训练时就应该用 JPG 格式的样本不要人为制造格式差异。另一种思路是统一转成 PNG但会增加存储和读取开销取舍取决于部署环境。5.4 显存不足跑一个 batch 就 OOM现象代码刚启动CUDA out of memory直接报错程序崩溃。原因输入分辨率过大或 batch size 设置过高。数据集里可能混有大尺寸图片Resize((224, 224))虽然会缩放但如果num_workers加载速度慢于 GPU 计算速度数据队列积压也会吃满显存。解决batch size 从 32 降到 16num_workers从 4 降到 2基本能缓解大部分情况。如果还不行检查是不是有多个程序同时占用 GPU用nvidia-smi查看另外别开pin_memoryTrue之外的额外显存开销。实在不行就用梯度累积把小 batch 的梯度累加起来再更新一次权重效果上接近大 batch代码改动也不大。6. 把模型用到真实道路场景推理脚本与可信度验证训练完成的模型最终要接进巡检流程我的做法是写一个独立的推理脚本输入一张图片输出类别和置信度。按概率阈值过滤预测结果置信度低于 0.7 的标记为「待人工复核」这样可以避免模型瞎报干扰巡检人员判断。下面这个脚本可以直接在命令行跑import torch import torchvision.transforms as transforms from PIL import Image def predict_image(image_path, model, class_names, device, threshold0.7): transform transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]) ]) img Image.open(image_path).convert(RGB) x transform(img).unsqueeze(0).to(device) model.eval() with torch.no_grad(): probs torch.softmax(model(x), dim1) score, pred torch.max(probs, 1) cls_name class_names[pred.item()] if score.item() threshold: print(f置信度 {score.item():.2f} 低于阈值建议人工复核) else: print(f预测类别: {cls_name}, 置信度: {score.item():.2f}) return cls_name, score.item()推理时要记住两个关键点图片预处理必须和训练时完全一致——244 缩放尺寸、Normalize 的 mean/std、RGB 通道顺序任何一步不一致都会导致准确率下滑model.eval()在推理时千万不能漏特别是模型里有 BatchNorm 层时。推理速度方面CPU 上跑 ResNet18 单张图大约几十毫秒到几百毫秒GPU 上可以做到实时用来处理巡检视频抽帧足够。最后分享一个我的验收习惯训练完不只看测试集准确率还会拿一段从未出现在数据集里的行车记录仪视频抽 100 帧人工标注后跑一遍统计真实场景的准确率和漏报率。因为模型在「干净」测试集上表现好是很正常的但真实路面光照、遮挡、运动模糊才是它真正的考场。坑洼识别这类任务最怕的不是准确率低而是「自我感觉良好」——跑通训练流程只是开始把模型在真实数据上的表现摸清楚才是收尾的最后一公里。希望帮到你。本文还有配套的精品资源点击获取

相关推荐

PCB缺陷检测实战:YOLOv9数据集解析与训练调优指南
PCB缺陷检测实战:YOLOv9数据集解析与训练调优指南

简介:PCB电路板缺陷检测识别数据集,面向计算机视觉工程师、工业质检人员及科研工作者,可用于搭建基于YOLOv9的电路板缺陷识别系统,解决生产中的外观质检与缺陷分类问题。包内共2000个文件,包含702张JPG缺陷样本图片、1… · 2026/9/24 19:11:08

OpenCV仪表盘指针读数识别:从Hough直线检测到参数调优实战
OpenCV仪表盘指针读数识别:从Hough直线检测到参数调优实战

简介:基于OpenCV的仪表盘指针读数识别系统,面向工业仪表自动抄表、课程设计以及计算机视觉项目开发者,解决传统人工读取仪表效率低、易出错的问题。压缩包共6个文件,包含3个C源文件、2个头文件和1个说明文档,整体仅9KB… · 2026/9/24 19:11:08

SQL注入绕过技巧全解析:从WAF原理到实战攻防
SQL注入绕过技巧全解析:从WAF原理到实战攻防

1. 为什么到现在还要聊SQL注入绕过先说个反直觉的事实:2025年了,SQL注入依然是OWASP Top 10里的常客,WAF(Web应用防火墙)和各类安全产品越铺越广,但真实攻防场景里,SQL注入绕过的话题从来就没冷… · 2026/9/24 19:11:08

MySQL高负载I/O故障全链路排查与优化实战
MySQL高负载I/O故障全链路排查与优化实战

凌晨两点十六分,监控大屏上的MySQL IOPS曲线突然拉成一条垂直的直线,告警声把值班室的安静撕得粉碎。那条从10点开始缓慢抬升的紫色线条,在那一刻直接冲上了磁盘性能的上限刻度,数据库的活跃会话数同步飙到400,大量业务… · 2026/9/24 19:49:11

企业级数据库工具怎么选?Navicat与NineData对比分析
企业级数据库工具怎么选?Navicat与NineData对比分析

做过十来年数据库运维和研发,Navicat 基本是很多人电脑里的“标配”,从连 MySQL、Oracle 到日常看数据、导数据,确实顺手。但这两年我越来越多地被企业客户问到同一个问题:团队规模上来之后,Navicat 还够用吗&#xff… · 2026/9/24 19:49:11

MySQL高负载I/O故障根因分析:从系统层到InnoDB的排查与优化
MySQL高负载I/O故障根因分析:从系统层到InnoDB的排查与优化

这事发生在上个月,客户的线上MySQL实例连续两天在业务高峰时段崩溃报警,从应用侧看就是大量请求超时,接口P99延迟从原本的80ms直接飙到3s以上。我看了一眼监控面板,CPU 80%以上,磁盘I/O util触顶100%,iowai… · 2026/9/24 19:49:11

C++与Python混合编程:pybind11、ctypes、C API选型指南
C++与Python混合编程:pybind11、ctypes、C API选型指南

1. 混合编程的选型困局:为什么三种方案总让人纠结做C和Python混合开发的人,几乎都绕不开一个灵魂拷问:到底用pybind11、ctypes还是Python C API?我最早接触这个领域是做量化回测系统,核心撮合引擎用C写,策略… · 2026/9/24 19:49:11

MySQL主从架构下MaxScale读写分离与高可用实战指南
MySQL主从架构下MaxScale读写分离与高可用实战指南

搞数据库的兄弟应该都有过这种体验:主从架构搭好了,读写分离却迟迟没落到位。业务代码里手动判断哪个库写、哪个库读,刚开始还行,等Server挂了一台、主从切换过几轮之后,各种连接串了、事务跑飞、延迟把从库拖垮的问题… · 2026/9/24 19:49:11

Jackett终极指南:一键搭建个人资源聚合中心的完整教程
Jackett终极指南:一键搭建个人资源聚合中心的完整教程

Jackett终极指南:一键搭建个人资源聚合中心的完整教程 Jackett是一款强大的开源资源聚合引擎,能够将上百个种子网站的资源整合到一个统一的搜索界面中。无论你是媒体爱好者、研究人员还是开源软件用户,Jackett都能为你节省大量搜索时间&… · 2026/9/24 19:49:05

基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程

简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13

1D-CNN时间序列建模实战:从Conv1d原理到工业落地
1D-CNN时间序列建模实战:从Conv1d原理到工业落地

简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26

柔软的L:汉语语流中被忽视的舌肌张力控制
柔软的L:汉语语流中被忽视的舌肌张力控制

1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码