计算图像中每种颜色(像素值)的出现次数
Count appearances of every color (pixel values) in an image
我正在尝试为作业的皮肤分割实现贝叶斯分类器,但我在计算时遇到了一些问题。
问题是我关注的论文说我需要 RGB 直方图或某种地图
种类结构:
map(R,G,B) -> 图像中出现的次数
到目前为止,我已经尝试找到满足此要求的地图结构或一些可以更轻松地完成此计数的函数或方法(我仍然希望某处有一个函数可以避免我遍历所有图像).
理想情况下,我需要它是快速的,因为我需要对数据集中一堆图像的计数求和。
欢迎提出任何想法。
也许这可以帮助:
imdata = double(imread('test.jpg'));
tic
[m,n,~] = size(imdata);
pixels = m*n;
x = imdata(:,:,1)*1000000+imdata(:,:,2)*1000+imdata(:,:,3);
keys = unique(x);
n_keys = length(keys);
map = containers.Map(keys,zeros(n_keys,1));
for i = 1:pixels
map(x(i)) = map(x(i)) +1;
end
toc
%here comes post-processing
tic
b = rem(keys, 1000);
g = floor((rem(keys, 1000000) - b)/1000);
r = floor(keys/1000000);
v = map.values;
result = [r g b [v{:}]'];
toc
我很确定这既不是最快也不是最优雅的解决方案。
我尝试做的事情:
每一种颜色的可逆单值
在 Map 对象中使用唯一值作为键
计算每个值的出现次数
最后一部分 - 可选 - 将地图转换为数组,其中前 3 列用于颜色分量,最后一列用于出现次数。
我在像附件一样的简单图片上检查过
您可以用它来测试,它是 500x500,只有 4 种颜色。在我的电脑上用了不到 7 秒。我在真实的 1080x1920 像素图像上进行了尝试——用了 57 秒。相当慢,我猜。所以,我尝试了另一种方法——我用另一种方法替换了循环:
for i = 1:n_keys
map(keys(i)) = sum(sum(x==keys(i)));
end
对于小图像,它的工作时间不到 0.05 秒(哇!)- 在这种情况下我们的密钥很少,因此我们进行了很少的迭代。
但是对于大的 - 它有 271833 种独特的颜色 - 需要几分钟,使得这种方法不可接受。如果我们可以将接近的颜色分组在一个容器中 - 它会工作得更快。
所以,我会坚持使用第一种方法。
我正在尝试为作业的皮肤分割实现贝叶斯分类器,但我在计算时遇到了一些问题。
问题是我关注的论文说我需要 RGB 直方图或某种地图 种类结构:
map(R,G,B) -> 图像中出现的次数
到目前为止,我已经尝试找到满足此要求的地图结构或一些可以更轻松地完成此计数的函数或方法(我仍然希望某处有一个函数可以避免我遍历所有图像).
理想情况下,我需要它是快速的,因为我需要对数据集中一堆图像的计数求和。
欢迎提出任何想法。
也许这可以帮助:
imdata = double(imread('test.jpg'));
tic
[m,n,~] = size(imdata);
pixels = m*n;
x = imdata(:,:,1)*1000000+imdata(:,:,2)*1000+imdata(:,:,3);
keys = unique(x);
n_keys = length(keys);
map = containers.Map(keys,zeros(n_keys,1));
for i = 1:pixels
map(x(i)) = map(x(i)) +1;
end
toc
%here comes post-processing
tic
b = rem(keys, 1000);
g = floor((rem(keys, 1000000) - b)/1000);
r = floor(keys/1000000);
v = map.values;
result = [r g b [v{:}]'];
toc
我很确定这既不是最快也不是最优雅的解决方案。 我尝试做的事情:
每一种颜色的可逆单值
在 Map 对象中使用唯一值作为键
计算每个值的出现次数
最后一部分 - 可选 - 将地图转换为数组,其中前 3 列用于颜色分量,最后一列用于出现次数。
我在像附件一样的简单图片上检查过
您可以用它来测试,它是 500x500,只有 4 种颜色。在我的电脑上用了不到 7 秒。我在真实的 1080x1920 像素图像上进行了尝试——用了 57 秒。相当慢,我猜。所以,我尝试了另一种方法——我用另一种方法替换了循环:
for i = 1:n_keys
map(keys(i)) = sum(sum(x==keys(i)));
end
对于小图像,它的工作时间不到 0.05 秒(哇!)- 在这种情况下我们的密钥很少,因此我们进行了很少的迭代。 但是对于大的 - 它有 271833 种独特的颜色 - 需要几分钟,使得这种方法不可接受。如果我们可以将接近的颜色分组在一个容器中 - 它会工作得更快。
所以,我会坚持使用第一种方法。