计算图像中的颜色数
Count the number of colors in images
我是一名 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
语句正确结束(请参阅上面问题中丹尼尔的评论)。例如,您需要为其中之一执行此操作:
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。然后,您可以应用 bsxfun
, permute
, sum
and accumarray
的组合来获得所需的结果。具体来说:
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
函数,两个输入的 class 需要相同。 bsxfun
本质上将 复制 3D 列向量,直到它与二进制 3D 矩阵匹配相同的形状,其大小与彩色图像相同。这样做的结果是,任何超过阈值的红色分量都被赋予 4 的值,否则为 0,同样对于绿色,我们得到 2 和蓝色 1。
要像您的代码中那样计算索引,我们只需使用 sum
并在第三维求和。这意味着对于矩阵中的每个 3D 列,我们将所有组件相加以生成我们的索引号。因此,out
将是一个二维矩阵,表示图像中每个位置的索引。最后一行代码使用 accumarray
,我们检查 out
中的所有元素并累积它们的所有出现。将矩阵 运行 转换为单个列向量很重要,因此我们使用 (:)
展开矩阵。我们还加 1,因为生成的索引 运行 在 0 到 7 之间。因为 MATLAB 索引数组从 1 开始,这就是我们添加这个值的原因。
结果应该等同于使用 for
循环的上述代码。事实上,我只是 运行 一些结果,它确实匹配。
祝你好运!
我是一名 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
语句正确结束(请参阅上面问题中丹尼尔的评论)。例如,您需要为其中之一执行此操作:
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。然后,您可以应用 bsxfun
, permute
, sum
and accumarray
的组合来获得所需的结果。具体来说:
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
函数,两个输入的 class 需要相同。 bsxfun
本质上将 复制 3D 列向量,直到它与二进制 3D 矩阵匹配相同的形状,其大小与彩色图像相同。这样做的结果是,任何超过阈值的红色分量都被赋予 4 的值,否则为 0,同样对于绿色,我们得到 2 和蓝色 1。
要像您的代码中那样计算索引,我们只需使用 sum
并在第三维求和。这意味着对于矩阵中的每个 3D 列,我们将所有组件相加以生成我们的索引号。因此,out
将是一个二维矩阵,表示图像中每个位置的索引。最后一行代码使用 accumarray
,我们检查 out
中的所有元素并累积它们的所有出现。将矩阵 运行 转换为单个列向量很重要,因此我们使用 (:)
展开矩阵。我们还加 1,因为生成的索引 运行 在 0 到 7 之间。因为 MATLAB 索引数组从 1 开始,这就是我们添加这个值的原因。
结果应该等同于使用 for
循环的上述代码。事实上,我只是 运行 一些结果,它确实匹配。
祝你好运!