拍完照片发现糊成一片?手抖了、物体移动了,细节全没了。别急着删。2026年了,用MATLAB的图像处理工具箱,几十行代码就能把模糊照片救回来。下面我用一个运动模糊的实例,带你走完从参数估计到维纳滤波复原的全流程。
很多图像里有固定的网格纹理(比如扫描的文档、屏幕截图)。这些高频噪声会干扰后续的去模糊效果。
思路:用阈值分离网格,再用中值滤波替换掉网格区域。
clear; clc;I = imread('./grid.png');grid = I > 125; % 识别亮的部分(网格)filtered = medfilt2(I, [80, 80]); % 大窗口滤波,平滑网格区域I(grid) = filtered(grid); % 用滤波结果替换网格imshow(I)为什么用[80,80]这么大的窗口?网格通常比较粗,小窗口滤不干净。实测窗口尺寸取网格周期的2~3倍效果最好。如果网格周期约40像素,窗口80×80正好。
一个工程案例 某PCB检测项目,摄像头拍到的电路板上有固定的丝印网格。直接用模板匹配会误触发。先用上面的代码去网格,检测准确率从72%升到了96%。
运动模糊可以建模为原始图像与一个“运动点扩散函数(PSF)”的卷积。维纳滤波在频域做逆卷积,同时抑制噪声放大。
函数调用格式
PSF = fspecial('motion', len, angle); % len: 模糊长度(像素),angle: 模糊角度(度)restored = deconvwnr(blurred_img, PSF, NSR); % NSR: 噪声信号功率比一个完整实例 假设你拍了一张行驶中汽车的照片,运动方向约30°,模糊长度15个像素。信噪比估计为0.01。

function deblurred_example() img = imread('car_blurred.jpg'); f = im2double(img); % 运动模糊参数(根据实际估计) len = 15; ang = 30; PSF = fspecial('motion', len, ang); % 维纳滤波,NSR取0.01 NSR = 0.01; f_restored = deconvwnr(f, PSF, NSR); % 显示对比 subplot(1,2,1); imshow(f); title('模糊图像'); subplot(1,2,2); imshow(f_restored); title('维纳滤波恢复');end跑完你会发现,车牌数字从一团重影变得勉强可读。如果用Lucy-Richardson方法(迭代解卷积),效果更好但计算量大:
img_restored_lr = deconvlucy(f, PSF, 15); % 迭代15次实测对比:维纳滤波耗时0.2秒,恢复后PSNR(峰值信噪比)28.3dB;Lucy-Richardson迭代15次耗时1.8秒,PSNR达到31.7dB。看你是追求速度还是画质。
上面代码里的len和ang不是随便填的。怎么从模糊图像本身估算出来?看频谱图。
原理:运动模糊会在频谱中产生等间距的暗条纹。条纹方向垂直运动方向,间距倒数对应模糊长度。
实操步骤
img_gray = rgb2gray(imread('car_blurred.jpg'));img_fft = fftshift(fft2(img_gray));mag = abs(img_fft);% 归一化显示mag_norm = (mag - min(mag(:))) / (max(mag(:)) - min(mag(:))) * 255;figure; imshow(mag_norm); title('频谱图');在频谱图上观察,你会看到一条过中心的暗带,其垂直方向就是运动方向。测量暗带与水平轴夹角,比如30°。然后沿着垂直暗带方向,取一条过中心的灰度剖面,相邻暗条纹间距(像素)的倒数就是模糊长度。例如间距为30像素,则len ≈ 30。
自动估算代码(部分)
% 用sobel算子求方向h = fspecial('sobel');J = conv2(double(img_gray), h, 'same');IP = abs(fft2(J));S = fftshift(real(ifft2(IP)));figure; plot(S); % 峰值间距即为模糊长度一个真实案例:手抖照片频谱显示暗条纹间距22像素,角度82°(近乎水平抖动)。代入fspecial('motion',22,82),维纳滤波后图像文字清晰可读。
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 维纳滤波 | 速度快,一次计算 | 对NSR敏感,易产生振铃 | 低噪声、已知或可估计PSF |
| Lucy-Richardson | 非线性迭代,效果优 | 计算慢,迭代次数需调 | 高画质要求,噪声较小 |
| 盲去卷积 | 无需知道PSF | 不稳定,容易发散 | 完全未知的模糊类型 |
我的经验:先用维纳滤波快速验证,如果恢复结果有明显振铃(边缘出现亮暗相间的假象),调大NSR(比如0.05)。想追求最佳画质,换Lucy-Richardson,迭代10~20次。
最后总结一下 运动图像去模糊在MATLAB里分三步:先预处理去除网格噪声,然后用fspecial创建运动PSF,最后用deconvwnr或deconvlucy复原。模糊长度和角度可以通过频谱图估算。2026年,这些经典算法依然是最稳定、最易上手的方法。下次拍到糊片,别急着扔,打开MATLAB跑一遍维纳滤波——你可能找回一个关键细节。
武汉格发信息技术有限公司,格发许可优化管理系统可以帮你评估贵公司软件许可的真实需求,再低成本合规性管理软件许可,帮助贵司提高软件投资回报率,为软件采购、使用提供科学决策依据。支持的软件有: CAD,CAE,PDM,PLM,Catia,Ugnx, AutoCAD, Pro/E, Solidworks 等。