我正在读取一个位图文件,并将每个的RGB值从0到255转换为二进制。
因此240 x 320位图将具有230400 RGB值进行转换。原来的dec2bin函数太慢了,所以我写了自己的函数,因为我知道我的值总是在0到255之间。
但是,通过230400值仍然需要大约。在我的机器上6秒,单色位图大约需要2.3秒。
无论如何,加速时间不到1秒甚至更好0.5秒,因为我的应用程序每毫秒计算一次?
这是我的代码:
function s = dec2bin_2(input)
if input == 255
s = [1;1;1;1;1;1;1;1];
return;
end
s = [0;0;0;0;0;0;0;0];
if input == 0
return;
end
if input >= 128
input = input - 128;
s(1) = 1;
if input == 0
return;
end
end
if input >= 64
input = input - 64;
s(2) = 1;
if input == 0
return;
end
end
if input >= 32
input = input - 32;
s(3) = 1;
if input == 0
return;
end
end
if input >= 16
input = input - 16;
s(4) = 1;
if input == 0
return;
end
end
if input >= 8
input = input - 8;
s(5) = 1;
if input == 0
return;
end
end
if input >= 4
input = input - 4;
s(6) = 1;
if input == 0
return;
end
end
if input >= 2
input = input - 2;
s(7) = 1;
if input == 0
return;
else
s(8) = 1;
end
end
end
我在想如果我在MATLAB中无法做到这一点,那么我可能会用C ++进行转换。这是可取的吗?
感谢。
答案 0 :(得分:10)
更快的方法是使用查找表。由于您知道所有值都是0到255之间的强度,因此您可以构造每个值的二进制等值来加速该过程。
% build table (computed once) [using gnovice option#1]
lookupTable = cell2mat(arrayfun(@(i)bitget([0:255]',9-i),1:8,'UniformOutput',0));
% random' image
I = randi(256, [240 320])-1;
% decimal to binary conversion
binI = lookupTable(I(:)+1,:);
在我的机器上,它平均花费0.0036329秒(仅转换)。请注意,查找表几乎没有空间开销:
>> whos lookupTable
Name Size Bytes Class Attributes
lookupTable 256x8 2048 uint8
答案 1 :(得分:4)
您可以循环覆盖图像中的每个像素(或RGB值),并使用BITGET获取0和1的向量。以下是如何使用BITGET的示例:
>> bitget(uint8(127),8:-1:1) % Get bits 8 through 1 for a uint8 value
ans =
0 1 1 1 1 1 1 1
可以创建一个矢量化解决方案,在其中循环每个位而不是每个像素,每次通过循环对整个图像矩阵执行BITGET操作。以下是一个这样的实现:
function B = get_bits(A,N)
% Gets the N lowest bits from each element of A
B = zeros([size(A) 0]);
nDims = ndims(A)+1;
for iBit = N:-1:1
B = cat(nDims,B,bitget(A,iBit));
end
end
如果矩阵A
是2-D(n-by-m)或3-D(n-by-m-by-p),矩阵B
将更大一维。额外维度的大小为N
,索引1中的位数最高。您可以索引此维度以获取位值,或将B
转换为更容易可视化的形式。以下是用法示例:
>> A = uint8([126 128; 127 129]); % A 2-by-2 matrix of uint8 values
>> B = get_bits(A,8); % B is a 2-by-2-by-8 matrix
>> B(:,:,1) % Get bit 8 for each value in A
ans =
0 1
0 1
>> reshape(B,4,8) % Reshape B into a 4-by-8 matrix
ans =
0 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0
1 0 0 0 0 0 0 1
答案 2 :(得分:0)
你不能用bitand直接得到这些位吗?
s(0) = 256 bitand input
s(1) = 128 bitand input
s(2) = 64 bitand input
等...
答案 3 :(得分:0)
这种问题(在大型数组上执行每元素操作,因为Matlab的内置代码太慢)有时会在Java中调用解决方案,因为Matlab在JRE上运行并且转换/传递数组参数是通常是一个相当快速的操作。
gnovice的解决方案听起来对你有用,但是如果你遇到一个你无法在纯Matlab中解决的情况,并且你精通Java,那么考虑编写一个自定义的JAR文件。这很容易。 (好吧,比试图将C ++与Matlab接口要容易得多!)