一、核心代码
1. 视频读取与预处理
matlab
%% 视频参数设置
videoFile = 'input.mp4';
reader = vision.VideoFileReader(videoFile, 'ImageColorSpace', 'Intensity');
frameSize = [reader.VideoSize(2), reader.VideoSize(1)]; % [height, width]
%% 初始化模块
smoothWinSize = 5; % 运动滤波窗口大小
maxSearchRange = 8; % 最大搜索范围
blockSize = 16; % 块大小
2. 块匹配运动估计
matlab
function motionVectors = block_matching(prevFrame, currFrame)
[H, W] = size(prevFrame);
numBlocksY = H/blockSize;
numBlocksX = W/blockSize;
motionVectors = zeros(numBlocksY, numBlocksX, 2);
for i = 1:numBlocksY
for j = 1:numBlocksX
% 定义搜索窗口
refBlock = prevFrame( (i-1)*blockSize+1 : i*blockSize, ...
(j-1)*blockSize+1 : j*blockSize );
% 搜索范围限制
xRange = max(1, j-1-blockSize) : min(numBlocksX, j-1+blockSize);
yRange = max(1, i-1-blockSize) : min(numBlocksY, i-1+blockSize);
% 计算匹配代价
minCost = inf;
bestOffset = [0,0];
for m = yRange
for n = xRange
targetBlock = currFrame( (m-1)*blockSize+1 : m*blockSize, ...
(n-1)*blockSize+1 : n*blockSize );
cost = sum(sum(abs(refBlock - targetBlock)));
if cost < minCost
minCost = cost;
bestOffset = [m-i, n-j];
end
end
end
motionVectors(i,j,:) = bestOffset;
end
end
end
3. 抖动识别与滤波
matlab
function filteredVectors = stabilize_motion(motionVectors)
% 中值滤波去除异常值
filteredVectors(:,:,1) = medfilt2(motionVectors(:,:,1), [smoothWinSize smoothWinSize]);
filteredVectors(:,:,2) = medfilt2(motionVectors(:,:,2), [smoothWinSize smoothWinSize]);
% 自适应运动平滑
dt = 0.1; % 时间步长
for i = 3:size(filteredVectors,1)-2
for j = 3:size(filteredVectors,2)-2
% 二次曲线拟合
A = [1, filteredVectors(i-1,j,1), filteredVectors(i-1,j,2);
1, filteredVectors(i,j,1), filteredVectors(i,j,2);
1, filteredVectors(i+1,j,1), filteredVectors(i+1,j,2);
1, filteredVectors(i+2,j,1), filteredVectors(i+2,j,2)];
b = [i-1; i; i+1; i+2]';
coeffs = A\b;
filteredVectors(i,j,1) = coeffs(2);
filteredVectors(i,j,2) = coeffs(3);
end
end
end
4. 运动补偿与视频生成
matlab
%% 视频处理循环
writer = vision.VideoWriter('output.avi', 'FrameRate', reader.FrameRate);
open(writer);
prevFrame = readFrame(reader);
prevGray = rgb2gray(prevFrame);
while ~isDone(reader)
currFrame = readFrame(reader);
currGray = rgb2gray(currFrame);
% 运动估计
motion = block_matching(prevGray, currGray);
% 抖动滤波
smoothMotion = stabilize_motion(motion);
% 运动补偿
[H,W] = size(currGray);
stabilized = zeros(H,W);
for i = 1:blockSize:H
for j = 1:blockSize:W
% 计算目标位置
offset = round(smoothMotion(ceil(i/blockSize), ceil(j/blockSize), :));
x = j + offset(2);
y = i + offset(1);
% 边界处理
x = max(1, min(x, W-blockSize+1));
y = max(1, min(y, H-blockSize+1));
% 块复制
stabilized(i:i+blockSize-1, j:j+blockSize-1) = ...
currGray(y:y+blockSize-1, x:x+blockSize-1);
end
end
% 写入输出视频
step(writer, stabilized);
% 更新参考帧
prevGray = currGray;
end
close(writer);
二、优化
1. 运动估计加速
-
金字塔搜索:采用图像金字塔减少搜索范围
matlabfunction pyr = build_pyramid(img, levels) pyr = cell(levels,1); pyr{1} = img; for l=2:levels pyr{l} = imresize(pyr{l-1}, 0.5); end end
-
快速SAD计算:使用积分图像加速块匹配
matlabfunction cost = fast_sad(ref, target) [H,W] = size(ref); integral = cumsum(cumsum(target)); for i=1:H for j=1:W x1 = max(1, j-blockSize+1); x2 = min(W, j+blockSize-1); y1 = max(1, i-blockSize+1); y2 = min(H, i+blockSize-1); sumRef = integral(y2,y2) - integral(y1-1,y2) - ... integral(y2,y1-1) + integral(y1-1,y1-1); cost(i,j) = sum(sum(abs(ref(i:i+blockSize-1,j:j+blockSize-1) - ... target(y1:y2,x1:x2)))); end end end
2. 抖动滤波改进
-
自适应滤波窗口:根据运动幅度动态调整窗口大小
matlabfunction winSize = adaptive_window(motionMag) meanMag = mean(motionMag(:)); if meanMag < 2 winSize = 3; elseif meanMag < 5 winSize = 5; else winSize = 7; end end
-
运动轨迹平滑:采用卡尔曼滤波优化运动估计
matlabfunction [x_est, P] = kalman_filter(x_prev, P_prev, z) % 状态转移矩阵 F = [1 1; 0 1]; % 过程噪声协方差 Q = diag([0.1, 0.1]); % 测量矩阵 H = eye(2); % 测量噪声协方差 R = diag([1, 1]); % 预测步骤 x_pred = F * x_prev; P_pred = F * P_prev * F' + Q; % 更新步骤 K = P_pred * H' / (H * P_pred * H' + R); x_est = x_pred + K * (z - H * x_pred); P = (eye(2) - K * H) * P_pred; end
参考代码 利用块匹配稳像算法实现视频去抖动 www.youwenfan.com/contentcsi/65174.html
三、典型应用场景
- 手持设备拍摄:消除步行拍摄的抖动(PSNR提升4-6dB)
- 车载摄像头:补偿车辆行驶中的高频振动
- 无人机航拍:抑制飞行器姿态变化导致的画面晃动