基于Matlab的指纹识别系统:预处理、特征提取与GUI实现

简介:这份资源面向计算机、电子信息工程、数学等专业的大学生,提供一套基于Matlab实现的指纹识别系统完整毕业设计参考方案,适合用于课程设计、期末大作业或毕业设计阶段的学习与借鉴。资源包内含源码、图片素材、PPT演示文稿及课题介绍文档,能够帮助读者理解指纹图像预处理、特征提取与匹配识别等核心环节的实现思路,并借助GUI可视化界面直观展示识别流程与结果。压缩包为rar格式,整体约3.54MB,文件类型涵盖程序源码、图像素材与演示文档,分别对应算法实现、测试数据与答辩展示等用途。目前已有388人学习关注,说明该方案在同类课题中具有一定参考价值。读者可据此梳理指纹识别系统的整体架构,参考界面布局与模块划分,并结合自身课题需求进行调试与功能扩展,从而提升毕业设计的完成效率与展示效果。

1. 指纹识别系统到底在做什么:从一张灰度图到匹配分数的完整链路

很多人第一次接触指纹识别,以为核心是“比对两张图像不像”。真跑起来才发现,难点根本不在比对,而在前处理——脊线增强、方向场估计、二值化、细化,每一步都能让最终匹配分数天差地别。这个毕业设计题目之所以经典,是因为它把图像处理、特征提取、GUI 工程三件事串成了一条完整链路,而且用 Matlab 实现时每一步都看得见中间结果,特别适合拿来理解“算法到底在干什么”。它适合两类人:一是要做图像处理方向毕设、需要一套能跑通、能演示、能写论文的系统;二是已经写过一些 Matlab 脚本,但没做过完整 GUI 项目、想补上“从算法到界面”这一环的人。下面我按实际落地顺序,把这条链路拆开讲。

2. 指纹图像预处理:为什么直接匹配原始图一定翻车

2.1 从灰度图到方向场:三个必调的参数

指纹原图直接送进匹配环节,结果基本是玄学。原因很简单:采集时手指压力不均、有汗渍、有划痕,脊线时断时续,直接算相似度等于在噪声里找信号。所以第一步必须做增强。常见做法是先用 Gabor 滤波器按局部脊线方向做滤波,而 Gabor 的核心参数有三个:方向数、频率、以及滤波窗口大小。

方向数一般取 8 或 16。取 8 时每个方向覆盖 22.5 度,对大多数指纹够用;取 16 会更精细,但计算量翻倍,GUI 里点一下要等好几秒,体验很差。频率指的是脊线间距的倒数,典型指纹脊线间距在 5 到 10 像素之间,所以频率参数通常设成 0.1 左右(周期约 10 像素)。窗口大小决定局部方向估计的平滑程度,太小方向场抖动,太大又糊掉细节,我一般从 16 开始试,根据图像分辨率微调。

% 指纹方向场与频率估计(简化版核心逻辑) % img: 输入灰度图,已归一化到 [0,1] % blkSize: 分块大小,常用 16 function [orient, freq] = estimateOriFreq(img, blkSize) [h, w] = size(img); % 梯度计算,Sobel 算子 [Gx, Gy] = gradient(img); % 分块累加梯度平方和 orient = zeros(ceil(h/blkSize), ceil(w/blkSize)); freq = zeros(size(orient)); for i = 1:blkSize:h for j = 1:blkSize:w i2 = min(i+blkSize-1, h); j2 = min(j+blkSize-1, w); gx = Gx(i:i2, j:j2); gy = Gy(i:i2, j:j2); % 方向场:利用梯度向量正交于脊线方向 num = sum(sum(2 * gx .* gy)); den = sum(sum(gx.^2 - gy.^2)); orient(ceil(i/blkSize), ceil(j/blkSize)) = 0.5 * atan2(num, den); % 频率估计:对脊线投影后做 FFT 取主峰 proj = sum(img(i:i2, j:j2), 1); proj = proj - mean(proj); if any(proj) f = abs(fft(proj)); [~, idx] = max(f(2:end)); freq(ceil(i/blkSize), ceil(j/blkSize)) = idx / length(proj); end end end end

这段代码里blkSize是最关键的参数。设 16 时,一块里通常包含 2 到 3 条脊线,方向估计比较稳;设 8 时块太小,噪声一大方向就乱;设 32 时块内脊线方向可能已经变了,估计出的方向没有代表性。atan2那行算的是梯度方向,因为梯度方向垂直于脊线,所以实际脊线方向要再转 90 度,后面 Gabor 滤波时用的时候注意这个关系。频率估计用投影加 FFT 是最省事的做法,但要求块内至少有两个完整周期,所以blkSize不能小于脊线周期的两倍。

2.2 Gabor 增强与二值化:中间结果一定要存图

Gabor 滤波之后,脊线会变得清晰连续,但仍然是灰度图。接下来要二值化,把脊线变成黑白。这里有个血泪经验:二值化的阈值不要用全局固定值,因为图像不同区域的亮度差异很大。常见做法是用局部自适应阈值,或者直接对 Gabor 滤波后的图做归一化再取 0.5 作为阈值。

% Gabor 增强 + 局部自适应二值化 % orient, freq 来自上一步,blkSize 保持一致 function bw = enhanceAndBinarize(img, orient, freq, blkSize) [h, w] = size(img); bw = zeros(h, w); for i = 1:blkSize:h for j = 1:blkSize:w i2 = min(i+blkSize-1, h); j2 = min(j+blkSize-1, w); blk = img(i:i2, j:j2); theta = orient(ceil(i/blkSize), ceil(j/blkSize)); f = freq(ceil(i/blkSize), ceil(j/blkSize)); if f == 0 f = 0.1; % 兜底频率,防止除零 end % 构造 Gabor 核,方向 theta,频率 f sigma_x = 4; sigma_y = 4; [X, Y] = meshgrid(-8:8, -8:8); Xr = X * cos(theta) + Y * sin(theta); Yr = -X * sin(theta) + Y * cos(theta); gabor = exp(-(Xr.^2/(2*sigma_x^2) + Yr.^2/(2*sigma_y^2))) ... .* cos(2*pi*f*Xr); filtered = conv2(blk, gabor, 'same'); % 局部自适应阈值:块均值 th = mean(filtered(:)); bw(i:i2, j:j2) = filtered > th; end end end

sigma_x和sigma_y控制 Gabor 核的包络宽度,一般取脊线周期的 0.5 到 1 倍。取太小滤波核只覆盖一条脊线,增强效果弱;取太大又会把相邻脊线混在一起。conv2的'same'参数保证输出和输入同尺寸,方便后续按块拼回去。二值化用块均值做阈值是最简单的自适应方案,效果比全局阈值稳,但在脊线特别密或特别疏的区域仍可能出错,所以后面还要做形态学清理。

提示:每一步的中间结果都存成图片,写论文时直接放对比图,比文字描述有说服力得多。GUI 里也可以加一个“显示中间结果”的按钮,答辩时演示效果很好。

3. 特征提取与匹配:细节点怎么找、匹配分数怎么算

3.1 细化与细节点检测:交叉点为什么总被误检

二值化之后要做细化,把脊线变成单像素宽。Matlab 里可以用bwmorph的'thin'操作,迭代到稳定。细化之后,脊线上的端点和分叉点就是细节点。端点周围只有一个脊线像素,分叉点周围有三个。

% 细化 + 细节点检测 function [endpoints, bifurcations] = detectMinutiae(bw) % 细化到单像素宽 thin = bwmorph(bw, 'thin', Inf); % 交叉数计算:对每个前景像素,统计其 8 邻域内 0->1 的跳变次数 [h, w] = size(thin); endpoints = []; bifurcations = []; for i = 2:h-1 for j = 2:w-1 if thin(i, j) == 0 continue; end % 按顺时针取 8 邻域 nb = [thin(i-1,j-1), thin(i-1,j), thin(i-1,j+1), ... thin(i,j+1), thin(i+1,j+1), thin(i+1,j), ... thin(i+1,j-1), thin(i,j-1)]; % 统计 0 到 1 的跳变次数 cross = sum(abs(diff([nb, nb(1)]))) / 2; if cross == 1 endpoints = [endpoints; i, j]; elseif cross == 3 bifurcations = [bifurcations; i, j]; end end end end

交叉数等于 1 是端点,等于 3 是分叉点,这是标准定义。但实际跑起来会发现分叉点数量远多于真实值,原因是细化后脊线边缘不平滑,一个真实分叉点周围可能产生多个伪分叉。解决办法是检测完之后做一次聚类,把距离小于某个阈值(比如 5 像素)的同类细节点合并成一个。另外,图像边缘附近的细节点不可靠,因为那里脊线本来就不完整,通常会把边界 10 到 15 像素内的点全部丢弃。

3.2 匹配分数计算:阈值设多少才不误判

细节点提取完,每个点用位置、方向、类型三个属性描述。匹配时,取两幅图的细节点集合,对每个点找另一幅图中距离最近且方向差在容忍范围内的点,配对成功就计一分。最终匹配分数通常用配对点数除以两幅图细节点总数的平均值。

% 细节点匹配与分数计算 % m1, m2: 细节点结构体数组,字段为 x, y, theta, type function score = matchMinutiae(m1, m2, distTh, angTh) matched = 0; used = false(length(m2), 1); for i = 1:length(m1) bestDist = inf; bestIdx = 0; for j = 1:length(m2) if used(j) || m1(i).type ~= m2(j).type continue; end d = norm([m1(i).x - m2(j).x, m1(i).y - m2(j).y]); da = abs(m1(i).theta - m2(j).theta); da = min(da, 2*pi - da); % 角度差取小值 if d < distTh && da < angTh && d < bestDist bestDist = d; bestIdx = j; end end if bestIdx > 0 matched = matched + 1; used(bestIdx) = true; end end score = 2 * matched / (length(m1) + length(m2)); end

distTh是距离容忍阈值,一般取 8 到 12 像素。取太小,同一枚指纹两次采集的形变会导致大量漏配;取太大,不同指纹之间也会产生虚假配对。angTh是方向容忍角,通常取 0.2 到 0.3 弧度(约 11 到 17 度)。匹配分数在 0 到 1 之间,实际系统中判定为同一枚指纹的阈值通常在 0.3 到 0.5 之间,具体值要用一批样本跑 ROC 曲线来定,不能拍脑袋。

注意:匹配分数对细节点数量很敏感。如果一幅图提取出 80 个点,另一幅只有 20 个,即使全部配对成功,分数也只有 0.4。所以预处理阶段要尽量保证两幅图提取到的细节点数量在同一量级。

4. GUI 界面搭建:怎么让算法跑起来不卡、演示不翻车

4.1 界面布局与回调函数:三个必须分离的模块

Matlab 的 GUI 可以用guide也可以用App Designer。做毕设演示,我建议用App Designer,因为布局更灵活,回调函数结构更清晰。整个界面至少分三块:图像显示区、按钮操作区、结果输出区。按钮至少要有“加载图像”“预处理”“提取特征”“匹配”“清空”。

关键原则是:算法逻辑和界面回调必须分离。不要把预处理代码直接写在按钮回调里,而是封装成独立函数,回调只负责取数据、调函数、更新显示。这样做的好处是,调试算法时可以直接在命令行跑函数,不用反复点界面。

% App Designer 中“预处理”按钮的回调示例 function PreprocessButtonPushed(app, ~) if isempty(app.OriginalImage) uialert(app.UIFigure, '请先加载图像', '提示'); return; end % 调用独立封装的预处理函数 [enhanced, bw] = preprocessFingerprint(app.OriginalImage); % 更新显示 app.EnhancedImage = enhanced; app.BinaryImage = bw; imshow(enhanced, 'Parent', app.UIAxes2); imshow(bw, 'Parent', app.UIAxes3); % 更新状态 app.StatusLabel.Text = '预处理完成'; drawnow; % 强制刷新界面,避免卡顿 end

drawnow这行很关键。Matlab 默认会等回调函数全部执行完才刷新界面,如果预处理要跑好几秒,用户会以为程序卡死了。在每一步显示之后加drawnow,界面就能实时更新。但也不要每行都加,频繁刷新反而拖慢速度,一般在每个主要步骤结束后加一次。

4.2 图像加载与显示:路径、格式、尺寸的三个坑

加载图像时,常见做法是用uigetfile让用户选文件。这里有三个坑:第一,路径里如果有中文或空格,某些 Matlab 版本会读取出错,所以最好在加载后立刻把图像数据读进内存,后续不再依赖文件路径。第二,不同格式的图片读进来可能是 RGB,也可能是灰度,统一用rgb2gray转成灰度再处理。第三,图像尺寸不一致时,匹配阶段会出问题,所以要么在加载时统一缩放到固定尺寸,要么在匹配前做对齐。

% 图像加载与统一预处理 [file, path] = uigetfile({'*.jpg;*.png;*.bmp', '图像文件'}); if isequal(file, 0) return; % 用户取消 end fullPath = fullfile(path, file); img = imread(fullPath); if size(img, 3) == 3 img = rgb2gray(img); end % 统一缩放到 256x256,保持长宽比,不足补零 targetSize = [256, 256]; img = imresize(img, targetSize); app.OriginalImage = im2double(img); imshow(app.OriginalImage, 'Parent', app.UIAxes1);

imresize直接缩放到固定尺寸会改变脊线间距,进而影响频率估计。如果两幅图原始分辨率差异很大,更好的做法是先按脊线频率归一化,再缩放。但毕设演示中,如果所有测试图都来自同一个采集设备,直接缩放问题不大。im2double把像素值转到 0 到 1 之间,后续所有计算都基于这个范围,避免整数溢出。

5. 避坑与排查:那些让系统跑不起来的常见问题

5.1 匹配分数总是很低甚至为零

现象:两幅同一手指的图像,匹配分数只有 0.1 左右,甚至完全配不上。原因通常有三个:一是预处理参数不匹配,比如一幅图用了blkSize=16,另一幅用了 8,导致细节点位置系统性偏移;二是细节点方向计算时角度范围没统一,有的在[-pi/2, pi/2],有的在[0, pi],匹配时角度差算出来全是错的;三是图像没有对齐,两幅图的手指位置差了几十个像素,细节点距离全都超过阈值。解决办法:固定一套预处理参数,所有图像走同一条流水线;角度统一用atan2的输出范围[-pi, pi];匹配前先做基于细节点质心的粗对齐,或者用互相关找平移量。

5.2 GUI 点击按钮后界面卡死

现象:点了“提取特征”之后,界面十几秒没反应,然后突然跳出结果。原因:Matlab 回调函数执行期间不刷新界面。解决办法:在耗时循环里定期调用drawnow,或者用waitbar显示进度条。如果循环次数很多,每 100 次迭代加一次drawnow就够了。另外,如果算法里有大矩阵运算,可以考虑用parfor并行,但毕设规模一般用不上。

5.3 细化后脊线断裂成碎片

现象:bwmorph细化之后,原本连续的脊线变成一段一段的。原因:二值化时局部阈值选得不好,脊线中间出现了空洞,细化时这些空洞被放大成断裂。解决办法:二值化后先做一次闭运算(imclose)填小洞,再做细化。闭运算的结构元素用 3x3 圆盘就行,太大反而会把两条脊线粘在一起。

5.4 不同图像细节点数量差异巨大

现象:有的图提取出 100 多个细节点,有的只有 10 几个。原因:图像质量差异大,质量差的图脊线模糊,二值化后断断续续,细节点要么暴多(伪分叉)要么暴少(脊线断裂)。解决办法:在预处理阶段加一个质量评估,如果前景区域占比太低或者方向场一致性太差,直接提示“图像质量不合格,请重新采集”。这比强行匹配得出错误结果要好。

5.5 打包成 exe 后无法运行

现象:在 Matlab 里跑得好好的,用mcc打包成 exe 后报错。原因:GUI 里用了uigetfile等交互函数,打包后路径处理方式变了;或者依赖了某个工具箱函数,打包时没包含进去。解决办法:打包前用deploytool检查依赖,把所有用到的工具箱勾上。路径操作全部用fullfile拼接,不要手写斜杠。如果还是不行,在 exe 同目录下放一个readme.txt说明需要安装 Matlab Runtime,版本要和打包时一致。

6. 从能跑到能答辩:三个让系统更稳的进阶技巧

第一个技巧是加一个“批量测试”模式。毕设答辩时老师经常会问“你这个系统准确率多少”,如果你只能一张一张点,现场演示很尴尬。提前写一个脚本,把测试集里所有同一手指的配对和不同手指的配对跑一遍,算出准确率和误识率,画成 ROC 曲线放在 PPT 里。代码很简单,就是循环调用匹配函数,把分数存下来,最后用perfcurve画图。

% 批量测试与 ROC 曲线 scores = []; labels = []; for k = 1:length(pairs) img1 = loadImage(pairs(k).path1); img2 = loadImage(pairs(k).path2); [m1, ~] = extractMinutiae(img1); [m2, ~] = extractMinutiae(img2); s = matchMinutiae(m1, m2, 10, 0.25); scores = [scores; s]; labels = [labels; pairs(k).isSame]; % 1 表示同一手指,0 表示不同 end [X, Y, T, AUC] = perfcurve(labels, scores, 1); plot(X, Y); xlabel('误识率'); ylabel('正确接受率'); title(['ROC 曲线,AUC = ' num2str(AUC)]);

perfcurve的第三个参数1表示把标签为 1 的类当作正类。AUC 越接近 1 越好,0.5 相当于随机猜。毕设系统能做到 0.85 以上就算不错了,因为指纹采集设备、光照、手指状态都会影响结果。

第二个技巧是给 GUI 加一个“参数调节”面板。把blkSize、distTh、angTh这几个关键参数做成滑块或输入框,演示时可以现场调参,让老师看到参数变化对结果的影响。这比只展示一个固定结果有说服力得多。但要注意,参数调节后要清空之前的状态,避免旧数据干扰。

第三个技巧是保存和加载特征模板。匹配时不需要每次都重新提取特征,可以把细节点集合存成.mat文件,下次直接加载。这样批量测试时速度会快很多。保存时把图像路径、预处理参数、细节点集合一起存进去,加载时校验参数是否一致,不一致就提示重新提取。

提示:答辩前一定要用不同质量的图像多跑几遍,把可能翻车的情况都试出来。我见过太多演示时因为一张图质量太差导致整个流程卡住的例子,提前准备几张“保底图”放在手边,万一现场采集的图效果不好,可以换用保底图继续演示。

最后说一个我自己的习惯:每改一次预处理参数,就把所有中间结果图重新存一遍,按参数命名文件夹。这样当匹配结果变差时,可以快速对比是哪一步出了问题,而不是从头再跑一遍。这个习惯帮我省下了大量反复调试的时间。希望帮到你。

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

相关新闻

ManiSkill panda_wristcam 腕部相机机械臂:从最小示例到参数覆盖的完整指南

ManiSkill panda_wristcam 腕部相机机械臂:从最小示例到参数覆盖的完整指南

ManiSkill panda_wristcam 腕部相机机械臂&#xff1a;从最小示例到参数覆盖的完整指南 【免费下载链接】ManiSkill Manipulation Skill Framework, an open source GPU parallelized robotics simulator and benchmark 项目地址: https://gitcode.com/GitHub_Trending/ma/Ma…

2026/10/20 19:05:03 阅读更多 →
基于改进鲸鱼算法的六自由度机械臂3-5-3多项式时间最优轨迹规划

基于改进鲸鱼算法的六自由度机械臂3-5-3多项式时间最优轨迹规划

机械臂的轨迹规划&#xff0c;说白了就是在“怎么走”和“走多快”之间做交易。生产线节拍压得紧&#xff0c;机械臂末端就得跑得更快&#xff0c;但速度一上来&#xff0c;关节的冲击和振动也跟着上来&#xff0c;时间久了螺丝都能给你抖松。我做过的一个很典型的项目——基于…

2026/10/20 19:04:03 阅读更多 →
SpringBoot+Vue民宿管理系统源码实战:从跑通到吃透

SpringBoot+Vue民宿管理系统源码实战:从跑通到吃透

这种基于SpringBootVue的民宿管理系统源码项目&#xff0c;这几年一直特别多&#xff0c;到2025年依然有不少人拿着类似标题的代码来找我帮忙跑通、改需求。原因不复杂&#xff1a;民宿短租业务贴近实际、模块边界清晰、技术栈覆盖面够广&#xff0c;作为课程设计、毕业设计或者…

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

最新新闻

模型量化如何影响推理性能?实战解析原理、选型与问题排查

模型量化如何影响推理性能?实战解析原理、选型与问题排查

在AI推理优化这条路上&#xff0c;量化是我见过投入产出比最高的手段。很多人以为量化就是把模型从FP32变成INT8&#xff0c;体积缩小、推理变快&#xff0c;但实操后才发现&#xff0c;AI模型量化对推理性能的影响并不只有正向&#xff1a;有时速度反而下降&#xff0c;精度却…

2026/10/20 20:20:51 阅读更多 →
基于Simulink的23自由度分布式电驱动整车动力学模型搭建与仿真

基于Simulink的23自由度分布式电驱动整车动力学模型搭建与仿真

做分布式电驱动车辆的控制&#xff0c;最头疼的问题就是你手上的整车模型到底该建多细。我这次在Matlab Simulink里完整搭了一套23自由度整车动力学模型&#xff0c;把车身六个方向的运动、四个车轮的垂向跳动、车轮旋转、转向系统、以及分布式驱动链条的扭转自由度全部拉进来了…

2026/10/20 20:20:51 阅读更多 →
用JSON和Python命令行构建个人技能管理工具:从数据建模到实践

用JSON和Python命令行构建个人技能管理工具:从数据建模到实践

1. 为什么需要技能管理工具&#xff1a;需求拆解与设计取舍上周末想更新简历&#xff0c;结果发现我根本说不清“现在到底会什么”。十几项技能分散在旧简历、脑图、收藏夹和一摞笔记本里&#xff0c;有的早已过期&#xff0c;有的只停留在“看过教程”的阶段&#xff0c;还有的…

2026/10/20 20:20:51 阅读更多 →
企业微信回调验证与AES加解密:.NET开发者接入指南

企业微信回调验证与AES加解密:.NET开发者接入指南

接手过几个企业微信自建应用的项目&#xff0c;每次新人对接时几乎都会卡在同一个地方&#xff1a;管理后台保存“接收消息服务器”配置时提示URL验证失败&#xff0c;或者明明验证过了&#xff0c;消息却一直推送不进来。这个环节看着只是填几个参数&#xff0c;背后实际上是一…

2026/10/20 20:20:51 阅读更多 →
vLLM Prefix Caching 原理:如何用 Paged KV 消除重复计算

vLLM Prefix Caching 原理:如何用 Paged KV 消除重复计算

先说一个我遇到过的情况。某个线上推理服务&#xff0c;所有请求都带着同一段两千多字的 system prompt&#xff0c;并发一上来&#xff0c;GPU 利用率看着很高&#xff0c;但真正对用户有用的计算没多少——大部分算力在一遍遍重复计算同一段内容的 K 和 V。很长一段时间里&am…

2026/10/20 20:20:51 阅读更多 →
用Design.md构建符合产品风格的原型设计:设计令牌实战指南

用Design.md构建符合产品风格的原型设计:设计令牌实战指南

上周跟某团队聊原型评审&#xff0c;对方把三个页面的设计稿拍在我面前&#xff0c;主色蓝就出现了五种&#xff0c;没有两个颜色值相同。评审会开了一个小时&#xff0c;快一半时间在争论“这个蓝到底是不是我们品牌那个蓝”。原型阶段最让人心累的从来不是画得快不快&#xf…

2026/10/20 20:19:47 阅读更多 →

日新闻

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/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/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 阅读更多 →