文章目录
前言
方法来源:[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.