Matlab:256个二进制矩阵到一个256级灰度图像

时间:2011-06-03 11:15:07

标签: matlab image-processing pixels grayscale

我的一个过程产生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个二进制图像的单元阵列。如果该位置的源图像像素与二进制图像的索引具有相同的级别,则这样的二进制图像包含1s。

即。二进制图像bl {12}包含1s,其中源图像具有级别为12的像素。

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

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

ps:我正在使用matlab R2010a学生版。

3 个答案:

答案 0 :(得分:3)

这整个答案仅适用于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)值G。所以现在你只需要总结这第三个维度来获得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(真): - )。

更新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。我的回答。

希望这会有所帮助......

答案 1 :(得分:2)

你的代码做了什么......

我认为最好首先查看您发布的代码实际上正在执行的操作,因为存在一些不一致之处。我将遍历你的循环中的每一行:

  • bw = (co == l);

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

  • l = 256

    您在ORDFILT2处所做的实际操作是binary erosion operationbe = ordfilt2(bw, 1, ones(3, 3));中以0作为其8个邻居中的一个的任何1的值将被设置为0,导致1的岛被侵蚀(即缩小尺寸)。一个小岛屿将消失,只留下具有相同灰度级别的较大的连续像素簇。

  • bw

    这是你可能会遇到一些误解的地方。首先,bl(int16(l)) = {bwlabel(be, 8)}; 中的矩阵不是 logical matrices。在您的示例中,函数BWLABEL将找到8个连接的集群。找到的第一个簇将在输出图像中将其元素标记为1,找到的第二个簇将其元素标记为2,等等。因此矩阵将包含正整数值,0表示背景。

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

现在,回答......

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

be

请注意,出于displayingsaving的目的,您可能希望将结果图像[maxValue,grayImage] = max(cat(3,bl{:}),[],3); grayImage(~maxValue) = 0; 的类型更改为无符号8位整数类型,如下所示:

grayImage

答案 2 :(得分:1)

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