Matlab 通过对数函数进行量化

Matlab 通过对数函数进行量化,matlab,image-processing,Matlab,Image Processing,所以我一直在想为什么我的对数量化方法不起作用。C1是原始图像,我只是将它们分成三个波段,然后尝试量化: OredChannel = uint8(double(C1(:,:,1))); OgreenChannel = uint8(double(C1(:,:,2))); OblueChannel = uint8(double(C1(:,:,3))); MaxR = 1/max(double(OredChannel(:))); NatImgR = uint8(MaxR * log(double(O

所以我一直在想为什么我的对数量化方法不起作用。C1是原始图像,我只是将它们分成三个波段,然后尝试量化:

OredChannel  = uint8(double(C1(:,:,1)));
OgreenChannel = uint8(double(C1(:,:,2)));
OblueChannel = uint8(double(C1(:,:,3)));

MaxR = 1/max(double(OredChannel(:)));
NatImgR = uint8(MaxR * log(double(OredChannel)));
MaxG = 1/max(double(OgreenChannel(:)));
NatImgG = uint8(MaxG *log(double(OgreenChannel)));
MaxB = 1/max(double(OblueChannel(:)));
NatImgB = uint8(MaxB * log(double(OblueChannel)));
CLog = cat(3,NatImgR,NatImgG,NatImgB);
imshow(CLog);
title('Part F: Natural Logarithm');

不过,我似乎只有一个黑屏。我试着在所有的乐队上加上1和1/3,但似乎没有解决这个问题

我将只关注一个频道的代码:

MaxR = 1/max(double(OredChannel(:)));
NatImgR = uint8(MaxR * log(double(OredChannel)));
MaxR
的定义使得
MaxR*double(或数据通道)
最多为1。将此值转换为
uint8
将为您提供一个图像,其中大部分为0,输入最大的为1。将
log
添加到混合中可以使结果得到更小的值,将其转换为
uint8
可以保证得到0

对于对数量化(使用自然对数,正如您所希望的那样),您可以执行以下操作:

NatImgR = exp(floor(log(double(OredChannel))));
floor
返回一个介于0和5之间的整数值(假设输入值在[0255]范围内),如果输入值为0,则返回
-Inf
。为了将其恢复到原始输入范围,我应用了
exp
,这当然与
log
相反。这将导致以下7个可能的输出值(假设输入值为整数):

如果愿意,您可以将其转换为
uint8
;这将对值进行四舍五入,得到可能的值
[0,1,3,7,20,55148]

要更改量化级别的数量,请缩放输入。如果最大值低于
exp(n-1)
,则将具有
n
量化级别:

n = 5;
scale = exp(n-1) / (max(double(OredChannel(:)))+1);
NatImgR = exp(floor(log(round(scale*double(OredChannel)))));
需要注意的几点:

  • scale
    使用
    max()+1
    计算。+1是为了确保输入值低于exp(n-1),永远不相等(因为这将引入一个更高的量化级别)

  • 我在缩放之后和取对数之前使用
    舍入
    。这是为了避免量化级别介于0和1之间:缩放可以在0和1之间引入非整数值,从而导致该范围内可能存在许多量化级别


我将重点介绍一个频道的代码:

MaxR = 1/max(double(OredChannel(:)));
NatImgR = uint8(MaxR * log(double(OredChannel)));
MaxR
的定义使得
MaxR*double(或数据通道)
最多为1。将此值转换为
uint8
将为您提供一个图像,其中大部分为0,输入最大的为1。将
log
添加到混合中可以使结果得到更小的值,将其转换为
uint8
可以保证得到0

对于对数量化(使用自然对数,正如您所希望的那样),您可以执行以下操作:

NatImgR = exp(floor(log(double(OredChannel))));
floor
返回一个介于0和5之间的整数值(假设输入值在[0255]范围内),如果输入值为0,则返回
-Inf
。为了将其恢复到原始输入范围,我应用了
exp
,这当然与
log
相反。这将导致以下7个可能的输出值(假设输入值为整数):

如果愿意,您可以将其转换为
uint8
;这将对值进行四舍五入,得到可能的值
[0,1,3,7,20,55148]

要更改量化级别的数量,请缩放输入。如果最大值低于
exp(n-1)
,则将具有
n
量化级别:

n = 5;
scale = exp(n-1) / (max(double(OredChannel(:)))+1);
NatImgR = exp(floor(log(round(scale*double(OredChannel)))));
需要注意的几点:

  • scale
    使用
    max()+1
    计算。+1是为了确保输入值低于exp(n-1),永远不相等(因为这将引入一个更高的量化级别)

  • 我在缩放之后和取对数之前使用
    舍入
    。这是为了避免量化级别介于0和1之间:缩放可以在0和1之间引入非整数值,从而导致该范围内可能存在许多量化级别


想想你在做什么:从0-255范围内的数字开始,取对数,使其变小,然后乘以一个小值,保证结果小于1。然后将其转换为整数。你预计会发生什么?啊。这就解释了。试图找出正确的常数,使对数进入正确的范围。我原以为那个常数应该是正确的。尝试了255/Max,我不相信这是正确的常数,是吗?想想你在做什么:你从一个0-255范围内的数字开始,取对数,使它变小,然后乘以一个小值,保证结果小于1。然后将其转换为整数。你预计会发生什么?啊。这就解释了。试图找出正确的常数,使对数进入正确的范围。我原以为那个常数应该是正确的。尝试了255/Max,我不相信这是正确的常数,是吗?嗯,我在这里尝试了量化:NatImgR=exp(floor(log(double(OredChannel));然后,当我把这三个波段放在一起时,除了一张空白的图形,而不是一张图片,我似乎什么也得不到。这个操作的结果是一个双数组
imshow
假定这些值在[0,1]范围内,并将剪裁更高的值。在显示之前,您需要缩放输出或将其转换为
uint8
。我这样做了,但它仍然会发生:NatImgR=uint8(exp(floor(log)(double(oredcchannel '));NatImgG=uint8(exp(地板)(对数)(双通道(OgreenChannel)'));NatImgB=uint8(exp(地板)(对数)(双通道););Clog1=cat(3,NatImgR,NatImgG,NatImgB);imshow(Clog1);11=数字;标题(“F部分:自然对数”);然后是输入值的问题。对于
OredChannel=0:255
,这将产生预期输出。如果你的输入值在[0,1]范围内,它将不起作用。嗯,我只是想找出正确的比率。因为你说过强制转换NatImgR会得到正确的值。嗯,我在这里尝试了量化:NatImgR=exp(floor(log(double(OredChannel)));然后当我