计算图像中的颜色数量

时间:2015-01-14 02:42:08

标签: image matlab image-processing

我是新手MATLAB程序员。我需要使用RGB计算图像中的颜色数量并显示在直方图中。 x轴将从0到7,因为它具有8种颜色,从二进制000到111(总共8种颜色)相同。 y轴将是图像中的颜色值。这是我的编程,但它并不完整。

count = zeros (1,8);
img = imread ('peppers.png');
[r,c,h] = size(img);

for i=1:5
    for j= 1:c

    a= img(i,j,1);
    b= img(i,j,2);
    d= img(i,j,3);

    if a >128,
        a2 =1;
    else
        a2 =0;

    if b > 128,
        b2 = 1;
    else
        b2 = 0;

    if d > 128,
        d2 = 1;
    else
        d2 = 0;




        index = 4*a2 + 2*b2 + d2 + 1;
        count(index) = count(index)+1;
    end

    end
end 

1 个答案:

答案 0 :(得分:0)

您的代码实际上很好(保存了几个语法错误)。您只需确保if-else语句正确结束(请参阅Daniel在上述问题中的评论)。例如,您需要为其中一个执行此操作:

if a >128,
    a2 =1;
else
    a2 =0;
end %// CHANGE

代码末尾有一个额外的end语句。请确保将其删除并将end语句正确放置在if-else语句所在的位置。因此,您的代码将是:

count = zeros (1,8);
img = imread ('onion.png');
[r,c,h] = size(img);

for i=1:r
    for j= 1:c

    a= img(i,j,1);
    b= img(i,j,2);
    d= img(i,j,3);

    if a >128,
        a2 =1;
    else
        a2 =0;
    end

    if b > 128,
        b2 = 1;
    else
        b2 = 0;
    end

    if d > 128,
        d2 = 1;
    else
        d2 = 0;
    end

    index = 4*a2 + 2*b2 + d2 + 1;
    count(index) = count(index)+1;

    end
end 

您似乎只计算前5行。我已经改变了这一点,以便你查看所有的行。


但是,如果我可以建议一种替代方法,您可以通过完全避免循环来实现。您可以简单地将整个RGB阵列的阈值设置为128,这将分别为每个颜色平面生成1和0。然后,您可以应用bsxfunpermutesumaccumarray的组合来获得所需的结果。具体做法是:

t = img > 128;
out = sum(bsxfun(@times, double(t), permute([4 2 1], [3 1 2])), 3);
count = accumarray(out(:) + 1, 1, [8 1]);

以上三行代码非常紧凑,但还有很多。第一行遍历RGB图像的每个元素,如果值大于128,则将每个平面位置的输出设置为1,否则设置为0。接下来,我们来看看这行代码:

bsxfun(@times, double(t), permute([4 2 1], [3 1 2]))

有点屈指可数,但没有问题要解释。让我们先区分这个部分:

permute([4 2 1], [3 1 2])

permute采用矩阵或向量并重新排序元素,使尺寸发生变化。因此,我们采用向量[4 2 1](允许我们为每个位串计算唯一的基数10)并获取第三维并将其放入输出的第一维。接下来,我们获取第一个维度(行)并将它们放入输出的第二个维度。最后,我们采用第二维(列)并将其放入输出的第三维。结果将是单个3D列,其中第一个切片包含4,下一个切片包含2,最后一个切片包含1.

现在,bsxfun的工作是获取二进制3D矩阵t并使用第二个3D矩阵进行逐点乘法,其中第一个平面完全由4个组成,下一个平面由2和最后一个平面由1组成。我们需要将t转换为double,因为t最初是logical矩阵。因为[4 2 1]是数字数组,如果要使用times函数,则两个输入的类必须相同。 bsxfun基本上复制 3D列向量,直到它与二进制3D矩阵匹配相同的形状,二维3D矩阵与彩色图像的大小相同。这样做的结果是超过阈值的任何红色分量都被赋值为4和0,否则,对于绿色我们得到2和蓝色1。

要计算代码中的索引,我们只需使用sum并在第三维中求和。这意味着对于矩阵中的每个3D列,我们将所有组件相加以生成索引号。因此,out将是一个2D矩阵,表示图像中每个位置的索引。最后一行代码使用accumarray,我们检查out中的所有元素并累积它们的所有出现次数。将矩阵转换为单个列向量非常重要,因此我们使用(:)展开矩阵。我们还加1,因为生成的索引范围在0到7之间。因为MATLAB从1开始索引数组,所以我们添加了这个值。

结果应该等同于使用for循环的上述代码。事实上,我只是运行了一些结果并确实匹配。


祝你好运!