Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image 两幅图像的互信息和联合熵——MATLAB_Image_Matlab_Image Processing_Entropy_Information Theory - Fatal编程技术网

Image 两幅图像的互信息和联合熵——MATLAB

Image 两幅图像的互信息和联合熵——MATLAB,image,matlab,image-processing,entropy,information-theory,Image,Matlab,Image Processing,Entropy,Information Theory,我有两个黑白图像,我需要计算互信息 Image 1 = X Image 2 = Y 我知道相互信息可以定义为: MI = entropy(X) + entropy(Y) - JointEntropy(X,Y) MATLAB已经内置了计算熵的函数,但没有计算联合熵。我想真正的问题是:如何计算两幅图像的联合熵 下面是一个我想找出联合熵的图像示例: X = 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1

我有两个黑白图像,我需要计算互信息

Image 1 = X 
Image 2 = Y
我知道相互信息可以定义为:

MI = entropy(X) + entropy(Y) - JointEntropy(X,Y)
MATLAB已经内置了计算熵的函数,但没有计算联合熵。我想真正的问题是:如何计算两幅图像的联合熵

下面是一个我想找出联合熵的图像示例:

X =

0    0    0    0    0    0
0    0    1    1    0    0
0    0    1    1    0    0
0    0    0    0    0    0
0    0    0    0    0    0

Y =

0    0    0    0    0    0 
0    0    0.38 0.82 0.38 0.04 
0    0    0.32 0.82 0.68 0.17
0    0    0.04 0.14 0.11 0 
0    0    0    0    0    0

要计算关节熵,需要计算两幅图像之间的关节直方图。联合直方图基本上与正常的1D直方图相同,但第一个图像的第一维记录强度,第二个图像的第二维记录强度。这与通常所说的a非常相似。在关节直方图中的位置
(i,j)
,它告诉您我们遇到了多少个强度值,第一个图像中的强度
i
,第二个图像中的强度
j

重要的是,这记录了我们在相同的对应位置看到这对强度的次数。例如,如果我们的联合直方图计数为
(7,3)=2
,这意味着当我们扫描两幅图像时,当我们在第二幅图像的相同对应位置遇到
7
的强度时,我们总共遇到
3
的强度
2次

构造联合直方图非常简单

  • 首先,创建一个
    256 x 256
    矩阵(假设图像是无符号8位整数),并将其初始化为全零。此外,您需要确保两个图像的大小(宽度和高度)相同
  • 一旦你这样做了,看看每个图像的第一个像素,我们将表示为左上角。具体来说,请查看此位置的第一个和第二个图像的强度。第一幅图像的强度将用作行,而第二幅图像的强度将用作列
  • 在矩阵中找到该位置,并将矩阵中的该点增加
    1
  • 对图像中的其余位置重复此操作
  • 完成后,将所有条目除以任一图像中的元素总数(记住它们的大小应该相同)。这将给出两幅图像之间的联合概率分布
  • 人们倾向于使用
    for
    循环来实现这一点,但众所周知,
    for
    循环速度非常慢,应该尽可能避免。但是,您可以通过以下方式在MATLAB中轻松完成此操作,而无需使用循环。让我们假设
    im1
    im2
    是要比较的第一个和第二个图像。我们能做的就是将
    im1
    im2
    转换成向量。然后,我们可以使用来帮助我们计算关节直方图
    accumarray
    是MATLAB中最强大的函数之一。您可以将其视为一个微型MapReduce范例。简单地说,每个数据输入都有一个键和一个关联的值。
    accumarray
    的目标是存储属于同一个键的所有值,并对所有这些值执行一些操作。在我们的例子中,“关键点”是强度值,对于每个强度值,值本身就是
    1
    的值。然后,我们希望将映射到同一个bin的
    1
    的所有值相加,这正是我们计算直方图的方法。
    accumarray
    的默认行为是添加所有这些值。具体而言,
    accumarray
    的输出将是一个数组,其中每个位置计算映射到该键的所有值的总和。例如,第一个位置是映射到键1的所有值的总和,第二个位置是映射到键2的所有值的总和,依此类推

    但是,对于关节直方图,您需要确定哪些值映射到相同的
    (i,j)
    强度对,因此这里的关键点是一对二维坐标。同样地,在两个图像之间共享的相同空间位置中,在第一个图像中具有
    i
    强度且在第二个图像中具有
    j
    强度的任何强度进入相同的键。因此,在2D情况下,
    accumarray
    的输出将是2D矩阵,其中每个元素
    (i,j)
    包含映射到键
    (i,j)
    的所有值的总和,类似于前面提到的1D情况,这正是我们所追求的

    换言之:

    indrow = double(im1(:)) + 1;
    indcol = double(im2(:)) + 1; %// Should be the same size as indrow
    jointHistogram = accumarray([indrow indcol], 1);
    jointProb = jointHistogram / numel(indrow);
    
    使用
    accumarray
    ,第一个输入是键,第二个输入是值。关于
    accumarray
    的一个注意事项是,如果每个键都有相同的值,您可以简单地为第二个输入指定一个常量,这就是我所做的,它是
    1
    。通常,这是一个与第一个输入具有相同行数的数组。另外,请特别注意前两行。图像中不可避免地会出现
    0
    的强度,但由于MATLAB从
    1
    开始索引,我们需要将两个数组偏移
    1

    现在我们有了关节直方图,计算关节熵真的很简单。它类似于1D中的熵,只是现在我们只是对整个联合概率矩阵求和。请记住,您的关节直方图很可能有许多
    0
    条目。我们需要确保跳过这些操作,否则
    log2
    操作将未定义。现在让我们去掉任何零项:

    indNoZero = jointHistogram ~= 0;
    jointProb1DNoZero = jointProb(indNoZero);
    
    注意,我搜索的是联合直方图,而不是联合概率矩阵。这是我的
    jointEntropy = -sum(jointProb1DNoZero.*log2(jointProb1DNoZero));
    
    [~,~,indrow] = unique(im1(:)); %// Change here
    [~,~,indcol] = unique(im2(:)); %// Change here
    
    %// Same code
    jointHistogram = accumarray([indrow indcol], 1);
    jointProb = jointHistogram / numel(indrow);
    indNoZero = jointHistogram ~= 0;
    jointProb1DNoZero = jointProb(indNoZero);
    jointEntropy = -sum(jointProb1DNoZero.*log2(jointProb1DNoZero));
    
    histogramImage1 = sum(jointHistogram, 1);
    histogramImage2 = sum(jointHistogram, 2);
    
    %// Find non-zero elements for first image's histogram
    indNoZero = histogramImage1 ~= 0;
    
    %// Extract them out and get the probabilities
    prob1NoZero = histogramImage1(indNoZero);
    prob1NoZero = prob1NoZero / sum(prob1NoZero);
    
    %// Compute the entropy
    entropy1 = -sum(prob1NoZero.*log2(prob1NoZero));
    
    %// Repeat for the second image
    indNoZero = histogramImage2 ~= 0;
    prob2NoZero = histogramImage2(indNoZero);
    prob2NoZero = prob2NoZero / sum(prob2NoZero);
    entropy2 = -sum(prob2NoZero.*log2(prob2NoZero));
    
    %// Now compute mutual information
    mutualInformation = entropy1 + entropy2 - jointEntropy;