一、核心代码
1. 视频读取与预处理
%% 视频参数设置
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. 块匹配运动估计
function motionVectors = block_matching(prevFrame, currFrame)[H, W] = size(prevFrame);numBlocksY = H/blockSize;numBlocksX = W/blockSize;motionVectors = zeros(numBlocksY, numBlocksX, 2);for i = 1:numBlocksYfor 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 = yRangefor n = xRangetargetBlock = currFrame( (m-1)*blockSize+1 : m*blockSize, ...(n-1)*blockSize+1 : n*blockSize );cost = sum(sum(abs(refBlock - targetBlock)));if cost < minCostminCost = cost;bestOffset = [m-i, n-j];endendendmotionVectors(i,j,:) = bestOffset;endend
end
3. 抖动识别与滤波
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)-2for 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);endend
end
4. 运动补偿与视频生成
%% 视频处理循环
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:Hfor 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);endend% 写入输出视频step(writer, stabilized);% 更新参考帧prevGray = currGray;
endclose(writer);
二、优化
1. 运动估计加速
- 
金字塔搜索:采用图像金字塔减少搜索范围 function pyr = build_pyramid(img, levels)pyr = cell(levels,1);pyr{1} = img;for l=2:levelspyr{l} = imresize(pyr{l-1}, 0.5);end end
- 
快速SAD计算:使用积分图像加速块匹配 function cost = fast_sad(ref, target)[H,W] = size(ref);integral = cumsum(cumsum(target));for i=1:Hfor j=1:Wx1 = 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))));endend end
2. 抖动滤波改进
- 
自适应滤波窗口:根据运动幅度动态调整窗口大小 function winSize = adaptive_window(motionMag)meanMag = mean(motionMag(:));if meanMag < 2winSize = 3;elseif meanMag < 5winSize = 5;elsewinSize = 7;end end
- 
运动轨迹平滑:采用卡尔曼滤波优化运动估计 function [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/contentcnk/65174.html
三、典型应用场景
- 手持设备拍摄:消除步行拍摄的抖动(PSNR提升4-6dB)
- 车载摄像头:补偿车辆行驶中的高频振动
- 无人机航拍:抑制飞行器姿态变化导致的画面晃动