基于块匹配的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. 无人机航拍:抑制飞行器姿态变化导致的画面晃动
相关推荐
Charlie_lll9 分钟前
力扣解题-移动零
后端·算法·leetcode
chaser&upper9 分钟前
矩阵革命:在 AtomGit 解码 CANN ops-nn 如何构建 AIGC 的“线性基石”
程序人生·算法
weixin_4997715518 分钟前
C++中的组合模式
开发语言·c++·算法
美狐美颜SDK开放平台31 分钟前
多终端适配下的人脸美型方案:美颜SDK工程开发实践分享
人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
iAkuya1 小时前
(leetcode)力扣100 62N皇后问题 (普通回溯(使用set存储),位运算回溯)
算法·leetcode·职场和发展
近津薪荼1 小时前
dfs专题5——(二叉搜索树中第 K 小的元素)
c++·学习·算法·深度优先
xiaoye-duck1 小时前
吃透 C++ STL list:从基础使用到特性对比,解锁链表容器高效用法
c++·算法·stl
松☆1 小时前
CANN与大模型推理:在边缘端高效运行7B参数语言模型的实践指南
人工智能·算法·语言模型
java干货1 小时前
为什么 “File 10“ 排在 “File 2“ 前面?解决文件名排序的终极算法:自然排序
开发语言·python·算法
皮皮哎哟1 小时前
数据结构:嵌入式常用排序与查找算法精讲
数据结构·算法·排序算法·二分查找·快速排序