matlab中RGB组合的直方图
我有一个RGB图像(uint8类型),我想执行以下过程:matlab中RGB组合的直方图,matlab,image-processing,histogram,particle-filter,Matlab,Image Processing,Histogram,Particle Filter,我有一个RGB图像(uint8类型),我想执行以下过程: 将图像量化到16个级别(每层) 计算每个RGB组合的直方图:首先,我需要一个16*16*16矩阵来保存这些值-即,如果我们表示直方图矩阵hist,那么hist(2,9,3)应该保存直方图中强度等级为r=2,g=9的像素数量,b=3等。下一步是将其重塑为4096*1矢量(但这是最简单的部分) 目前,我有以下实现: function hist = compRGBHist(I) I = I./16 % quantize to 16 co
hist
,那么hist(2,9,3)
应该保存直方图中强度等级为r=2,g=9的像素数量,b=3等。下一步是将其重塑为4096*1矢量(但这是最简单的部分)function hist = compRGBHist(I)
I = I./16 % quantize to 16 color levels
hist = zeros(16,16,16);
[m, n, ~] = size(I);
for i=1:m
for j = 1:n
rgb = impixel(I,j,i);
r = rgb(1);
g = rgb(2);
b = rgb(3);
A(r,g,b) = A(r,g,b) + 1;
end
end
hist = reshape(hist, 4096, 1);
end
这个实现是可行的,但速度非常慢-我需要重复100次这个过程(作为实现粒子过滤器的一部分),即使在大小约为80*40的非常小的图像(实际上是图像部分)上执行,也需要很长时间我正在寻找一种更有效的方法来实现这一点。谢谢 您可以使用位移位将RGB的4位值转换为12位值:
I = uint16(bitshift(I,-4)); % make sure the integer is large enough
twelvebit = bitshift(I(:,:,1),8) + bitshift(I(:,:,2)),4) + I(:,:,3);
这将产生如下所示的值:
0 0 0 0 R R R R G G G G B B B B
------- ------- ------- -------
unused red green blue
现在,您的值在[0..4095]范围内,您可以计算4096个箱子的直方图。您可以使用位移位将RGB的4位值转换为12位值:
I = uint16(bitshift(I,-4)); % make sure the integer is large enough
twelvebit = bitshift(I(:,:,1),8) + bitshift(I(:,:,2)),4) + I(:,:,3);
这将产生如下所示的值:
0 0 0 0 R R R R G G G G B B B B
------- ------- ------- -------
unused red green blue
现在,您的值在[0..4095]范围内,您可以计算4096个箱子的直方图。如果您将uint8(0..255)除以2^4,则得到的范围是(0..16),而不是(0..15)。我想你应该先减去2^3,以确保你得到的是16个垃圾箱
I = randi([0 255],512,512,3,'uint8'); %example data
I = (I-2^3)./2^4;
I = uint16(I);
I(:,:,2)=I(:,:,2)*2^4;
I(:,:,3)=I(:,:,3)*2^8;
I = sum(I,3,'native');
h=hist(I(:),[0:4095]);
h=reshape(h,[16 16 16]);
如果将uint8(0..255)除以2^4,则得到的范围是(0..16),而不是(0..15)。我想你应该先减去2^3,以确保你得到的是16个垃圾箱
I = randi([0 255],512,512,3,'uint8'); %example data
I = (I-2^3)./2^4;
I = uint16(I);
I(:,:,2)=I(:,:,2)*2^4;
I(:,:,3)=I(:,:,3)*2^8;
I = sum(I,3,'native');
h=hist(I(:),[0:4095]);
h=reshape(h,[16 16 16]);
我喜欢这里的Accumaray
function hist = compRGBHist(I)
I = bitshift(I, -4); % quantize to 16 color levels
R = I(:,:,1) + 1; % +1 to be in [1..16]
G = I(:,:,2) + 1;
B = I(:,:,3) + 1;
A = accumarray([R(:), G(:), B(:)], 1, [16,16,16]);
hist = reshape(A, 4096, 1);
end
注:烧杯的,bitshift
解决方案可能是最好的。我喜欢这里的Accumaray
:
function hist = compRGBHist(I)
I = bitshift(I, -4); % quantize to 16 color levels
R = I(:,:,1) + 1; % +1 to be in [1..16]
G = I(:,:,2) + 1;
B = I(:,:,3) + 1;
A = accumarray([R(:), G(:), B(:)], 1, [16,16,16]);
hist = reshape(A, 4096, 1);
end
PS:Bicker's,bitshift
解决方案可能是最好的。为什么不将每个通道的4位级别连接成一个12位整数,然后计算4096个箱子上的直方图?听起来很有趣。。。如何执行这种连接?我不确定我是否熟悉这种技术。。。我需要它无循环,如果可能的话,请不要I./16
在[0..16]
中给出结果?我不这么认为,图像层中的最高级别是255,所以255/16(假设它是uint8图像)15@G.J255/16=16(matlab对整数除法执行舍入):为什么不将每个通道的4位级别连接成一个12位整数,然后计算4096个箱子上的直方图?听起来很有趣。。。如何执行这种连接?我不确定我是否熟悉这种技术。。。我需要它无循环,如果可能的话,请不要I./16
在[0..16]
中给出结果?我不这么认为,图像层中的最高级别是255,所以255/16(假设它是uint8图像)15@G.J255/16=16(matlab对整数除法执行舍入):谢谢!哪个函数最适合计算4096直方图?我不确定该选哪一个。histogram
和histcounts
都允许您指定存储箱的数量,但是histogram
也会绘制条形图,所以我想这取决于您是否想查看该图hist
和histc
是旧版本,新版本的MATLAB不鼓励使用它们。谢谢!哪个函数最适合计算4096直方图?我不确定该选哪一个。histogram
和histcounts
都允许您指定存储箱的数量,但是histogram
也会绘制条形图,所以我想这取决于您是否想查看该图hist
和histc
是旧版本,在新版本的MATLAB中不鼓励使用它们。你说得对。它实际上应该是floor
或bitshift
。我会更新我的答案。啊,bitshift确实是一个更好的解决方案!谢谢。结合你的答案,我得到了最好的结果。谢谢你们两位@bicker和GelliantYou说得很好。它实际上应该是floor
或bitshift
。我会更新我的答案。啊,bitshift确实是一个更好的解决方案!谢谢。结合你的答案,我得到了最好的结果。谢谢你们两位@bicker和Gelliantaccumarray
总是很有趣,但是直方图
太快了,很难被打败。@G.J我刚刚试过-注意accumarray
不一定能创建16*16*16矩阵。在这种情况下,重塑
失败……您可以将输出的大小指定为第三个参数。我将进行编辑以添加它。accumarray
总是很有趣,但histogram
太快了,很难打败。@G.J我刚刚尝试过它-请注意accumarray
不一定创建16*16*16矩阵。在这种情况下,重塑
失败……您可以将输出的大小指定为第三个参数。我将编辑以添加它。