CIELAB 颜色图像中每个超像素的平均颜色 space

Mean color for each superpixel in an image in the CIELAB color space

根据MATLAB帮助测量每个超像素的平均颜色,我将图像分割为200个超像素,并尝试将输出图像中每个像素的颜色设置为超像素区域的平均CIELAB颜色。 输入图片如下图:

B=imread('H.jpg');
A=rgb2lab(B);    // conversion from rgb to lab

[L,N] = superpixels(A,200);
figure
BW = boundarymask(L);
imshow(imoverlay(A,BW,'cyan'),'InitialMagnification',67);


outputImage = zeros(size(A),'like',A);
idx = label2idx(L);
numRows = size(A,1);
numCols = size(A,2);
for labelVal = 1:N
  redIdx = idx{labelVal};
  greenIdx = idx{labelVal}+numRows*numCols;
  blueIdx = idx{labelVal}+2*numRows*numCols;
  outputImage(redIdx) = mean(A(redIdx));
  outputImage(greenIdx) = mean(A(greenIdx));
  outputImage(blueIdx) = mean(A(blueIdx));
end    
figure
imshow(outputImage,'InitialMagnification',67);

我不确定这段代码的输出是否正确地给出了 CIELAB 颜色 space 中每个超像素的正确平均颜色。与 RGB 颜色相比,图像的颜色是否如此不同 space 或者代码不正确? CIELAB颜色通道平均颜色测量space,代码有问题吗?

这里的主要问题是 imshow 显示给您的不是数据包含的内容。

imshow 假设,对于 double 输入,像素值在 [0,1] 范围内。 Lab在第一个通道中的范围是[0,100],我相信在其他两个通道中是[-20,20](也许不同,但这两个通道是围绕0对称的,这是灰色的)。

如果你这样做 imshow(A,[]) 那么数据将被缩放以显示所有内容。因此将对所有通道进行相同的缩放,因此这也不是查看数据的最佳方式,但无论如何 L 通道将显示为红色,a 和 b 通道将显示为绿色和蓝色。不要指望这看起来像您的原始图像,即使您仍然拥有恢复原始图像的所有数据。

接下来,superpixels需要一个RGB图像作为输入,考虑传递原始图像B,而不是Lab图像A。这不会阻止您在找到的超像素内计算 Lab 通道的方法。 可以选择使用 Lab 输入图像)。

如果您想测量每个超像素内的平均 Lab 值并在进一步处理中使用它,请不要创建 outputImage,而是使用这些值创建 table:

data = zeros(N,3);
for labelVal = 1:N
  redIdx = idx{labelVal};
  greenIdx = idx{labelVal}+numRows*numCols;
  blueIdx = idx{labelVal}+2*numRows*numCols;
  data(labelVal,1) = mean(A(redIdx));
  data(labelVal,2) = mean(A(greenIdx));
  data(labelVal,3) = mean(A(blueIdx));
end    

现在,data(ii,:) 是超像素数 ii 的 Lab 值。 L==ii 是属于这个超像素的像素。

请注意,尽管超像素算法 SLIC 在 L*a*b* space 中运行,但它需要 RGB 图像作为输入。如果您想要预计算 L*a*b* 表示以供下游使用,例如在您的用例中,您需要使用 'IsInputLab' Name/Value。否则,该算法将尝试将已经是 L*a*b* 的图像转换为 L*a*b*。

你想要:

B=imread('H.jpg');
A=rgb2lab(B);  
[L,N] = superpixels(A, 200,'IsInputLab',true);

Chris Lueno 已经回答了超像素图中特征的平均计算。超像素之间的距离是相似的,你基本上计算每个超像素的质心特征来描述它们的位置,然后测量它们之间的距离。请注意,在下面的代码中,矩阵关于其对角线对称且对角线上为 0。如果你关心这个,我会把它留给你来提高效率。

distanceMatrix = zeros(N,N);
for m = 1:N
    for n = 1:n
        [i1,j1] = ind2sub(size(A),idx{m});
        [i1,j2] = ind2sub(size(A),idx{n});
        Icenter1 = mean(i1);
        Jcenter1 = mean(j1);
        Icenter2 = mean(i2);
        Jcenter2 = mean(j2);
        distanceMatrix(m,n) = sqrt((Icenter1-Icenter2)^2+(Jcenter1-Jcenter2)^2);
    end 
end