声明:本文涉及到的行数皆指本文提供的附件imadjust.m的代码中行数 本文只讨论imadjust函数是一种用法,即 J = IMADJUST(I,[LOW_IN; HIGH_IN],[LOW_OUT; HIGH_OUT],GAMMA) 处理效果如下图 图像矩阵I要求数据类型uint8、uint16、double、single和int16,[LOW_IN HIGH_IN]和[LOW_OUT HIGH_OUT] 要求范围都要在[0 1]区间中,不然会出问题。
1.函数首先获得输入参数(行97) [img,imageType,lowIn,highIn,lowOut,highOut,gamma] = ... parseInputs(varargin{:}); 根据用法 J = IMADJUST(I,[LOW_IN; HIGH_IN],[LOW_OUT; HIGH_OUT],GAMMA) 其中I赋值给img,imgeType后续有说明,LOW_IN赋值给lowIn,HIGH_IN赋值给highIn,LOW_OUT赋值给lowOUt,HIGH_OUT赋值给highOut,GAMMA赋值给gamma。 进入子函数paraseInputs(行196) 函数会判断输出参数个数多少,本文主要讨论参数个数>1,从行231看起
View Code
这个if-else语句代码很明显看到函数输入参数[LOW_IN HIGH_IN]赋值给了lowhigh_in,参数[LOW_OUT HIGH_OUT]赋值给了lowhigh_out,而参数GAMMA赋值给了gamma,然后执行参数有效性判断。(行265) imageType = findImageType(img, lowhigh_in, lowhigh_out); checkRange(lowhigh_in, imageType, 2,'[LOW_IN; HIGH_IN]'); checkRange(lowhigh_out, imageType, 3,'[LOW_OUT; HIGH_OUT]'); 第一个语句主要用于根据输入图像矩阵判断图像类型,第二个和第三个主要是判断[LOW_IN HIGH_IN]和[LOW_OUT HIGH_OUT]的正确性。 (1)findImageType函数如下(行274)
View Code
图像类型分为三种,第一种是'truecolor'图像,第二种是'intensity',第三种为'indexed'。本文讨论的为第二种(一般情况使用的就是第二种,其他的目前没遇到,后续文章更新),即'intensity',判定第二种条件为[LOW_IN HIGH_IN]和[LOW_OUT HIGH_OUT]的元素个数为2并且输入图像矩阵列数不为3。 (2)chackRange函数如下(行300)
View Code
前面判定图像为'intensity',这里主要判断[LOW_IN HIGH_IN]和[LOW_OUT HIGH_OUT]元素个数必须为2,不然报错,这里就是第一个检查,后面还有检查。 最后 [low_in high_in] = splitRange(lowhigh_in, imageType); [low_out high_out] = splitRange(lowhigh_out, imageType); 获取参数[low_in high_in] 和 [low_out high_out] ,然后函数返回。
2.参数检查 前面通过函数paraseInputs获取了用户输入的参数,接下来进行参数有效性检验 validateLowHigh(lowIn,highIn,lowOut,highOut); gamma = validateGamma(gamma,imageType); (1)函数validateLowHigh(行340)
View Code
该函数首先检查了lowIn要小于highIn,但是没要求lowOut要小于highOut,因为这个函数有个运用,在于可以反转图像,即[0 1]变换到[1 0]。 然后使用函数isInvalidRange限制了输入lowIn、highIn、lowOut和highOut范围为[0 1],这就是开头所说[LOW_IN HIGH_IN]和[LOW_OUT HIGH_OUT] 要求范围都要在[0 1]区间中的出处。 (2)函数validateGamma(行362)
View Code
前面判定图像类型为'intensity',这里判定gamma参数必须为正数。
3.执行变换(行104)
View Code
首先判断如果图像矩阵数据不为浮点数(double和single)并且矩阵元素个数>65536,则执行函数adjustWithLUT函数。 (1)adjustWithLUT函数如下
View Code
关键部分 for p = 1:size(img,3)
lut = linspace(0,1,lutLength);
scalingFactor = 1;
lut = adjustArray(lut,lowIn(p),highIn(p),lowOut(p),highOut(p), ...
gamma(p),scalingFactor);
lut = conversionFcn(lut);
out(:,:,p) = intlut(img(:,:,p),lut);
end
首先创建一个数组作为筛选数组,不需要对图像矩阵进行变换,直接根据筛选数组的筛选图像矩阵。以下语句为灰度值归一化,将灰度归一化到[0 1]范围,这是为了后面变换方便。 lut = linspace(0,1,lutLength); lutLength的大小为图像矩阵数据类型对应该类型的最大值,例如图像矩阵数据类型为uint8,则lutLength=256。该语句作用在于创建一个数组lut,数组储存归一化后的灰度值,每个元素分别对于相应的灰度等级。 lut = adjustArray(lut,lowIn(p),highIn(p),lowOut(p),highOut(p), ... gamma(p),scalingFactor); 对lut进行变换,变换结果如开头的图 lowIn=低输入 highIn=高输入 lowOut=低输出 highOut=高输出 由于数组lut元素范围[0 1],这是归一化数据,因此要还原对应的值 lut = conversionFcn(lut); 剩下就是筛选了 out(:,:,p) = intlut(img(:,:,p),lut);
(2)adjustArray函数(行187) function out = adjustArray(img,lIn,hIn,lOut,hOut,g,d) %make sure img is in the range [lIn;hIn] img(:) = max(lIn(d,:), min(hIn(d,:),img)); out = ( (img - lIn(d,:)) ./ (hIn(d,:) - lIn(d,:)) ) .^ (g(d,:)); out(:) = out .* (hOut(d,:) - lOut(d,:)) + lOut(d,:); 首先筛选掉矩阵img中小于lIn的数的数值变为lIn,大于hIn的数的数值变为hIn,筛选语句如下 img(:) = max(lIn(d,:), min(hIn(d,:),img)); 接着进行变换,令 并且d=1,则该函数处理的效果等价于: 至于为什么这样,我手写推导过程如下 表达式就是曲线AB的方程
附件:imadjust.m代码
View Code
|
|