分享

imadjust函数分析一

 爱吃西红柿的婕 2017-07-30

声明:本文涉及到的行数皆指本文提供的附件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

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多