Qt时间轴趋势图源码实战:QCustomPlot高性能实现与避坑指南

简介:这是一份面向Qt/C++图形界面开发者的时间轴趋势图实现源码,适合正在学习QGraphicsView图形框架、需要为监控系统或数据分析场景搭建动态图表的初中级开发者参考。压缩包共5个文件,约11KB,包含pro工程文件、cpp源码、qrc资源文件及配套数据文本,结构精简,便于快速导入Qt Creator编译运行。源码围绕QGraphicsView与QGraphicsScene构建二维绘图场景,通过自定义QGraphicsItem绘制数据点与趋势线,并借助QDateTime实现时间轴刻度映射;同时涉及数据模型转换、paint刷新机制、信号槽通信以及滚轮缩放、拖拽平移等交互处理,还兼顾了样式设置与大数据量下的性能优化思路。已有327人学习,可作为理解Qt图表绘制流程、动手改造时间轴趋势图的实用起点。

1. 时间轴趋势图为什么总在 Qt 里翻车

做过工业上位机、监控看板或者数据分析工具的人,大概率都碰过同一个需求:把一串带时间戳的采样值画成一条能左右拖动、能缩放、能实时追加的趋势曲线。听起来简单,真动手才发现坑一个接一个——用 QChart 数据一多就卡成幻灯片,自己拿 QPainter 画又搞不定坐标映射和滚动同步,时间轴刻度还老是跳来跳去对不齐。标题里的「qt时间轴趋势图源码」讲的正是这件事:一套基于 Qt 的时间轴趋势图实现,核心是把时间作为横轴、把采样值作为纵轴,做成可交互、可增量刷新的曲线控件。它适合做设备监控、传感器采集、日志指标可视化这类需要长时间跑、数据点动辄几十万的场景。下面我按自己踩过的路子,把选型、实现、参数和避坑一次讲透。

2. 选型先定死:QChart、QCustomPlot 还是纯 QPainter

在动手写任何一行代码之前,先把绘图底座选对,否则后面重构的代价比从头写还大。时间轴趋势图和普通静态图最大的区别在于:横轴是连续时间、数据是增量到达的、用户还要频繁拖动缩放。这三个特征直接决定了哪种方案能扛住。

2.1 三种主流方案的适用边界

QChart 是 Qt 官方模块,API 友好,QDateTimeAxis 直接支持时间轴,上手最快。但它的内部实现是场景图(QGraphicsScene)体系,每个数据点都对应图元对象,数据量一过几千就开始明显掉帧。我实测过,两万点的折线在普通办公机上拖动就已经有肉眼可见的延迟。所以 QChart 只适合数据量小、刷新频率低的展示型场景,比如日报曲线。

QCustomPlot 是第三方单文件库,基于 QPainter 自绘,性能比 QChart 高一个数量级,内置 QCPAxisTickerDateTime 处理时间刻度,支持增量数据和自适应采样。十万级数据点做缩放拖动基本流畅。它的代价是要自己管理数据容器和重绘触发,API 比 QChart 啰嗦一些。

纯 QPainter 自绘是性能天花板,没有任何中间层,想怎么优化就怎么优化。但坐标映射、刻度生成、命中测试、滚动条同步全得自己写,工作量大概是 QCustomPlot 方案的三到五倍。只有当数据量到百万级、或者有特殊渲染需求(比如多图层叠加、自定义图元)时才值得走这条路。

方案数据量上限(流畅)时间轴支持开发成本适用场景
QChart约 5 千点内置 QDateTimeAxis低小数据展示
QCustomPlot约 10 万点内置 DateTimeTicker中监控、采集
纯 QPainter百万级全自研高高频实时、特殊渲染

2.2 我一般怎么选

判断标准就一条:你的数据点会不会超过一万,以及刷新频率会不会高于每秒十次。两个都不超,QChart 省事;超了任意一个,直接上 QCustomPlot;如果还要做多曲线叠加加实时滚动,且单帧数据过十万,再考虑自绘。绝大多数「qt时间轴趋势图」的需求落在中间那档,所以后面的实现我以 QCustomPlot 为主线讲,思路对 QChart 和自绘同样有参考价值。

2.3 时间轴和普通数值轴的本质差异

很多人第一次做时间轴会直接把时间戳当 double 塞进数值轴,结果刻度显示成「1.7e9」这种鬼东西。时间轴的核心在于刻度生成逻辑:它要按人类可读的单位(秒、分、时、天)自适应切换,还要处理时区、夏令时、跨天跨年。QCustomPlot 的 QCPAxisTickerDateTime 就是干这个的,它接收 Unix 时间戳(秒为单位,double 类型),根据当前可视范围自动决定刻度间隔和标签格式。你要做的只是把时间戳正确喂进去,并设置好 ticker 的格式策略。

3. 用 QCustomPlot 搭出可拖动的时间轴趋势图

这一章是能直接抄作业的部分。我按「初始化 → 喂数据 → 增量刷新 → 交互」的顺序拆,每一步都给可运行的代码和参数说明。

3.1 初始化画布与时间轴

先建一个 QCustomPlot 实例,配置横轴为时间轴、纵轴为数值轴,打开交互开关。

// 初始化趋势图控件 QCustomPlot *plot = new QCustomPlot(this); // 横轴:时间轴,使用 Unix 时间戳(秒) QSharedPointer<QCPAxisTickerDateTime> timeTicker(new QCPAxisTickerDateTime); timeTicker->setDateTimeFormat("hh:mm:ss"); // 默认标签格式 timeTicker->setTickCount(6); // 可视区刻度数量 plot->xAxis->setTicker(timeTicker); plot->xAxis->setLabel("时间"); // 纵轴:数值轴,自动缩放 plot->yAxis->setLabel("采样值"); plot->yAxis->setRange(0, 100); // 交互:拖动 + 滚轮缩放 + 框选缩放 plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables); plot->axisRect()->setRangeDrag(Qt::Horizontal | Qt::Vertical); plot->axisRect()->setRangeZoom(Qt::Horizontal | Qt::Vertical); // 性能相关:关闭抗锯齿可显著提速 plot->setNotAntialiasedElements(QCP::aeAll);

逻辑说明:setTicker 把横轴换成时间刻度生成器,这是时间轴能正确显示的关键。setInteractions 打开拖动和缩放,用户才能左右拖时间轴。setNotAntialiasedElements 关掉抗锯齿,在数据量大时能省下大量渲染时间,代价是线条略糙,监控场景完全可接受。

参数说明:setTickCount 控制刻度密度,太小标签会挤,太大显得空,6 到 8 是常见值。setDateTimeFormat 是默认格式,实际显示时 ticker 会根据范围自动调整,比如范围跨天时会显示日期。setRange 的初始值按你的数据范围设,后面用 rescaleAxes 自动适配也行。

3.2 增量追加数据与滚动窗口

实时趋势图不能每次全量重画,要用 addData 增量追加,并维护一个固定长度的时间窗口。

// 假设 graph 已经通过 plot->addGraph() 创建 QCPGraph *graph = plot->addGraph(); graph->setPen(QPen(Qt::green)); // 固定窗口长度:最近 60 秒 const double windowSec = 60.0; // 模拟一次数据到达 void appendSample(double timestampSec, double value) { graph->addData(timestampSec, value); // 只保留窗口内的数据,移除过老的点 double leftBound = timestampSec - windowSec; graph->data()->removeBefore(leftBound); // 横轴跟随滚动,纵轴按窗口内数据自适应 plot->xAxis->setRange(leftBound, timestampSec); graph->rescaleValueAxis(false, true); // 只缩放纵轴,保留边距 plot->replot(QCustomPlot::rpQueuedReplot); // 排队重绘,合并多次请求 }

逻辑说明:addData 是增量插入,内部用有序容器维护,插入复杂度可控。removeBefore 把窗口外的老数据删掉,防止内存无限增长——这是长时间运行的程序必须做的,否则跑一天内存就爆了。rescaleValueAxis 的第二个参数 true 表示留 10% 边距,避免曲线贴边。rpQueuedReplot 是关键优化:它把重绘请求合并到事件循环里,一秒来一百个数据也只重绘一次,而不是一百次。

参数说明:windowSec 决定可视时间跨度,按业务定,监控常用 30 到 300 秒。removeBefore 的阈值要比窗口左边界略小一点,留点余量,否则拖动时边缘会突然空掉。rescaleValueAxis 的第一个参数是 onlyEnlarge,设 false 表示允许缩小,设 true 则只扩不缩,实时场景一般用 false 让纵轴跟着数据走。

3.3 时间戳的生成与精度处理

时间戳喂错是新手最常见的翻车点。QCPAxisTickerDateTime 要的是秒为单位的 double,不是毫秒,也不是 QDateTime 对象。

// 正确:当前时间转 Unix 秒(带毫秒小数) double nowSec = QDateTime::currentMSecsSinceEpoch() / 1000.0; // 错误示范:直接塞毫秒,横轴会显示成 1970 年附近 // double wrong = QDateTime::currentMSecsSinceEpoch(); // 如果数据源给的是毫秒时间戳,统一转换 double fromMillis(qint64 ms) { return ms / 1000.0; } // 如果数据源给的是本地时间字符串,先解析再转 double fromLocalString(const QString &s) { QDateTime dt = QDateTime::fromString(s, "yyyy-MM-dd hh:mm:ss.zzz"); dt.setTimeSpec(Qt::LocalTime); return dt.toMSecsSinceEpoch() / 1000.0; }

逻辑说明:Unix 时间戳以秒为单位,double 的小数部分承载毫秒精度,这样既能表示绝对时间,又能保留亚秒级分辨率。除以 1000.0 而不是 1000,是为了强制浮点除法,否则整数除法会把毫秒截断。本地时间字符串解析后要显式设 TimeSpec,不然跨时区会偏。

参数说明:如果你的采样间隔小于一秒,务必保留小数部分,否则同一秒内的多个点会挤在一起。格式字符串里的 zzz 表示毫秒,按数据源实际格式调整。

3.4 拖动与缩放时的刻度自适应

用户拖动时间轴时,可视范围变了,刻度格式也该跟着变。QCPAxisTickerDateTime 默认会处理,但你可以微调策略。

// 自定义刻度格式策略:根据范围长度切换 class AdaptiveTimeTicker : public QCPAxisTickerDateTime { protected: QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) override { double range = mAxis->range().size(); // 当前可视范围(秒) if (range < 60) { setDateTimeFormat("hh:mm:ss"); } else if (range < 86400) { setDateTimeFormat("hh:mm"); } else { setDateTimeFormat("MM-dd"); } return QCPAxisTickerDateTime::getTickLabel(tick, locale, formatChar, precision); } };

逻辑说明:继承 ticker 重写 getTickLabel,在每次生成标签前根据当前范围动态改格式。范围小于一分钟显示到秒,小于一天显示时分,超过一天显示月日。这样用户缩放时标签始终可读,不会出现一堆重复的「00:00」。

参数说明:range 单位是秒,86400 是一天。阈值可以按业务调,比如做高频采集时把秒级阈值提到 10 秒。注意 setDateTimeFormat 在 getTickLabel 里调用会有轻微开销,但刻度数量有限,影响可忽略。

4. 大数据量下的性能调优与渲染策略

数据量上去之后,光靠前面的基础写法还不够。这一章讲几个真正拉开差距的优化点,都是我在实际项目里验证过的。

4.1 自适应采样:让一万个像素只画必要点

屏幕横轴最多也就一两千个像素,你塞十万个点进去,大部分点落在同一个像素列上,画了也看不见,纯属浪费。自适应采样就是根据当前可视范围和控件宽度,动态抽稀数据。

// 开启 QCustomPlot 自带的自适应采样 graph->setAdaptiveSampling(true); // 手动控制采样精度(可选) // 当数据点密度超过每像素 2 个时开始抽稀 plot->setPlottingHint(QCP::phFastPolylines, true);

逻辑说明:setAdaptiveSampling 打开后,QCustomPlot 在绘制折线时会根据像素密度跳过冗余点,只保留能体现曲线形状的关键点。phFastPolylines 用更快的折线算法,牺牲一点线条质量换速度。这两个开关在大数据量下能带来数倍提升。

参数说明:自适应采样默认开启,但如果你发现曲线在极值处被削平了,可以关掉它改用自己实现的抽稀算法(比如保留每像素列的最大最小值)。phFastPolylines 在曲线平滑度要求高时慎用。

4.2 双缓冲与重绘节流

频繁 replot 是卡顿的头号元凶。除了前面用的 rpQueuedReplot,还可以配合定时器做节流。

// 用定时器统一刷新,固定 30 FPS QTimer *refreshTimer = new QTimer(this); refreshTimer->setInterval(33); // 约 30 FPS connect(refreshTimer, &QTimer::timeout, this, [plot]() { plot->replot(QCustomPlot::rpQueuedReplot); }); refreshTimer->start(); // 数据到达时只更新数据,不立即重绘 void onDataArrived(double t, double v) { graph->addData(t, v); graph->data()->removeBefore(t - windowSec); // 不调用 replot,交给定时器 }

逻辑说明:把重绘从「数据到达触发」改成「定时触发」,一秒最多重绘 30 次,无论来多少数据。人眼对 30 FPS 已经感知流畅,再高是浪费。数据更新和渲染解耦后,CPU 占用会明显下降。

参数说明:33 毫秒对应约 30 FPS,要更流畅可以设 16(60 FPS),但 CPU 占用翻倍。监控场景 20 到 30 FPS 足够。注意定时器间隔别小于实际渲染耗时,否则会堆积。

4.3 多曲线场景的图层管理

一个趋势图里叠好几条曲线很常见,但每条都独立重绘会拖慢整体。合理做法是共享坐标轴、统一重绘。

// 多条曲线共享同一对坐标轴 QCPGraph *g1 = plot->addGraph(plot->xAxis, plot->yAxis); QCPGraph *g2 = plot->addGraph(plot->xAxis, plot->yAxis); g1->setPen(QPen(Qt::green)); g2->setPen(QPen(Qt::yellow)); // 统一重绘,不要每条曲线单独 replot // 数据更新后由定时器统一触发一次 replot

逻辑说明:addGraph 传入坐标轴指针让多条曲线共用坐标系,避免各自维护轴范围导致错位。重绘是整块画布的事,调一次和调十次成本差不多,所以统一触发。曲线数量超过五条时,考虑用不同颜色加图例区分,别堆太多。

参数说明:共享坐标轴后,纵轴范围要按所有曲线的数据综合计算,用 rescaleValueAxis 时注意它会考虑所有绑定到该轴的曲线。如果某条曲线量纲差异大,考虑用第二纵轴。

5. 时间轴趋势图避坑清单:五个血泪教训

这一章全是踩过的坑,每条按现象、原因、解决写,能帮你省下大量调试时间。

5.1 曲线拖动时突然空白

现象:用户快速拖动时间轴,曲线边缘出现空白区域,松手后才恢复。

原因:removeBefore 删数据删得太狠,把窗口左边界附近还在可视范围内的点也删了,导致拖动瞬间没有数据可画。

解决:removeBefore 的阈值要比窗口左边界再往左留一段余量,比如多留窗口长度的 10%。或者改成按数据点数量上限删除,而不是按时间。

5.2 时间标签显示成 1970 年

现象:横轴刻度全是 1970-01-01 附近的时间。

原因:时间戳单位搞错了,把毫秒当秒喂进去,或者把秒当毫秒。1970 加上一个很小的秒数就是 1970 年初。

解决:统一在数据入口处做单位转换,所有时间戳进图前都转成秒。加一个断言检查时间戳范围,比如小于 1e9 的肯定是错的(那对应 2001 年之前)。

5.3 长时间运行内存持续上涨

现象:程序跑几小时后内存从几十兆涨到几个 G。

原因:只 addData 不删老数据,graph 的数据容器无限增长。或者每次 replot 都新建 QCPGraph 没释放。

解决:每次追加后调 removeBefore 清理窗口外数据。曲线对象只创建一次,复用。用任务管理器或 Qt 的内存分析工具定期观察。

5.4 缩放后纵轴范围乱跳

现象:用户缩放横轴时,纵轴范围跟着剧烈变化,曲线忽大忽小。

原因:每次数据更新都调 rescaleValueAxis,而它按当前可视范围内的数据算范围,横轴一变范围就变。

解决:纵轴范围要么固定,要么只在数据超出当前范围时才扩(rescaleValueAxis 的 onlyEnlarge 参数设 true)。或者干脆手动设一个合理的固定范围。

5.5 高 DPI 屏上曲线模糊

现象:在 4K 屏或缩放 150% 的屏幕上,曲线和文字发虚。

原因:Qt 的高 DPI 缩放和 QCustomPlot 的像素计算没对齐,绘制时用了逻辑像素但没考虑设备像素比。

解决:在 main 里开启高 DPI 支持,并给 QCustomPlot 设置正确的 devicePixelRatio。Qt5 用 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling),Qt6 默认开启。必要时重写 paintEvent 手动处理缩放。

6. 把趋势图做成能复用的控件:封装与验证

前面讲的都是单次实现,真正做项目时你会希望把它封装成一个可复用控件,下次直接拖进界面就能用。这一章讲封装思路和一个验证方法。

封装的核心是把「数据接口」和「渲染细节」分开。对外暴露三个方法:appendPoint(timestamp, value) 追加数据、setWindowSeconds(sec) 设窗口长度、setYRange(min, max) 设纵轴范围。内部自己管理 QCustomPlot、定时器、数据清理。这样调用方不用关心 QCustomPlot 的任何 API,换绘图底座时也不影响业务代码。

class TrendChart : public QWidget { Q_OBJECT public: explicit TrendChart(QWidget *parent = nullptr); void appendPoint(double timestampSec, double value); void setWindowSeconds(double sec); void setYRange(double min, double max); private: QCustomPlot *m_plot; QCPGraph *m_graph; QTimer *m_refreshTimer; double m_windowSec = 60.0; double m_lastTimestamp = 0; void onRefresh(); }; void TrendChart::appendPoint(double timestampSec, double value) { m_graph->addData(timestampSec, value); m_lastTimestamp = timestampSec; // 数据清理和重绘交给定时器,保持接口轻量 } void TrendChart::onRefresh() { if (m_lastTimestamp <= 0) return; double left = m_lastTimestamp - m_windowSec; m_graph->data()->removeBefore(left); m_plot->xAxis->setRange(left, m_lastTimestamp); m_plot->replot(QCustomPlot::rpQueuedReplot); }

逻辑说明:appendPoint 只做数据插入,不触发重绘,保证高频调用时开销最小。onRefresh 由定时器驱动,统一做清理、范围更新和重绘。这样数据生产和渲染彻底解耦,是实时控件该有的结构。

参数说明:m_windowSec 通过 setWindowSeconds 修改,改完下次刷新生效。setYRange 直接设坐标轴范围,覆盖自动缩放。定时器间隔在构造函数里设,一般 33 毫秒。

验证方法:写一个模拟数据源,用 QTimer 每 50 毫秒产生一个正弦波加噪声的采样值,喂给控件跑十分钟。观察三件事:内存是否稳定、拖动是否流畅、时间标签是否正确。如果十分钟后内存涨幅在几兆以内、拖动无明显卡顿,基本就达标了。我一般还会故意把系统时间往前调一天,看时间轴会不会错乱,这是检验时间戳处理是否健壮的好办法。

做这类控件我最大的教训是:别一上来就追求功能全,先把「稳定跑一小时不崩、不卡、不涨内存」这条底线守住,再往上加交互和样式。很多看起来炫酷的趋势图,跑半小时就露馅。希望帮到你。

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

相关新闻

AST对象合并:JS反混淆中被低估的结构重建关键技术

AST对象合并:JS反混淆中被低估的结构重建关键技术

1. 为什么“对象合并”是AST反混淆里最常被低估的突破口在做JS反混淆项目时&#xff0c;我见过太多人一上来就盯着字符串解密、控制流扁平化、变量名还原这些“显眼包”问题猛攻。结果花三天调通了一个Deobfuscator插件&#xff0c;跑完发现代码还是满屏的_0x1a2b3c[push](_0x4…

2026/10/20 8:57:32 阅读更多 →
从卫星通信频段干扰到低噪声放大器自激振荡:一次射频前端故障的完整排查与整改

从卫星通信频段干扰到低噪声放大器自激振荡:一次射频前端故障的完整排查与整改

有一类投诉&#xff0c;会在邮件到达的那一刻就让整个研发团队安静下来。半个月前&#xff0c;我接到某卫星地球站客户的电话&#xff0c;说他们在 1400-1427MHz 频段的下行接收链路里&#xff0c;持续出现一个时有时无的强干扰信号&#xff0c;严重时整条链路信噪比掉到没法用…

2026/10/20 8:57:32 阅读更多 →
OpenClaw+飞书:AI跨境电商选品系统的落地实践

OpenClaw+飞书:AI跨境电商选品系统的落地实践

做跨境电商选品这行当&#xff0c;最折磨人的不是找不到数据&#xff0c;而是数据散落在各种地方&#xff1a;某平台后台的销量趋势、运营工具里的关键词热度、供应链那边给的供货价&#xff0c;还有三方数据服务商每周发来的一堆行业报告。以前我们团队的做法是运营手动汇总Ex…

2026/10/20 8:57:32 阅读更多 →

最新新闻

AI课程矩阵实战路线:从提示词工程到API调用与批量部署

AI课程矩阵实战路线:从提示词工程到API调用与批量部署

AI 课程现在不难找&#xff0c;难的是判断一门课在你的成长路径里到底处于哪个位置。市面上大量课程要么只教提示词&#xff0c;要么直接堆 ComfyUI 节点&#xff0c;学完能复现案例&#xff0c;但换个场景就不会用了。“河南元力共生 AI 课程矩阵”这个提法&#xff0c;核心是…

2026/10/20 9:45:00 阅读更多 →
秋招十月下旬还没回音:剩下六周怎么排

秋招十月下旬还没回音:剩下六周怎么排

版权与内容来源声明 本文为原创整理。文中涉及官方文档、开源仓库、论文与公开报道的内容&#xff0c;均在附表 A 中标注来源&#xff1b;引用官方原文保持原样&#xff0c;不作改写。文中命令、版本号与界面截图以本文成文时的实测/核验结果为准&#xff0c;标注「待验证」的部…

2026/10/20 9:45:00 阅读更多 →
Matlab GUI实时均衡器:IIR滤波器零极点与音频信号流协同设计

Matlab GUI实时均衡器:IIR滤波器零极点与音频信号流协同设计

简介&#xff1a;本资源是一份面向数字信号处理初学者与Matlab GUI入门者的实践型教学项目&#xff0c;聚焦音频信号频率响应调节这一典型应用场景&#xff0c;帮助学习者掌握IIR滤波器设计原理与交互式界面开发方法。压缩包共3个文件&#xff08;2个.m主程序与辅助函数、1个.f…

2026/10/20 9:45:00 阅读更多 →
企业网盘选型实测:安全管控与协作效率深度对比

企业网盘选型实测:安全管控与协作效率深度对比

测评类文章最容易犯的毛病&#xff0c;就是把配置参数罗列一通&#xff0c;最后丢一句“按需选择”就完事。这篇不一样&#xff0c;我从企业实际使用的角度出发&#xff0c;把真正影响日常协作和数据安全的关键点都拆开讲清楚&#xff0c;包括那些厂商不会主动告诉你的限制和坑…

2026/10/20 9:45:00 阅读更多 →
AI日报系统设计与实现:从RSS聚合到智能摘要生成

AI日报系统设计与实现:从RSS聚合到智能摘要生成

我无法基于当前输入生成符合要求的博文。原因如下&#xff1a;输入中项目标题为“AI 日报&#xff08;2026年10月10日&#xff09;”&#xff0c;但该标题本身不具备可拆解的实质性项目属性——它是一个时间标记型信息聚合名称&#xff0c;而非具体技术实现、工具开发、系统搭建…

2026/10/20 9:45:00 阅读更多 →
FPGA+AD/DA协同设计:H题信号发生器与频谱分析的时序工程实践

FPGA+AD/DA协同设计:H题信号发生器与频谱分析的时序工程实践

简介&#xff1a;本资源为2024年全国大学生电子设计竞赛H题完整参赛代码工程包&#xff0c;面向电子类、自动化、通信等专业本科生及嵌入式开发初学者&#xff0c;聚焦高实时性、强稳定性嵌入式系统实现场景。压缩包含180个文件&#xff0c;主体为C语言源码&#xff08;c/h&…

2026/10/20 9:43:58 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →