STM32单片机FFT实战:CMSIS-DSP实现振动监测与频谱分析

简介:这份资源面向嵌入式开发初学者与数字信号处理方向的工程师,围绕STM32F1系列单片机(ARM Cortex-M3内核)讲解FFT快速傅里叶变换的完整实现方案,帮助读者把时域采样信号转换到频域,用于通信、音频与图像等场景的频率成分分析。压缩包共225个文件,约4.12MB,以60个h头文件与56个c源文件为核心,配合30个o目标文件、30个d依赖文件及27个crf编译记录,另有uvprojx、uvoptx工程文件、map映射表、hex烧录文件与bat脚本,覆盖从源码到编译产物的完整工程结构。资源涉及Cortex-M3内核特性、Cooley-Tukey蝶形运算与位反转、SRAM内存布局、TIM定时器中断触发、CMSIS-DSP库调用及误差与实时性分析等知识点,并附带TFTLCD、ADC、I2C、CAN等外设驱动源码,便于对照调试与性能优化。目前已有10174人学习下载,适合希望系统掌握STM32平台FFT落地方案的读者参考。

1. 为什么我劝你先别急着上DSP:STM32做FFT的真实落地场景

前阵子帮一个做振动监测的朋友看代码,他用STM32F103采集加速度传感器信号,想算出主频判断设备有没有异常。一开始他打算外挂一块专用DSP芯片,结果板子空间不够、成本也压不下来。我让他直接在STM32上跑FFT,用芯片自带的ADC采样、DMA搬运、CMSIS-DSP库做运算,整条链路在一颗几十块钱的单片机上就跑通了。这件事让我意识到,很多做嵌入式信号处理的人对“STM32单片机实现FFT”有误解,觉得精度不够、速度太慢,实际上对于几百Hz到几十kHz的振动、音频、电流谐波分析场景,STM32的算力完全够用。这篇笔记就围绕这个项目,把FFT在STM32上的完整实现路径拆开讲清楚,从采样配置到频谱输出,再到怎么改成你自己的应用。适合正在做嵌入式信号采集、想把频谱分析塞进单片机的开发者,也适合刚接触CMSIS-DSP库、想找一个能跑通的完整例程的人。

2. 项目定位与技术选型:为什么是CMSIS-DSP而不是自己手写蝶形运算

2.1 这个项目到底在做什么

项目核心目标很明确:用STM32的ADC对模拟信号进行等间隔采样,把采样数据送进FFT算法,输出各个频率分量的幅值,从而判断信号的主频成分。典型应用包括电机振动监测、音频频谱显示、电网谐波分析、传感器信号特征提取。整个系统不需要操作系统,裸机跑主循环加中断即可,资源占用小,适合成本敏感的批量产品。

技术栈上,主控选STM32F4系列(比如F407或F411),原因是它带FPU浮点运算单元,做浮点FFT时速度比F1系列快一个数量级。如果非要用F103,那就得用Q15定点格式,精度和动态范围会打折扣。开发环境用STM32CubeIDE或者Keil MDK都行,库依赖ST官方的HAL库加上ARM的CMSIS-DSP库。CMSIS-DSP是ARM官方为Cortex-M系列优化的数字信号处理库,里面已经写好了FFT、FIR、IIR等常用算法,直接调用就行,没必要自己手写蝶形运算——手写的版本在代码体积和运行效率上通常都不如官方库。

2.2 采样率、点数与频率分辨率的关系

这三个参数是FFT应用里最容易翻车的地方,必须先算清楚。频率分辨率等于采样率除以FFT点数。比如采样率设为10kHz,做1024点FFT,分辨率就是9.77Hz,意味着你能区分的最小频率间隔是9.77Hz。如果两个信号频率差小于这个值,频谱上就会糊在一起。

另一个约束是采样定理:采样率必须大于信号最高频率的两倍。实际工程中一般取2.5到5倍,留出抗混叠滤波器的过渡带。比如你要分析最高5kHz的信号,采样率至少设12.5kHz,稳妥点设20kHz以上。

点数选择上,STM32的RAM有限,F407有192KB SRAM,做4096点浮点FFT需要两个4096长度的float数组(实部+虚部),每个float占4字节,一共32KB,加上其他变量和栈空间,勉强够用。如果RAM紧张,可以用1024点或2048点,或者改用Q15定点格式把内存减半。

参数典型值说明
采样率10kHz~50kHz根据信号最高频率的2.5~5倍选取
FFT点数1024 / 2048 / 4096点数越大分辨率越高,但RAM和运算时间增加
频率分辨率采样率/点数例如10kHz/1024≈9.77Hz
数据格式float32 或 q15F4带FPU优先用float32

2.3 整体数据流设计

从信号到频谱,数据流是这样的:模拟信号经过抗混叠滤波(硬件RC低通或者运放搭建的有源滤波)进入ADC引脚,定时器触发ADC以固定频率采样,DMA把ADC结果搬运到缓冲区,攒够N个点后触发中断,在主循环或中断回调里调用CMSIS-DSP的FFT函数,最后对复数结果求模得到幅值谱。这个链路里,定时器触发保证采样间隔严格均匀,DMA搬运不占CPU,是保证FFT精度的关键。如果采样间隔不均匀,频谱会出现杂散,相当于人为引入了相位噪声。

3. 工程搭建与核心代码:从CubeMX配置到FFT输出完整链路

3.1 CubeMX里的时钟、ADC与DMA配置

先在STM32CubeMX里把时钟树配好。以F407为例,外部晶振8MHz,经过PLL倍频到168MHz系统时钟。ADC时钟不能超过36MHz,所以APB2分频后给ADC的时钟要控制在36MHz以内。定时器时钟设为84MHz(APB1定时器时钟)。

ADC配置为独立模式,规则通道,使能连续转换模式关闭(我们用定时器触发),外部触发源选定时器TRGO事件。DMA设置成循环模式,数据宽度半字(ADC是12位,用uint16_t存),内存地址递增,外设地址不变。

定时器配置为向上计数,预分频器和自动重载值决定采样率。公式是:采样率 = 定时器时钟 / ((PSC+1)*(ARR+1))。比如定时器时钟84MHz,想要10kHz采样率,可以设PSC=0,ARR=8399,这样84MHz/8400=10kHz。

// 定时器3初始化,产生10kHz触发信号 void MX_TIM3_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim3.Instance = TIM3; htim3.Init.Prescaler = 0; // 不分频 htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 8399; // 84MHz / 8400 = 10kHz htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; HAL_TIM_Base_Init(&htim3); sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig); // 配置TRGO输出,用于触发ADC sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig); }

这段代码把TIM3配成10kHz更新事件,每次更新时TRGO输出一个脉冲触发ADC。参数说明:Prescaler是预分频,0表示不分频;Period是自动重载值,实际分频系数是Period+1;MasterOutputTrigger选TIM_TRGO_UPDATE表示更新事件触发。

3.2 DMA搬运与采样缓冲区管理

ADC采集到的数据需要连续不断地存到数组里,用DMA可以完全不占CPU。定义一个长度为FFT点数的uint16_t数组作为DMA目标地址,DMA循环模式会让它自动回卷。但要注意,FFT运算需要一帧完整的数据,所以通常用双缓冲或者半传输中断加传输完成中断来管理。

#define FFT_SIZE 1024 uint16_t adc_buf[FFT_SIZE]; // ADC原始数据 float fft_input[FFT_SIZE * 2]; // FFT输入:实部+虚部交错 float fft_output[FFT_SIZE]; // FFT幅值输出 // DMA传输完成回调,一帧数据攒够后触发 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { // 把ADC数据转成float并去直流分量 float sum = 0.0f; for (int i = 0; i < FFT_SIZE; i++) { sum += (float)adc_buf[i]; } float mean = sum / FFT_SIZE; for (int i = 0; i < FFT_SIZE; i++) { fft_input[2*i] = ((float)adc_buf[i] - mean) * 3.3f / 4096.0f; fft_input[2*i+1] = 0.0f; // 虚部清零 } // 这里可以置标志位,在主循环里做FFT fft_ready = 1; }

这段回调里做了三件事:求均值去直流、把ADC码值转成电压、虚部清零。去直流很重要,如果信号有直流偏置,FFT结果在0Hz处会有一个很大的峰,可能掩盖低频成分。电压转换系数3.3f/4096.0f是因为ADC是12位,参考电压3.3V。虚部清零是因为输入是实信号,FFT之前虚部必须为0。

3.3 调用CMSIS-DSP的FFT函数

CMSIS-DSP提供了多种FFT函数,实数FFT用arm_rfft_fast_f32效率最高,它内部会把实信号打包成复数再运算,比直接用复数FFT省一半计算量。初始化时先创建实例,然后调用初始化函数,最后执行变换。

#include "arm_math.h" arm_rfft_fast_instance_f32 fft_inst; void fft_init(void) { // 初始化实数FFT实例,参数是点数 arm_rfft_fast_init_f32(&fft_inst, FFT_SIZE); } void fft_process(void) { // 执行FFT,fft_input是交错格式的实部虚部 arm_rfft_fast_f32(&fft_inst, fft_input, fft_output, 0); // 求模得到幅值谱,注意输出是对称的,只看前一半 arm_cmplx_mag_f32(fft_output, fft_output, FFT_SIZE / 2); // 找最大峰值对应的频率 float max_val; uint32_t max_idx; arm_max_f32(fft_output, FFT_SIZE / 2, &max_val, &max_idx); // 频率 = 索引 * 采样率 / FFT点数 float peak_freq = (float)max_idx * SAMPLE_RATE / FFT_SIZE; }

arm_rfft_fast_f32的第三个参数是输出数组,第四个参数0表示正向变换(1是逆变换)。注意实数FFT的输出格式比较特殊:输出数组的前半部分是复数频谱的实部,后半部分是虚部,但arm_cmplx_mag_f32可以直接处理这种打包格式,所以不用手动拆。求模之后结果是对称的,只需要看前N/2个点。最后用arm_max_f32找峰值索引,乘以频率分辨率就得到主频。

3.4 加窗与频谱泄漏处理

如果信号频率不是频率分辨率的整数倍,FFT会出现频谱泄漏,峰值附近出现拖尾。工程上一般加汉宁窗或汉明窗来抑制。加窗的代价是主瓣变宽,频率分辨率略微下降,但峰值幅度更准确。

// 生成汉宁窗系数 float window[FFT_SIZE]; for (int i = 0; i < FFT_SIZE; i++) { window[i] = 0.5f * (1.0f - arm_cos_f32(2.0f * PI * i / (FFT_SIZE - 1))); } // 在ADC回调里加窗 for (int i = 0; i < FFT_SIZE; i++) { fft_input[2*i] = ((float)adc_buf[i] - mean) * 3.3f / 4096.0f * window[i]; fft_input[2*i+1] = 0.0f; }

加窗之后幅值需要乘以补偿系数,汉宁窗的相干增益是0.5,所以幅值要乘2才能还原真实幅度。如果只是找主频位置,不做绝对幅度测量,可以不加补偿。

4. 避坑与常见问题:采样、内存和精度上的血泪经验

4.1 采样率不对导致频谱整体偏移

现象:频谱上峰值位置和信号源频率对不上,偏差很大且没有规律。原因通常是定时器配置算错了,或者ADC触发源没选对。比如定时器时钟不是你以为的84MHz,而是经过分频后的42MHz,采样率就变成5kHz,所有频率读数翻倍。解决方法是先用示波器测ADC触发引脚或者用GPIO翻转法确认实际采样率,再反推定时器参数。我一般会在定时器中断里翻转一个IO口,用示波器看方波频率,确认无误后再接传感器。

4.2 内存溢出导致HardFault

现象:程序跑一会儿就进HardFault,或者FFT结果全是乱码。原因多半是数组太大,栈溢出或者堆不够。F407的默认栈大小在启动文件里是0x400(1KB),如果FFT数组定义在局部变量里,1024点浮点数组就要8KB,直接爆栈。解决办法是把大数组定义成全局变量或者用static修饰,放到静态存储区。另外检查链接脚本里的RAM分配,确保堆栈区域够用。

4.3 直流偏置淹没低频分量

现象:频谱上0Hz附近有一个巨大峰值,低频信号完全看不见。原因是ADC采集到的信号有直流偏置,比如传感器输出叠加了1.65V的偏置电压。FFT对直流分量非常敏感,0Hz处的幅值会非常大。解决办法是在FFT之前减去均值,代码里就是先求和再减去平均值。如果偏置是缓慢漂移的,可以用高通滤波器先滤掉。

4.4 频谱泄漏导致峰值判断错误

现象:信号频率在两个频点之间时,峰值出现在错误的索引上,或者出现两个相近的峰。原因是没加窗或者窗函数选得不对。矩形窗泄漏最严重,汉宁窗和汉明窗抑制效果好但主瓣宽。解决办法是根据应用选窗:如果只关心主频位置,汉宁窗够用;如果需要区分相近频率,用矩形窗但增加点数。另外可以用抛物线插值法对峰值索引做修正,提高频率估计精度。

4.5 浮点运算速度不够导致实时性差

现象:FFT运算时间太长,采样数据来不及处理,缓冲区被覆盖。F103没有FPU,浮点FFT跑1024点可能要几十毫秒。解决办法是换F4系列带FPU的芯片,或者改用Q15定点格式。CMSIS-DSP提供了arm_rfft_q15函数,速度比浮点快很多,但要注意数据范围不能超过Q15的表示范围(-1到1),输入前要归一化。

5. 二次开发与改造:把FFT例程变成你自己的产品代码

5.1 从固定点数改成动态配置

原始例程里FFT_SIZE是宏定义,编译时固定。实际产品可能需要根据上位机命令切换分辨率,比如低功耗模式下用256点,高精度模式下用4096点。改造思路是把FFT实例和缓冲区都做成结构体,运行时根据配置参数初始化。

typedef struct { arm_rfft_fast_instance_f32 inst; float *input; float *output; uint16_t size; float sample_rate; } fft_handle_t; int fft_config(fft_handle_t *h, uint16_t size, float fs) { h->size = size; h->sample_rate = fs; h->input = (float *)malloc(size * 2 * sizeof(float)); h->output = (float *)malloc(size * sizeof(float)); if (!h->input || !h->output) return -1; arm_rfft_fast_init_f32(&h->inst, size); return 0; }

这样改造后,上层应用只需要调用fft_config传入点数和采样率,不用关心底层细节。注意malloc在单片机上要慎用,容易产生碎片,更稳妥的做法是预分配最大尺寸的静态数组,运行时只改size参数。

5.2 增加峰值插值提高频率精度

直接取最大索引的频率分辨率有限,比如10kHz采样1024点,分辨率9.77Hz。如果信号是50.3Hz,峰值可能落在51.7Hz的索引上。用抛物线插值可以把精度提高到1Hz以内。

// 抛物线插值修正峰值索引 float interpolate_peak(float *mag, uint32_t idx, uint16_t size) { if (idx == 0 || idx >= size - 1) return (float)idx; float alpha = mag[idx - 1]; float beta = mag[idx]; float gamma = mag[idx + 1]; float delta = 0.5f * (alpha - gamma) / (alpha - 2.0f * beta + gamma); return (float)idx + delta; }

这个公式利用峰值左右两个点的幅值做二次拟合,delta是偏移量,范围在-0.5到0.5之间。修正后的索引乘以频率分辨率就是更准确的频率估计。注意如果峰值在边界上(索引0或N/2-1),插值会失效,需要特殊处理。

5.3 多通道FFT与结果上报

实际产品往往需要同时分析多路信号,比如三相电流的谐波。改造方法是给每个通道分配独立的ADC缓冲区和FFT实例,用DMA的多个通道或者ADC扫描模式轮流采集。运算时可以分时复用同一个FFT实例,只要保证数据不冲突。

结果上报一般通过UART或CAN发给上位机。建议定义一个简单的协议帧,包含通道号、峰值频率、峰值幅值、时间戳。如果上位机需要完整频谱,可以把幅值数组按一定间隔抽取后发送,避免数据量过大。

改造方向关键改动注意事项
动态点数结构体封装+运行时初始化避免频繁malloc,预分配最大缓冲区
峰值插值增加插值函数边界索引需特殊处理
多通道多缓冲区+分时复用FFT实例注意DMA通道冲突
结果上报自定义协议帧控制发送频率,避免阻塞采样

5.4 验证方法:用信号发生器闭环测试

改完之后怎么验证?我一般用信号发生器输出一个已知频率的正弦波,比如1kHz、幅度1Vpp,接到ADC输入端。然后看串口打印的峰值频率是不是1kHz附近,幅值是不是和输入匹配。如果频率对不上,先查采样率;如果幅值不对,查窗函数补偿和ADC参考电压。再用示波器看ADC输入引脚,确认信号没有失真。最后把信号频率改成非整数倍分辨率的值,比如1.005kHz,看插值后的结果是否准确。

从那以后我每次做FFT相关的项目,都会先用信号发生器跑一遍单频点闭环,确认采样率、窗函数、插值三个环节都没问题,再接真实传感器。这个习惯帮我省了很多调试时间,也避免过把传感器装到设备上才发现频谱不对的尴尬。希望帮到你。

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

相关新闻

C++11引入的STL中的unordered系列关联式容器

C++11引入的STL中的unordered系列关联式容器

前言 C11 引入了四个无序关联容器&#xff1a;std::unordered_map、std::unordered_set、std::unordered_multimap、std::unordered_multiset。它们位于 <unordered_map> 与 <unordered_set> 两个头文件中&#xff0c;底层基于哈希表&#xff0c;平均情况下查找、插…

2026/10/20 15:02:37 阅读更多 →
美团CatPaw公开“录制生成Skill”后,测试团队要补哪条回归链?

美团CatPaw公开“录制生成Skill”后,测试团队要补哪条回归链?

摘要&#xff1a;从美团CatPaw公开的一键录制能力出发&#xff0c;拆解Skill版本、权限、Trace与业务副作用的回归闭环。美团技术团队公开介绍 CatPaw 时&#xff0c;给出了一项很容易让测试人产生画面的能力&#xff1a;内嵌浏览器可以一键录制操作过程&#xff0c;把日常高频…

2026/10/20 15:02:37 阅读更多 →
OpenClaw+飞书多智能体实战:架构、调度与群聊机器人落地

OpenClaw+飞书多智能体实战:架构、调度与群聊机器人落地

1. 为什么选择“OpenClaw 飞书 多智能体”这个组合 说句实在话&#xff0c;刚拿到 OpenClaw 这套工具链的时候&#xff0c;我第一反应是“又一个套壳框架”。但真正跑起来之后&#xff0c;我发现它对智能体的编排方式和飞书开放平台的契合度&#xff0c;确实比我预想中要顺滑…

2026/10/20 15:02:37 阅读更多 →

最新新闻

MATLAB贝叶斯优化实战:bayesopt代码案例与调参避坑指南

MATLAB贝叶斯优化实战:bayesopt代码案例与调参避坑指南

简介&#xff1a;这份MATLAB代码案例面向需要处理高成本、黑盒或高维函数优化问题的科研人员与工程开发者&#xff0c;围绕贝叶斯优化这一全局优化方法展开。资源以zip压缩包形式提供&#xff0c;共2个文件&#xff0c;均为.m脚本&#xff0c;包体约641B&#xff0c;体量轻巧&a…

2026/10/20 21:20:10 阅读更多 →
技能管理:拆解、练习、复盘与复利,系统化打造个人竞争力

技能管理:拆解、练习、复盘与复利,系统化打造个人竞争力

“skills”&#xff0c;中文翻译过来就是“技能”。这个词在各种岗位描述、简历模板、年终总结里反复出现&#xff0c;但说实话&#xff0c;大多数人并没有认真琢磨过“技能”这两个字背后到底意味着什么。我自己带过不少人&#xff0c;也做过很多项目&#xff0c;越来越强烈的…

2026/10/20 21:20:10 阅读更多 →
即梦AI生图提示词全攻略:三层结构+六大维度

即梦AI生图提示词全攻略:三层结构+六大维度

1. 即梦AI提示词先搞懂这三层逻辑1.1 提示词不是“魔法咒语”&#xff0c;而是“设计简报”我经常看到有人在群里贴出一大段英文提示词&#xff0c;里面全是 masterpiece、best quality、8k、ultra-detailed&#xff0c;结果出图还是翻车。问题不在模型不行&#xff0c;而是提示…

2026/10/20 21:20:10 阅读更多 →
CCF CSP DHCP服务器模拟:状态机与时间驱动实战

CCF CSP DHCP服务器模拟:状态机与时间驱动实战

1. 这道题到底在考什么DHCP 这个协议&#xff0c;干网络运维的人天天见&#xff0c;但真让你手写一个 DHCP 服务器的状态机&#xff0c;很多人第一反应是"不就是分配 IP 吗"。我当初也是这么想的&#xff0c;直到把 CCF202104-3 这道题完整跑通&#xff0c;才发现坑全…

2026/10/20 21:20:10 阅读更多 →
DHCP服务器模拟题解析:状态机设计与租约管理实战

DHCP服务器模拟题解析:状态机设计与租约管理实战

1. 从一道模拟题看DHCP服务器的核心机制DHCP服务器这个题目&#xff0c;放在编程竞赛里是一道典型的模拟题&#xff0c;但它的价值远不止于拿100分。我做了这么多年后端开发&#xff0c;见过太多人对网络协议的理解停留在“背八股”的层面&#xff0c;真让他手写一个状态机来处…

2026/10/20 21:20:09 阅读更多 →
AI Agent成本结构全解析:从API调用费到隐性人力的完整账本

AI Agent成本结构全解析:从API调用费到隐性人力的完整账本

先说一个我最近复盘的真实项目。某电商团队上线了一个订单查询与退换货的客服 Agent&#xff0c;第一周看账单&#xff0c;推理费一天几百块&#xff0c;负责人很高兴&#xff0c;觉得这玩意儿比招人划算多了。三个月后做财务复盘&#xff0c;把所有配套成本拉出来一算&#xf…

2026/10/20 21:19:04 阅读更多 →

日新闻

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/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

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

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

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

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

如果你的信息流最近也天天刷到“机器人大脑”这个词&#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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →