基于GBTF算法的MATLAB代码

基于GBTF(Gradient-Based Threshold-Free)算法的MATLAB代码,用于将Bayer格式的单通道图像转换为RGB全彩图像。该算法通过梯度加权插值减少伪色效应,适用于高动态范围场景。

GBTF算法MATLAB实现

function rgbImg = demosaic_gbtf(bayerImg, pattern)
    % 输入参数:
    % bayerImg: 输入的Bayer格式单通道图像 (灰度图, 大小为HxW)
    % pattern: Bayer排列模式 (如 'RGGB' 或 'BGGR')
    % 输出参数:
    % rgbImg: 输出的RGB图像 (HxWx3)

    % 初始化参数
    [H, W] = size(bayerImg);
    rgbImg = zeros(H, W, 3, class(bayerImg));
    
    % 根据Bayer模式分配初始通道
    switch lower(pattern)
        case 'rggb'
            R = bayerImg(1:2:end, 1:2:end);    % 奇行奇列
            Gr = bayerImg(1:2:end, 2:2:end);   % 奇行偶列
            Gb = bayerImg(2:2:end, 1:2:end);   % 偶行奇列
            B = bayerImg(2:2:end, 2:2:end);    % 偶行偶列
        case 'bggr'
            B = bayerImg(1:2:end, 1:2:end);
            Gr = bayerImg(1:2:end, 2:2:end);
            Gb = bayerImg(2:2:end, 1:2:end);
            R = bayerImg(2:2:end, 2:2:end);
        otherwise
            error('Unsupported Bayer pattern');
    end
    
    % 插值Green分量 (核心步骤)
    G = interp_green_gbtf(R, Gr, Gb, B);
    
    % 插值R/B分量在G位置
    R_gb = interp_R_Gb_gbtf(Gr, Gb, G);
    B_gr = interp_B_Gr_gbtf(Gr, Gb, G);
    
    % 插值剩余颜色分量
    R = interp_remaining_R_gbtf(R, R_gb, G);
    B = interp_remaining_B_gr_tf(B, B_gr, G);
    
    % 合并通道
    rgbImg(:,:,1) = R;  % Red
    rgbImg(:,:,2) = G;  % Green
    rgbImg(:,:,3) = B;  % Blue
end

%% Green分量插值函数 (5x5窗口)
function G = interp_green_gbtf(R, Gr, Gb, B)
    [H, W] = size(R);
    G = zeros(H, W);
    
    % 边界填充 (镜像填充)
    padded_R = padarray(R, [2 2], 'symmetric', 'both');
    padded_Gr = padarray(Gr, [2 2], 'symmetric', 'both');
    padded_Gb = padarray(Gb, [2 2], 'symmetric', 'both');
    padded_B = padarray(B, [2 2], 'symmetric', 'both');
    
    for i = 3:H+2
        for j = 3:W+2
            % 当前点为R或B时插值G
            if mod(i-2, 2) == 1 && mod(j-2, 2) == 0  % R位置
                center = padded_R(i, j);
                % 计算梯度
                dx = [padded_Gr(i, j+1) - padded_Gr(i, j-1), ...
                      padded_Gb(i, j+1) - padded_Gb(i, j-1)];
                dy = [padded_Gr(i+1, j) - padded_Gr(i-1, j), ...
                      padded_Gb(i+1, j) - padded_Gb(i-1, j)];
                grad = sqrt(dx.^2 + dy.^2);
                
                % 权重计算
                weight = 1 ./ (grad + eps);
                weight = weight / sum(weight);
                
                % 插值G
                G(i-2, j-2) = center + 0.5 * sum(grad .* (padded_Gr(i, j+1) + padded_Gr(i, j-1) - 2*padded_Gr(i, j)));
            elseif mod(i-2, 2) == 0 && mod(j-2, 2) == 1  % B位置
                center = padded_B(i, j);
                % 类似R位置的插值逻辑
                dx = [padded_Gr(i, j+1) - padded_Gr(i, j-1), ...
                      padded_Gb(i, j+1) - padded_Gb(i, j-1)];
                dy = [padded_Gr(i+1, j) - padded_Gr(i-1, j), ...
                      padded_Gb(i+1, j) - padded_Gb(i-1, j)];
                grad = sqrt(dx.^2 + dy.^2);
                weight = 1 ./ (grad + eps);
                weight = weight / sum(weight);
                G(i-2, j-2) = center + 0.5 * sum(grad .* (padded_Gr(i, j+1) + padded_Gr(i, j-1) - 2*padded_Gr(i, j)));
            else
                G(i-2, j-2) = padded_Gr(i, j);  % Gr或Gb位置直接赋值
            end
        end
    end
end

%% R/B位置插值剩余颜色分量 (3x3窗口)
function R_out = interp_remaining_R_gbtf(R, R_gb, G)
    [H, W] = size(R);
    R_out = zeros(H, W);
    padded_R = padarray(R, [1 1], 'replicate', 'both');
    padded_R_gb = padarray(R_gb, [1 1], 'replicate', 'both');
    padded_G = padarray(G, [1 1], 'replicate', 'both');
    
    for i = 2:H+1
        for j = 2:W+1
            if mod(i, 2) == 1 && mod(j, 2) == 0  % Gr位置插值B
                center_G = padded_G(i, j);
                delta_R = (padded_R_gb(i, j+1) - padded_R_gb(i, j-1)) / 2;
                delta_B = (padded_R_gb(i+1, j) - padded_R_gb(i-1, j)) / 2;
                R_out(i-1, j-1) = center_G + delta_R + delta_B;
            elseif mod(i, 2) == 0 && mod(j, 2) == 1  % Gb位置插值R
                center_G = padded_G(i, j);
                delta_R = (padded_R_gb(i+1, j) - padded_R_gb(i-1, j)) / 2;
                delta_B = (padded_R_gb(i, j+1) - padded_R_gb(i, j-1)) / 2;
                R_out(i-1, j-1) = center_G + delta_R + delta_B;
            else
                R_out(i-1, j-1) = padded_R(i, j);  % R或B位置直接赋值
            end
        end
    end
end

算法说明

  1. Green分量插值
    • 5x5窗口梯度计算:通过计算水平(Gr/Gb)和垂直(R/B)方向的梯度,动态调整插值权重,减少边缘伪影。
    • 权重分配:梯度越大(边缘区域),权重越小,抑制噪声;梯度越小(平滑区域),权重越大,保持细节。
  2. R/B分量插值
    • 3x3窗口双线性插值:利用周围色差信息,结合已插值的Green分量,恢复缺失的R/B值。
  3. 边界处理
    • 采用镜像填充(symmetric模式)避免边缘效应,确保插值窗口完整性。

使用示例

% 读取Bayer格式RAW数据 (假设为RGGB排列)
rawData = load('bayer_data.mat');  % 包含变量bayerPattern (HxW)
pattern = 'RGGB';

% 执行GBTF Demosaic
rgbImage = demosaic_gbtf(rawData.bayerPattern, pattern);

% 显示结果
imshow(rgbImage);
imwrite(rgbImage, 'output_rgb.png');

优化建议

  1. 硬件加速:对循环部分使用MATLAB的parfor并行计算或转换为C-MEX代码提升速度。
  2. 动态范围扩展:对RAW数据进行去马赛克前,先进行黑电平校正和白平衡预处理。
  3. 色彩校正:添加3A算法(自动曝光、自动对焦、自动白平衡)提升色彩准确性。

参考

  • CSDN博客《ISP图像处理之Demosaic算法》 blog.csdn.net/EyRe1/article/details/133668975
  • 代码 用于Demosaic的方法,GBTF的matlab实现 www.youwenfan.com/contentcno/78846.html
  • CSDN博客《Demosaic GBTF算法思想和原理》
posted @ 2025-12-24 17:36  csoe9999  阅读(1)  评论(0)    收藏  举报