基于块匹配的MATLAB视频去抖动算法

一、核心代码

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. 运动估计加速
  • 金字塔搜索:采用图像金字塔减少搜索范围

    matlab 复制代码
    function 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计算:使用积分图像加速块匹配

    matlab 复制代码
    function 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. 抖动滤波改进
  • 自适应滤波窗口:根据运动幅度动态调整窗口大小

    matlab 复制代码
    function winSize = adaptive_window(motionMag)
        meanMag = mean(motionMag(:));
        if meanMag < 2
            winSize = 3;
        elseif meanMag < 5
            winSize = 5;
        else
            winSize = 7;
        end
    end
  • 运动轨迹平滑:采用卡尔曼滤波优化运动估计

    matlab 复制代码
    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/contentcsi/65174.html

三、典型应用场景

  1. 手持设备拍摄:消除步行拍摄的抖动(PSNR提升4-6dB)
  2. 车载摄像头:补偿车辆行驶中的高频振动
  3. 无人机航拍:抑制飞行器姿态变化导致的画面晃动
相关推荐
十重幻想3 小时前
PTA6-1 使用函数求最大公约数(C)
c语言·数据结构·算法
大千AI助手4 小时前
蛙跳积分法:分子动力学模拟中的高效数值积分技术
算法·积分·数值积分·蛙跳积分法·牛顿力学系统·verlet积分算法
zycoder.4 小时前
力扣面试经典150题day3第五题(lc69),第六题(lc189)
算法·leetcode·面试
王严培.5 小时前
7.MATLAB疑难问题诊疗的技术
开发语言·matlab·信息可视化
bubiyoushang8886 小时前
MATLAB实现直流电法和大地电磁法的一维正演计算
前端·javascript·matlab
西阳未落6 小时前
LeetCode——双指针
c++·算法
胖咕噜的稞达鸭6 小时前
C++中的父继子承:继承方式实现栈及同名隐藏和函数重载的本质区别, 派生类的4个默认成员函数
java·c语言·开发语言·数据结构·c++·redis·算法
笑口常开xpr6 小时前
【C++】模板 - - - 泛型编程的魔法模具,一键生成各类代码
开发语言·数据结构·c++·算法
IT小番茄7 小时前
Kubernetes云平台管理实战:自动加载到负载均衡(七)
算法