Image 计算图像中的颜色数

Image 计算图像中的颜色数,image,matlab,image-processing,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=

我是一个新手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 

您的代码实际上很好(保存一些语法错误)。您只需确保您的
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。然后,您可以应用、和的组合以实现所需的结果。具体而言:

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
最初是一个
逻辑矩阵。因为
[4 2 1]
是一个数字数组,如果要使用
times
函数,两个输入的类必须相同
bsxfun
基本上将复制3D列向量,直到它与二进制3D矩阵的形状匹配,这与彩色图像的大小相同。这样做的结果是,任何超过阈值的红色分量都将被分配值4和0,否则,同样地,对于绿色,我们得到2和蓝色1

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

使用
for
循环,结果应与上述代码等效。事实上,我刚刚运行了一些结果,它确实匹配



祝你好运

您的
如果
-
else
语句不完整,它们没有
结束
s,但是您在结束时有3个
结束
s,它们结束的是什么?您的代码实际上是很好的。只需确保每个
if-else
块都有
end
语句。顺便问一下,为什么只检查前5行?为什么不完整的图片,因为这是直方图应该做的?无论如何,非常感谢您的回复。我昨天终于解决了我的问题。是的,当然我必须结束每一个if-else语句。我已经完成了一个程序,通过使用RGB方法,从000到111,可以在图像中计算多达8种颜色。我需要对它做一些修改。到目前为止,我声明如果128以上等于1,128以下等于0。它将计算8种颜色。如果让我从0-64,65-128129-192193-255部分增加颜色数,如何增加颜色数。@RabaniAhmadTasman-这需要提出一个新问题。请在我回答之前这样做。