一种快速灰度校正算法(处理亮度不均等情况)(含MATLAB代码)


前言

方法来源:[1]高建贞,任明武,杨静宇.一种快速实用的灰度校正算法[J].中国图象图形学报,2002(06):30-34.
MATLAB代码:经MATLAB R2019a实现。
程序小白,代码有不合理的地方望指正。


一、MATLAB代码

MATLAB代码如下:

clc;clear;close all
im=imread('企鹅.jpg');
im= rgb2gray(im);
figure
imshow(im)          %企鹅灰度图像

[m,n]=size(im);     %原图的尺寸
blocksize=8;        %分块大小,此处块为正方形,方便后面差值运算
%分块处理
blocknum1 =floor(m/blocksize);    %分块数量(对应图像长度,即m),取整后,原图会剩下几个像素的长或宽未做处理
blocknum2 =floor(n/blocksize);    %分块数量(对应图像宽度,即n)
length =blocknum1*blocksize;   %处理的长度像素数
height =blocknum2*blocksize;   %处理的宽度像素数
A=zeros(blocknum1,blocknum2) ;
ff = im(1:length,1:height);     %生成一个用来原图副本(去除多余像素的)
%开始分块处理
for k = 1:blocknum2
    for h = 1:blocknum1
    
        %生成模板
        block = zeros(size(ff));    %将模板初始化为0
        lini = 1 + blocksize * (h - 1);
        hini = 1 + blocksize * (k - 1);     %分块的第一个像素在原图中的坐标
        x = lini:(lini + blocksize - 1);
        y = hini:(hini + blocksize - 1);    %生成分块长、宽坐标序列
        block(x, y) = 1;                     %将模板上需要进行分块的部分转换成1,用来提取该分块
        
        %提取分块
        ff = im2double(ff);     %原图转换为double类型,保证和模板black同类型以做点乘
        block = block .* ff;    %将原图投影在模板上
        block = block(x, y);    %提取分块
        %%%%%%%%%%%%%%%%对块进行处理%%%%%%%%%%%%%%%%%%%%%%%
        a=blocksize * blocksize;   %块的像素总数
        B=reshape(block,[1,a]);    %将块的矩阵中的数重新排列为一行a列的一维矩阵
        C=sort(B,'ascend');        %对矩阵B进行升序排列,即从小到大排列
        b=floor(a/4);              %b为一维矩阵1/4处的长度
        D=C(1,b:a) ;               %D为一维矩阵后3/4的部分
        A(h,k)=mean(D);            %A(h,k)为D的平均值,A为背景模板矩阵
    end
end
 A=im2uint8(A);
 A=imblizoom(A,blocksize);    %对A进行差值放大,放大后的矩阵与ff一样,此时为图像背景矩阵
 I0=im2double(A);             %I0为背景矩阵
 I1=im2double(im);            %原图矩阵变为double类型
 c=0.7;          %系数可调
 I=zeros(length,height);                %定义I,提高运算速度
 for i=1:length
     for j=1:height
         I(i,j)=I1(i,j)*c/I0(i,j);   %灰度校正公式
     end
 end
im1=im2uint8(I);  %结果是去掉多余像素的,可以加回来,但多余像素未作处理
figure
imshow(im1)
imwrite(im1,'0.7.jpg')

其中块的大小blocksize以及系数c可调。


子函数:imblizoom

function [ ZI ] = imblizoom( I,zmf )
%----------------------双线性插值法缩放矩阵或图像---------------------------
%       I:图像文件名或矩阵(整数值(0~255))
%       zmf:缩放因子,即缩放的倍数
%       缩放后的图像矩阵 ZI


if ~exist('I','var') || isempty(I)
    error('输入图像 I未定义或为空!');
end
if ~exist('zmf','var') || isempty(zmf) || numel(zmf) ~= 1
     error('位移矢量 zmf未定义或为空或 zmf中的元素超过2!');
end
if isstr(I)
    [I,M] = imread(I);
end
if zmf <= 0
     error('缩放倍数 zmf的值应该大于0!');
end


[IH,IW,ID] = size(I);
ZIH = round(IH*zmf); 
ZIW = round(IW*zmf); 
ZI = zeros(ZIH,ZIW,ID); 



IT = zeros(IH+2,IW+2,ID);
IT(2:IH+1,2:IW+1,:) = I;
IT(1,2:IW+1,:)=I(1,:,:);IT(IH+2,2:IW+1,:)=I(IH,:,:);
IT(2:IH+1,1,:)=I(:,1,:);IT(2:IH+1,IW+2,:)=I(:,IW,:);
IT(1,1,:) = I(1,1,:);IT(1,IW+2,:) = I(1,IW,:);
IT(IH+2,1,:) = I(IH,1,:);IT(IH+2,IW+2,:) = I(IH,IW,:);



for zj = 1:ZIW         
    for zi = 1:ZIH
        ii = (zi-1)/zmf; jj = (zj-1)/zmf;
        i = floor(ii); j = floor(jj); 
        u = ii - i; v = jj - j;
        i = i + 1; j = j + 1;
        ZI(zi,zj,:) = (1-u)*(1-v)*IT(i,j,:) +(1-u)*v*IT(i,j+1,:) + u*(1-v)*IT(i+1,j,:) +u*v*IT(i+1,j+1,:);
    end
end
ZI = uint8(ZI);
end  

二、结果示例

在这里插入图片描述


总结

方法来源:[1]高建贞,任明武,杨静宇.一种快速实用的灰度校正算法[J].中国图象图形学报,2002(06):30-34.

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

‭刘燚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值