[计算机视觉] 基于双线性插值的直方图均衡化算法Matlab源码

main.m

clear;
clc;
rgb = imread('girl.jpg');
gray = rgb2gray(rgb);
new_gray = gray;
figure(1);
subplot(1,2,1);
imshow(gray);
title('原图');

% 划分4*4的网格,分别计算cdf
[m, n] = size(gray);
cdf = zeros(16, 256);
for i=1:4
    for j=1:4
        cdf((i - 1) * 4 + j,:) = compute_cdf(gray((i - 1) * m / 4 + 1 : i * m / 4, (j - 1) * n / 4 + 1 : j * n / 4));
    end
end

% 逐个像素点进行转换
for i=1:m
    for j=1:n
       % 处理四个角落
       if ((i <= m / 8 || i >= m - m / 8) && (j <= n / 8 || j >= n - n / 8))
           gray_scale_value = gray(i, j) + 1;
           which_block = (ceil(i / m * 4) - 1) * 4 + ceil(j / m * 4 );
           new_gray(i, j) = round(256 * cdf(which_block,gray_scale_value));
       end
       % 使用单线性插值 处理上下两条边
       if ((i <= m / 8 && j > n / 8 && j < n - n / 8) || (i >= m - m / 8 && j > n / 8 && j < n - n / 8))
           gray_scale_value = gray(i, j) + 1;
           block_1 = (ceil(i / m * 4) - 1) * 4 + ceil((j - n / 8) / n * 4 );
           block_2 = block_1 + 1;
           block_1_abs = j - ((ceil((j - m / 8) / m * 4 ) - 1) * n / 4 + n / 8);
           block_2_abs = ceil((j - m / 8) / m * 4 ) * n / 4 + n / 8 - j;
           new_gray(i, j) = round(256 * (cdf(block_1,gray_scale_value) * block_2_abs / n * 4 + cdf(block_2,gray_scale_value) * block_1_abs / n * 4));
       end
       % 使用单线性插值 处理左右两条边
       if ((j <= n / 8 && i > m / 8 && i < m - m / 8) || (j >= n - n / 8 && i > m / 8 && i < m - m / 8))
           gray_scale_value = gray(i, j) + 1;
           block_1 = (ceil((i - m / 8) / m * 4) - 1) * 4 + ceil(j / n * 4 );
           block_2 = block_1 + 4;
           block_1_abs = i - ((ceil((i - m / 8) / m * 4) - 1) * m / 4 + m / 8);
           block_2_abs = ceil((i - m / 8) / m * 4) * m / 4 + m / 8 - i;
           new_gray(i, j) = round(256 * (cdf(block_1,gray_scale_value) * block_2_abs / m * 4 + cdf(block_2,gray_scale_value) * block_1_abs / m * 4));
       end
       % 处理中间一块
       if (i > m / 8 && i < m - m / 8 && j > n / 8 && j < n - n / 8)
           gray_scale_value = gray(i, j) + 1;
           % 目标像素在哪一个(中间一块新的3*3)
           block_row = ceil((i - m / 8) / m * 4);
           block_col = ceil((j - n / 8) / n * 4);
           % 四个中心点的值
           lt_value = cdf((block_row - 1) * 4 + block_col, gray_scale_value);
           rt_value = cdf((block_row - 1) * 4 + block_col + 1, gray_scale_value);
           lb_value = cdf(block_row * 4 + block_col, gray_scale_value);
           rb_value = cdf(block_row * 4 + block_col + 1, gray_scale_value);
           % 四个中心点坐标
           lt_row = m / 8 + (block_row - 1) * m / 4;
           lt_col = n / 8 + (block_col - 1) * n / 4;
           rt_row = lt_row;
           rt_col = lt_col + n / 4;
           lb_row = lt_row + m / 4;
           lb_col = lt_col;
           rb_row = lt_row + m / 4;
           rb_col = lt_col + n / 4;
           % 左右插值
           top_linear = ((j - lt_col) / n * 4) * rt_value + ((rt_col - j) / n * 4) * lt_value;
           bottom_linear = ((j - lb_col) / n * 4) * rb_value + ((rb_col - j) / n * 4) * lb_value;
           % 上下插值
           new_gray_value = ((i - lt_row) / m * 4) * bottom_linear + ((lb_row - i) / m * 4) * top_linear;
           new_gray(i, j) = round(256 * new_gray_value);
       end
    end
end
subplot(1,2,2);
% p = new_gray./gray;
imshow(new_gray);
title('双线性差值');
    

compute_cdf.m

% cdf
function cdf = compute_cdf(local_gray)
    cdf = zeros(1,256);
    for i=0:255
        cdf(1,i+1) = sum(local_gray(:)==i);
    end
    cdf = cumsum(cdf) / numel(local_gray);
end

实验图像

在这里插入图片描述

效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_40996518/article/details/106957596
今日推荐