【问题标题】:Matlab : 256 binary matrices to one 256 levels grayscale imageMatlab:256个二进制矩阵到一个256级灰度图像
【发布时间】:2011-06-03 11:15:06
【问题描述】:

我的一个过程产生 256 个二进制(逻辑)矩阵,一个用于灰度源图像的每一级。

代码如下:

so = imread('bio_sd.bmp');
co = rgb2gray(so);

for l = 1:256
    bw = (co == l); %         Binary image from level l of original image
    be = ordfilt2(bw, 1, ones(3, 3)); %  Convolution filter
    bl(int16(l)) = {bwlabel(be, 8)}; %   Component labelling
end

我获得了一个包含 256 个二进制图像的单元阵列。如果该位置的源图像像素与二值图像的索引具有相同的级别,则这样的二值图像包含 1。

即。二值图像 bl{12} 包含 1,其中源图像的像素级别为 12。

我想通过将 256 个二进制矩阵组合回灰度图像来创建新图像。

但我对 Matlab 很陌生,我想知道是否有人可以帮我编写代码:)

ps:我使用的是matlab R2010a学生版。

【问题讨论】:

  • 你能确定每个像素都有一个“1”和 255 个“0”吗?如果不是,应该如何解决冲突?
  • 不,源图像的每个像素都有一个级别值。如果该位置的源图像像素与二值图像的索引具有相同的级别,则二值图像包含 1。
  • 查看您在编辑问题时添加的代码:我认为您应该非常仔细地查看您的代码实际执行的操作,与您认为的操作相比,以及函数的文档你用。例如,bwlabel 可以轻松返回大于 1 的值,这与您的想法相反。我不认为当前的代码接近你想要它做的......
  • 对不起,我的问题似乎不够清楚。
  • @gnovice 很好地解释了您的代码的作用。请注意,原始代码的循环变量中也存在一个错误:灰度值将从 0 变为 255,因此循环变量 l 不应上升到 256,而应该从 0 开始1.当然这意味着你不能直接使用l作为bl的索引,你需要使用l+1

标签: matlab image-processing pixels grayscale


【解决方案1】:

整个答案仅适用于original form of the question

假设您可以将所有二进制矩阵组合成一个大的 n×m×256 矩阵binaryimage(x,y,greyvalue)。然后你可以计算你的最终图像为

newimage=sum(bsxfun(@times,binaryimage,reshape(0:255,1,1,[])),3)

这里的魔法是由 bsxfun 完成的,它将 3D (n x m x 256) 二值图像与包含灰度值 0...255 的 1 x 1 x 256 向量相乘。这将生成一个 3D 图像,其中对于固定的 x 和 y,向量 (y,x,:) 包含许多零,并且(对于一个灰度值 G,其中二进制图像包含 1)它包含值 @987654326 @。所以现在你只需要对这个三维求和就可以得到n x m 图像。

更新

为了测试它是否正常工作,让我们先换一种方式:

fullimage=floor(rand(100,200)*256);
figure;imshow(fullimage,[0 255]);

是随机灰度图像。您可以像这样计算 256 个二进制矩阵:

binaryimage=false([size(fullimage) 256]);
for i=1:size(fullimage,1)
   for j=1:size(fullimage,2)
      binaryimage(i,j,fullimage(i,j)+1)=true;
   end
end

我们现在可以应用我上面给出的解决方案

newimage=sum(bsxfun(@times,binaryimage,reshape(0:255,1,1,[])),3);

并验证我是否返回了原始图像:

all(newimage(:)==fullimage(:))

给出1 (true) :-)。

更新 2

您现在提到您的二进制图像在一个单元格数组中,我假设binimg{1:256},每个单元格包含一个 n x m 二进制数组。如果可以的话,更改生成此数据的代码以创建我在上面使用的 3D 二进制数组可能是有意义的 - 如果不同的单元格包含不同类型、形状或大小的数据,则单元格最有用。

如果有充分的理由坚持使用元胞数组,您可以使用将其转换为 3D 数组

binaryimage = reshape(cell2mat(reshape(binimg,1,256)),n,m,256);

使用上面使用的nm。如果您已经拥有size(binimg)==[1 256],则无需进行内部重塑。所以总结一下,您需要使用您的单元格数组binimg 来计算3D 矩阵二进制图像,然后您可以使用它来计算您有兴趣使用我的答案开头的代码的newimage

希望这会有所帮助...

【讨论】:

  • 感谢您(非常快速)的回答,我很感激。但我遇到了一个理解问题。我的二进制图像是 n×m 逻辑值矩阵(真/假)。我有 256 个,收集在一个单元阵列中。如何将它们与灰度值相乘?我在您的回答中看不到这一点:/
  • 我应该补充一点,新图像结合了二进制图像的所有级别,与原始图像不同,应用了一组过滤器。
  • 嗨@Laurent,如果您有其他信息,也可以将其添加到您的问题中,这样对其他人来说更明显。我在我的答案中添加了一个更新来处理单元数组。我不确定您的第二条评论:在您的问题中,您只询问从二进制图像到普通图像(我在代码示例中将其称为 newimage)。在这个过程中什么时候需要添加过滤器??
  • 嗨@Jonas,我更新了问题以澄清。过滤器应用于 256 个级别的源图像的每个级别,并为每个级别生成 256 个二进制图像,我想将其重新组合成一个生成的灰度图像。
【解决方案2】:

你的代码做了什么...

我认为最好先了解一下您发布的代码实际上在做什么,因为存在一些不一致之处。我将遍历循环中的每一行:

  • bw = (co == l);

    这只是创建一个二进制矩阵bw,其中您的灰度图像co 的像素强度等于循环值l。我注意到你从 1 循环到 256,这让我觉得很奇怪。通常,images loaded into MATLAB 将是 unsigned 8-bit integer type,这意味着灰度值将跨越 0 到 255 的范围。在这种情况下,您在 l = 256 时计算的最后一个二进制矩阵 bw 将始终包含全零。此外,您不会对灰度级别为 0 的像素进行任何处理。从后续处理中,我猜您有意忽略 0 的灰度值,在这种情况下,您可能只需要从 1 循环到 255 .

  • be = ordfilt2(bw, 1, ones(3, 3));

    您在这里使用ORDFILT2 所做的基本上是执行binary erosion operationbw 中的任何值为 1 的 0 作为其 8 个邻居之一将被设置为 0,从而导致岛的侵蚀(即尺寸缩小)。小岛将消失,只留下具有相同灰度级别的较大的连续像素簇。

  • bl(int16(l)) = {bwlabel(be, 8)};

    这就是您可能有一些误解的地方。首先,bl 中的矩阵不是 logical matrices。在您的示例中,函数 BWLABEL 将找到由 8 个连接的集群组成的集群。找到的第一个聚类将在输出图像中将其元素标记为 1,找到的第二个聚类将其元素标记为 2,依此类推。因此,矩阵将包含正整数值,其中 0 表示背景。

    其次,您打算将这些带标签的集群用于任何事情吗?您可能需要进行进一步的处理,您需要在给定的灰度强度级别识别单独的集群,但关于从bl 中的元素创建灰度图像,特定标签 value 是不必要。您只需要识别零值与非零值,因此如果您不使用 bl 其他任何值,我建议您只需将 be 的各个值保存在单元格数组中并使用它们重新创建灰度图片。

现在,进入答案...

一个非常简单的解决方案是使用函数CAT 将您的图像元胞数组连接成一个3-D 矩阵,然后使用函数MAX 查找沿第三维出现非零值的索引(对应于原始图像的灰度值)。对于给定的像素,如果在第三维上没有找到非零值(即全为零),那么我们可以假设像素值应该为 0。但是,MAX 返回的该像素的索引将默认为为1,所以你必须使用最大值作为逻辑索引将像素设置为0:

[maxValue,grayImage] = max(cat(3,bl{:}),[],3);
grayImage(~maxValue) = 0;

请注意,出于displayingsaving 的目的,您可能需要将生成的图像grayImage 的类型更改为无符号的8 位整数类型,如下所示:

grayImage = uint8(grayImage);

【讨论】:

  • 感谢您提供完整而真实的答案,以及您为我的问题奉献的时间。我知道我发布的代码不完整/有问题,但它是初稿,我发布它希望它能更清楚地理解我的问题。我有直觉认为 Matlab 可以很好地适应这个问题。我结束了在 C 中使用 OpenCV 对其进行编码,它可以工作,但代码要长得多:)
【解决方案3】:

最简单的解决方案是依次遍历每个逻辑矩阵,将其乘以相应的权重,然后累积到一个输出矩阵中,该矩阵将代表您的最终图像。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-11
    • 2014-02-19
    相关资源
    最近更新 更多