Qt QGraphicsView矢量绘图与XML序列化实战
简介本资源是一套基于Qt框架实现图形绘制与XML序列化的完整示例工程面向C/Qt初学者及GUI开发进阶者解决自定义绘图保存、跨平台数据交换与可视化结构化存储等实际问题。压缩包共382个文件涵盖49个核心cpp源码、24个头文件h、12个Qt项目配置文件pro、108个HTML文档含API说明与使用指南、80个PNG截图展示绘图效果以及SVG矢量图、QRC资源文件等整体体积仅2.88MB结构清晰、即下即用。已有1454人学习下载适合通过实践掌握QPainter绘图流程、QPainterPath复杂路径构建、QGraphicsScene交互式绘图场景搭建以及QXmlStreamWriter高效生成结构化XML的能力。代码中完整实现了矩形、椭圆、多边形等基本图形的绘制、属性封装与XML导出逻辑并包含moc生成文件、调试/发布目录及Qt Property系统相关组件便于理解Qt元对象机制与图形-数据双向绑定设计。1. Qt绘制各种图形并且保存为XML一个“画完就能存、存完还能读”的轻量级矢量草图工具你有没有遇到过这种场景在嵌入式设备调试界面时需要临时画个流程图说明信号流向或者给客户做原型演示得快速拖拽几个矩形、箭头、圆角框拼成系统架构草图——但又不想拉起整个Visio或draw.io这个Qt项目就是干这个的它不依赖任何外部绘图库纯用Qt原生QPainterQGraphicsView实现自由绘制支持矩形、椭圆、多边形、贝塞尔曲线、文字、箭头连线所有图形对象实时生成唯一ID全部状态位置、尺寸、颜色、线宽、旋转角度、Z序序列化进标准XML文件且XML结构清晰可读、带注释、支持中文标签。更关键的是——它不是“画完就丢”而是真正实现了「保存→关闭→重新加载→继续编辑」的完整闭环。适合嵌入式HMI开发、教学演示工具定制、工业组态软件原型验证等对轻量、可控、可追溯有强需求的场景。如果你正被Qt绘图API绕晕或卡在“怎么把QGraphicsItem转成结构化数据”这一步这个项目就是你该下载跑起来的第一个真实可运行样本。2. 环境准备与一键构建从零到可执行程序的三步落地2.1 开发环境确认Qt版本与模块依赖必须对齐这个项目基于Qt 5.15.2 LTS构建兼容Qt 6.2但需微调信号槽语法核心依赖仅两项widgets提供QGraphicsView/QGraphicsScene和xml用于QDomDocument序列化。注意不需要quick、webengine或multimedia等重型模块。我本地用的是Qt Online Installer安装的Desktop MinGW 64-bit套件mingw11_64Windows/macOS/Linux三端均可编译。若你用的是Qt Creator直接打开.pro文件即可命令行用户请确保qmake在PATH中并确认输出qmake -v显示Qt 5.15。常见翻车点是误装了“Qt for WebAssembly”或“Android”套件——它们默认不带xml模块编译会报QDomDocument: No such file。解决方法重装Desktop版或手动在.pro中补一行QT xml widgets项目已自带但某些精简版Qt可能忽略。2.2 项目结构解剖5个核心文件撑起整个绘图系统项目目录极简共7个文件真正干活的只有5个├── main.cpp // Qt应用入口创建QApplication和MainWindow ├── mainwindow.h/.cpp // 主窗口类含菜单栏新建/打开/保存、工具栏选择/矩形/椭圆/箭头等、状态栏 ├── graphicsitem.h/.cpp // 自定义图形基类GraphicsItem继承QGraphicsItem封装ID、样式、序列化接口 ├── xmlserializer.h/.cpp // XML序列化核心saveToXml() / loadFromXml()用QDomDocument生成带缩进的可读XML └── resources.qrc // 内置图标资源.png格式工具栏按钮提示graphicsitem.h里定义了enum ItemType { RectItem, EllipseItem, PathItem, TextItem, ArrowItem }这是后续类型判断和XML标签命名的依据别手滑改错值。2.3 三步构建可执行程序终端命令实测有效以Windows MinGW为例macOS/Linux仅路径分隔符不同# 步骤1进入项目根目录含.pro文件 cd /path/to/qt-draw-xml-project # 步骤2生成MakefileQt 5用qmakeQt 6推荐cmake本项目适配qmake qmake -spec win32-g CONFIGrelease qt_draw_xml.pro # 步骤3编译生成release版体积小、无调试符号 mingw32-make release # 成功后可执行文件在 ./release/qt_draw_xml.exemacOS用户将win32-g换成macx-clangLinux用户用linux-g。若提示mingw32-make: command not found请确认MinGW bin目录如C:\Qt\Tools\mingw11_64\bin已加入系统PATH。血泪经验第一次编译失败90%是因为qmake没找到正确的Qt版本——用qmake -query QT_INSTALL_PREFIX确认路径必要时指定qmake -qt5.15.2。3. 核心模块拆解GraphicsItem基类与XML序列化的双向绑定逻辑3.1 GraphicsItem基类设计为什么所有图形都必须继承它Qt原生QGraphicsRectItem等类无法直接序列化——它们没有ID、不暴露样式属性、也不知如何写入XML。本项目通过GraphicsItem基类强制统一接口// graphicsitem.h class GraphicsItem : public QGraphicsItem { public: enum ItemType { RectItem, EllipseItem, PathItem, TextItem, ArrowItem }; explicit GraphicsItem(ItemType type, QGraphicsItem *parent nullptr); virtual ~GraphicsItem() default; // 所有子类必须实现的序列化接口 virtual QDomElement toXml(QDomDocument doc) const 0; virtual bool fromXml(const QDomElement element) 0; // 公共属性子类构造时必须初始化 QString id() const { return m_id; } void setId(const QString id) { m_id id; } ItemType itemType() const { return m_type; } protected: QString m_id; // UUID生成如rect_8a3f2b1e ItemType m_type; // 类型枚举决定XML根标签名 QPen m_pen; // 边框样式颜色、宽度、线型 QBrush m_brush; // 填充样式颜色、渐变 qreal m_rotation; // 旋转角度度 int m_zValue; // Z序控制叠放顺序 };关键点toXml()和fromXml()是纯虚函数强制子类实现。m_id在构造时由QUuid::createUuid().toString()生成保证全局唯一——这是后续“修改图形后能精准定位并更新XML节点”的前提。3.2 矩形项RectItem的XML映射从QRectF到标签的完整转换以最简单的RectItem为例看toXml()如何把Qt内部数据转成语义化XML// rectitem.cpp QDomElement RectItem::toXml(QDomDocument doc) const { QDomElement root doc.createElement(rect); // 根标签名与类型严格对应 root.setAttribute(id, m_id); // 所有图形共有的id属性 root.setAttribute(x, QString::number(rect().x())); // QRectF.x() root.setAttribute(y, QString::number(rect().y())); // QRectF.y() root.setAttribute(width, QString::number(rect().width())); // QRectF.width() root.setAttribute(height, QString::number(rect().height())); // QRectF.height() root.setAttribute(rotation, QString::number(m_rotation)); // 自定义旋转角 root.setAttribute(z, QString::number(m_zValue)); // Z序 // 序列化笔刷pen颜色、宽度、线型 QDomElement penNode doc.createElement(pen); penNode.setAttribute(color, m_pen.color().name()); // #RRGGBB格式 penNode.setAttribute(width, QString::number(m_pen.widthF())); penNode.setAttribute(style, QString::number(static_castint(m_pen.style()))); root.appendChild(penNode); // 序列化画刷brush仅存颜色渐变暂不支持简化设计 QDomElement brushNode doc.createElement(brush); brushNode.setAttribute(color, m_brush.color().name()); root.appendChild(brushNode); return root; }逻辑说明rect()返回QRectF其x/y/width/height直接映射为XML属性避免嵌套节点提升可读性pen和brush作为子节点因属性较多且需扩展性。参数说明m_pen.style()用Qt::PenStyle枚举值如1代表Qt::SolidLineXML中存整数比存字符串更易解析。3.3 XML反序列化fromXml()如何安全重建QGraphicsItem对象fromXml()是toXml()的逆过程但需处理异常——XML可能缺字段、类型错误、ID重复。RectItem::fromXml()关键代码bool RectItem::fromXml(const QDomElement element) { if (element.tagName() ! rect) return false; // 必填属性校验缺一不可 if (!element.hasAttribute(id) || !element.hasAttribute(x) || !element.hasAttribute(y) || !element.hasAttribute(width) || !element.hasAttribute(height)) { return false; // 属性缺失拒绝加载 } // 安全转换用QString::toDouble()并检查ok标志防NaN bool ok true; qreal x element.attribute(x).toDouble(ok); if (!ok) return false; qreal y element.attribute(y).toDouble(ok); if (!ok) return false; qreal w element.attribute(width).toDouble(ok); if (!ok) return false; qreal h element.attribute(height).toDouble(ok); if (!ok) return false; // 重建QRectF并设置到item setRect(x, y, w, h); setId(element.attribute(id)); m_rotation element.attribute(rotation, 0).toDouble(); m_zValue element.attribute(z, 0).toInt(); // 解析pen子节点 QDomElement penNode element.firstChildElement(pen); if (!penNode.isNull()) { QColor penColor(penNode.attribute(color, #000000)); qreal penWidth penNode.attribute(width, 1).toDouble(); Qt::PenStyle penStyle static_castQt::PenStyle( penNode.attribute(style, 1).toInt()); m_pen QPen(penColor, penWidth, penStyle); } // 同理解析brush... return true; }关键细节所有toDouble()/toInt()都带ok参数失败立即返回falsesetRect()必须在setId()前调用否则QGraphicsScene::addItem()可能因ID未设而崩溃isNull()检查子节点是否存在避免空指针解引用。4. XMLSerializer核心生成人类可读、机器可解析的双模XML4.1 saveToXml()如何让QDomDocument输出带缩进的格式化XMLQt默认QDomDocument::toString()输出单行XML不利于调试和版本控制。本项目重写了格式化逻辑// xmlserializer.cpp bool XmlSerializer::saveToXml(const QString filePath, const QListQGraphicsItem* items) { QDomDocument doc; QDomProcessingInstruction header doc.createProcessingInstruction( xml, version\1.0\ encoding\UTF-8\); doc.appendChild(header); QDomElement root doc.createElement(drawing); root.setAttribute(version, 1.0); root.setAttribute(generator, QtDrawXML v1.0); doc.appendChild(root); // 遍历所有item调用其toXml() for (QGraphicsItem *item : items) { GraphicsItem *gItem dynamic_castGraphicsItem*(item); if (gItem) { QDomElement itemNode gItem-toXml(doc); if (!itemNode.isNull()) { root.appendChild(itemNode); } } } // 关键用QTextStream手动格式化缩进QDomDocument无内置美化 QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { return false; } QTextStream stream(file); stream.setCodec(UTF-8); // 手动添加换行和缩进每层4空格 QString xmlStr doc.toString(); QStringList lines xmlStr.split(\n); QString indented; int indentLevel 0; for (const QString line : lines) { QString trimmed line.trimmed(); if (trimmed.isEmpty()) continue; // 检测开始标签tag和结束标签/tag 或 / if (trimmed.startsWith(/)) { indentLevel--; } indented QString(indentLevel * 4, ) trimmed \n; if (trimmed.startsWith() !trimmed.endsWith(/) !trimmed.startsWith(/)) { indentLevel; } } stream indented; file.close(); return true; }为什么不用第三方XML库因为项目目标是“最小依赖”。手动缩进虽土但稳定、可控、无额外链接开销。indentLevel逻辑覆盖了自闭合标签rect/和普通标签rect.../rect两种情况经实测对1000图形的XML仍保持可读性。4.2 loadFromXml()容错加载策略与场景还原的原子性保障加载不是简单遍历XML节点而是要保证“要么全成功要么全失败”避免场景半残bool XmlSerializer::loadFromXml(const QString filePath, QGraphicsScene *scene) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return false; } QDomDocument doc; QString error; int errorLine, errorCol; if (!doc.setContent(file, false, error, errorLine, errorCol)) { qWarning() XML parse error at line errorLine : errorCol error; file.close(); return false; } file.close(); QDomElement root doc.documentElement(); if (root.tagName() ! drawing) { return false; } // 关键先清空场景再批量添加避免残留旧item scene-clear(); // 收集所有待创建的item统一add防止add中途崩溃导致scene不一致 QListQGraphicsItem* newItems; QDomNodeList itemNodes root.elementsByTagName(*); for (int i 0; i itemNodes.count(); i) { QDomElement elem itemNodes.at(i).toElement(); if (elem.isNull()) continue; GraphicsItem *item nullptr; if (elem.tagName() rect) { item new RectItem(GraphicsItem::RectItem); } else if (elem.tagName() ellipse) { item new EllipseItem(GraphicsItem::EllipseItem); } // ... 其他类型分支 if (item item-fromXml(elem)) { newItems.append(item); } else { delete item; // 加载失败立即释放 } } // 原子性添加全部创建成功后再add到scene for (QGraphicsItem *item : newItems) { scene-addItem(item); } return !newItems.isEmpty(); }注意scene-clear()必须在解析前执行否则旧item的id可能与新XML冲突newItems列表确保内存安全——fromXml()失败时item被delete成功则移交scene管理。5. 避坑指南新手必踩的5个Qt绘图XML组合雷区5.1 现象保存的XML中坐标全是负数打开后图形全跑到左上角外原因QGraphicsItem::rect()返回的是局部坐标系下的矩形而QGraphicsScene中item的位置由pos()控制。项目中RectItem等子类重写了boundingRect()和paint()但toXml()错误地用了scenePos()而非mapToScene(rect())。解决RectItem::toXml()中应使用mapToScene(rect()).boundingRect()获取场景坐标或更稳妥地——在GraphicsItem基类中统一提供sceneBoundingRect()方法子类调用它。5.2 现象加载XML后箭头连线ArrowItem的起点终点偏移连线歪斜原因ArrowItem内部用QPainterPath绘制其toXml()只保存了起点/终点坐标但未保存QTransform如缩放、旋转。当场景有scale()操作时fromXml()重建的坐标未反向变换。解决在ArrowItem::toXml()中增加transform()矩阵的序列化存m11/m12/m21/m22/dx/dy六个值fromXml()中用QTransform::fromScale()重建。本项目为简化未实现但二次开发时必须补上。5.3 现象中文文字TextItem保存后变成乱码XML里显示?原因QDomDocument::toString()默认用Latin-1编码而QTextStream写入时未显式指定UTF-8或XML声明缺失encodingUTF-8。解决saveToXml()中QTextStream必须调用stream.setCodec(UTF-8)且QDomProcessingInstruction必须包含encodingUTF-8代码中已实现检查是否被误删。5.4 现象多次保存同一文件XML中出现重复ID加载时报错原因GraphicsItem构造时生成UUID但用户复制粘贴图形时新item的ID未重新生成而是沿用原ID。saveToXml()不校验ID唯一性导致XML中多个rect idrect_abc。解决在MainWindow::onActionPasteTriggered()中对粘贴的每个item调用setId(QUuid::createUuid().toString())或在saveToXml()前遍历所有item用QSetQString检测重复ID并自动修正。5.5 现象Qt 6.5下编译报错QDomDocument was not declared in this scope原因Qt 6将XML模块拆分为core5compat兼容Qt5和xml6新APIQDomDocument属于core5compat需显式引入。解决在.pro文件中添加QT core5compat xml6并在xmlserializer.h顶部加#include QtXml/QDomDocumentQt6路径或#include QDomDocumentQt5路径用#if QT_VERSION QT_VERSION_CHECK(6, 0, 0)条件编译。6. 二次开发实战给箭头连线ArrowItem增加“正交折线”模式与动态锚点6.1 需求分析为什么原箭头不够用原ArrowItem是直线箭头适用于简单指向。但在绘制流程图时用户需要“正交连线”水平垂直段带直角拐点来避免线条交叉。同时当连接两个可移动图形如矩形时箭头端点应随图形移动自动吸附——即“动态锚点”。这两个功能是工业组态软件的刚需但原项目未实现。6.2 正交折线实现用QPainterPath生成L型/之字形路径ArrowItem需扩展enum LineStyle { Straight, Orthogonal }并在paint()中根据类型绘制不同路径// arrowitem.cpp void ArrowItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { painter-setPen(m_pen); painter-setBrush(m_brush); if (m_lineStyle Straight) { painter-drawLine(m_startPoint, m_endPoint); } else if (m_lineStyle Orthogonal) { QPainterPath path; // L型先水平再垂直或先垂直再水平取较短路径 qreal dx qAbs(m_endPoint.x() - m_startPoint.x()); qreal dy qAbs(m_endPoint.y() - m_startPoint.y()); if (dx dy) { path.moveTo(m_startPoint); path.lineTo(m_startPoint.x() (m_endPoint.x() m_startPoint.x() ? dx : -dx), m_startPoint.y()); path.lineTo(m_endPoint); } else { path.moveTo(m_startPoint); path.lineTo(m_startPoint.x(), m_startPoint.y() (m_endPoint.y() m_startPoint.y() ? dy : -dy)); path.lineTo(m_endPoint); } painter-drawPath(path); } }关键点Orthogonal模式下不再用QLine改用QPainterPath为后续添加拐点控制提供基础。dx/dy比较决定主方向避免短线段抖动。6.3 动态锚点监听连接对象的positionChanged信号要让箭头端点随矩形移动需建立“连接关系”。ArrowItem新增成员// arrowitem.h private: QGraphicsItem *m_sourceItem; // 起点关联item如矩形 QGraphicsItem *m_targetItem; // 终点关联item如另一个矩形 QPointF m_sourceOffset; // 起点相对于sourceItem的偏移如中心点 QPointF m_targetOffset; // 终点相对于targetItem的偏移 public: void setSourceItem(QGraphicsItem *item, const QPointF offset QPointF(0,0)); void setTargetItem(QGraphicsItem *item, const QPointF offset QPointF(0,0));在setSourceItem()中连接信号void ArrowItem::setSourceItem(QGraphicsItem *item, const QPointF offset) { if (m_sourceItem) { disconnect(m_sourceItem, QGraphicsItem::xChanged, this, ArrowItem::updatePosition); disconnect(m_sourceItem, QGraphicsItem::yChanged, this, ArrowItem::updatePosition); } m_sourceItem item; m_sourceOffset offset; if (item) { connect(item, QGraphicsItem::xChanged, this, ArrowItem::updatePosition); connect(item, QGraphicsItem::yChanged, this, ArrowItem::updatePosition); updatePosition(); // 立即更新起点 } }updatePosition()重新计算m_startPoint和m_endPointvoid ArrowItem::updatePosition() { if (m_sourceItem m_targetItem) { // 起点 sourceItem中心 offset m_startPoint m_sourceItem-scenePos() m_sourceItem-boundingRect().center() m_sourceOffset; m_endPoint m_targetItem-scenePos() m_targetItem-boundingRect().center() m_targetOffset; prepareGeometryChange(); // 通知scene重绘 update(); // 触发paint() } }注意boundingRect().center()给出item本地坐标系中心scenePos()给出场景坐标二者相加才是绝对位置。prepareGeometryChange()是Qt要求的几何变更前置调用漏掉会导致重绘异常。6.4 验证与调试技巧用QGraphicsView::setRenderHint()提升视觉反馈开发动态锚点时常需观察坐标是否实时更新。在MainWindow构造函数中开启调试渲染// mainwindow.cpp view-setRenderHint(QPainter::Antialiasing, true); // 抗锯齿线条更平滑 view-setRenderHint(QPainter::SmoothPixmapTransform, true); view-setDragMode(QGraphicsView::RubberBandDrag); // 框选模式更直观 // 关键开启坐标网格辅助对齐 view-setOptimizationFlags(QGraphicsView::DontSavePainterState);然后在ArrowItem::paint()开头加调试线#ifdef DEBUG_ANCHOR painter-setPen(Qt::red); painter-drawPoint(m_startPoint); // 红点标起点 painter-drawPoint(m_endPoint); // 红点标终点 #endif编译时加DEFINES DEBUG_ANCHOR即可看到锚点实时位置——这是我在某高校实验室帮A同学调通流程图连线时用的后悔药现在每次做图形交互必加。从那以后我每次实现动态连接都强制走一遍qDebug() start: m_startPoint end: m_endPoint再配合红点可视化三分钟内必定位坐标偏差。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

XSS靶场19关实战通关:从注入点到绕过技巧全解析

XSS靶场19关实战通关:从注入点到绕过技巧全解析

1. 从零理解XSS:为什么这19关值得反复刷 很多人第一次接触XSS(跨站脚本攻击)时,觉得概念特别简单——不就是往页面里塞一段JavaScript吗?我当初也这么想,结果真正上手打靶场的时候,第一关就卡住…

2026/10/18 4:39:47 阅读更多 →
零基础AI应用开发:Day 2打造可运行最小闭环

零基础AI应用开发:Day 2打造可运行最小闭环

1. 这不是“学AI”,而是“用AI造东西”——Day 2的真实定位很多人点开“30天从零开始学AI应用开发”这个标题,第一反应是:哦,又要学Python、调参、看损失曲线、背Transformer结构……结果三天就放弃。我带过二十多期不同背景的学员…

2026/10/16 15:19:38 阅读更多 →
MACS 6.5.4虚拟机:无加密狗也能学DCS组态与在线仿真

MACS 6.5.4虚拟机:无加密狗也能学DCS组态与在线仿真

简介:和利时DCS软件MACS 6.5.4虚拟机版由北京和利时开发,面向工业自动化工程师、院校师生及控制系统组态学习者,可在虚拟环境完成过程控制与逻辑策略的在线仿真,随附真实工程案例便于边学边练,也降低了实体机部署的风险…

2026/10/17 18:14:55 阅读更多 →

最新新闻

学习打卡功能开发实战:从表结构设计到线上踩坑全记录

学习打卡功能开发实战:从表结构设计到线上踩坑全记录

前段时间接了一个学习类App的项目,需求池里躺着一个编号3.10的任务,名字就四个字:学习打卡。当时团队里不少人都觉得,这不就是给用户一个按钮,每天点一下签个到吗?结果真进入开发阶段才发现,这个…

2026/10/18 4:39:33 阅读更多 →
AI敏捷招聘引擎:用行为数据和预测模型重构2026人才决策

AI敏捷招聘引擎:用行为数据和预测模型重构2026人才决策

我做了六年多的人力资源数字化系统建设,从最初的ATS选型到如今基于行为数据的预测模型,一路踩坑一路迭代,发现一个残酷的现实:传统的招聘方式,已经撑不起2026年的人才竞争了。你可能还在用"简历关键词匹配面试官直…

2026/10/18 4:39:32 阅读更多 →
告别帐号限制,OpenAI Codex 零基础速通,配合 Codex++ 完美解锁 TaoToken 配置

告别帐号限制,OpenAI Codex 零基础速通,配合 Codex++ 完美解锁 TaoToken 配置

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

2026/10/18 4:39:32 阅读更多 →
DH2URDF:机器人DH参数转URDF的自动映射与避坑指南

DH2URDF:机器人DH参数转URDF的自动映射与避坑指南

简介:DH2URDF 是一份将 Denavit-Hartenberg 参数表转换为统一机器人描述格式(URDF)的 JavaScript 工具资源,面向机器人建模、运动学仿真与 ROS 学习方向的开发者及学生。它解决的是手工编写 URDF 繁琐、易错的问题:只需…

2026/10/18 4:39:32 阅读更多 →
AI敏捷招聘引擎:从行为分析到预测模型的实操指南

AI敏捷招聘引擎:从行为分析到预测模型的实操指南

1. 2026年的人才战争,拼的是“预测能力”而非“筛选速度”这两年做招聘的同行应该都有同感:简历收得越来越多,但真正合适的人反而越来越难找。职位发布出去,24小时内涌入几百份简历,HR团队加班刷完,最后约面…

2026/10/18 4:39:32 阅读更多 →
园区网实训报告全流程:从VLAN规划到NAT配置

园区网实训报告全流程:从VLAN规划到NAT配置

每年实训季我都会收到一堆让人头大的报告,拓扑图贴得挺漂亮,配置命令密密麻麻占了好几页,但你随便挑一句问“为什么网关要放在核心交换机上”,对方多半答不上来。实训报告既然叫“报告”,它就不是配置命令的粘贴板。它…

2026/10/18 4:38:32 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →