我有一个来自图像传感器(2560x2160像素)的数据,编码为Mono12Packed。
此编码定义为:
Byte 0: Pixel 1 (bits 4:11)
Byte 1: Pixel 1 (bits 0:3), Pixel 2 (bits 0:3)
Byte 3: Pixel 2 (bits 4:11)
要解压此数据,我使用两个不同的代码:
第一个以12位读取数据(因此我免费获得了一半的值),然后另一半工作。
fseek(fid, 0, 'bof');
raw = fread(fid, 2560*2160, 'ubit12');
raw(1:2:end) = arrayfun( ...
@(x) bitor(bitand(bitshift(x, 4), 4095), bitshift(x, -8)), ...
raw(1:2:end) ...
);
dat = reshape(raw, [2560, 2160]);
当逐字节读取数据时,第二种方法使用了更多的“标准”方法。
raw = fread(fid, ceil(2560*2160*1.5), 'ubit8');
dat = zeros(2560*2160, 1);
for i = 1:3:ceil(2560*2160*1.5)
p1 = bitor(bitshift(raw(i), 4), bitand(raw(i+1), 15));
p2 = bitor(bitshift(raw(i+2), 4), bitand(bitshift(raw(i+1), -4), 15));
dat(ceil(i/1.5)) = p1;
dat(ceil(i/1.5)+1) = p2;
end;
dat = reshape(dat2, [2560, 2160]);
尽管第二个要快得多(对我来说是令人惊讶的),但两者都非常慢。我确定可以通过向量化循环来加快速度,我只是不知道如何。
或者也许还有另一种解决方案,如何解压缩似乎很常见的数据。
顺便说一句,有人可以向我解释为什么数据以这种方式排序而不是“连续”吗?
谢谢
答案 0 :(得分:1)
for循环的矢量化版本:
dat(1:2:end) = bitor(bitshift(raw(1:3:end), 4), bitand(raw(2:3:end), 15));
dat(2:2:end) = bitor(bitshift(raw(3:3:end), 4), bitand(bitshift(raw(2:3:end), -4), 15));
我使用以下代码进行测试:
%Create input data for testing:
I = (0:4095)';
J = zeros(1, numel(I)*1.5);
%Byte 0: Pixel 1 (bits 4:11)
%Byte 1: Pixel 1 (bits 0:3), Pixel 2 (bits 0:3)
%Byte 3: Pixel 2 (bits 4:11)
J(1:3:end) = floor(I(1:2:end) / 16);
J(2:3:end) = mod(I(2:2:end), 16)*16 + mod(I(1:2:end), 16);
J(3:3:end) = floor(I(2:2:end)/16);
f = fopen('raw12.bin', 'w');
fwrite(f, J, 'uint8');
fclose(f);
len = numel(I);
fid = fopen('raw12.bin', 'r');
raw = fread(fid, len*1.5, 'ubit8');
dat = zeros(len, 1);
dat(1:2:end) = bitor(bitshift(raw(1:3:end), 4), bitand(raw(2:3:end), 15));
dat(2:2:end) = bitor(bitshift(raw(3:3:end), 4), bitand(bitshift(raw(2:3:end), -4), 15));
% for i = 1:3:len*1.5
% p1 = bitor(bitshift(raw(i), 4), bitand(raw(i+1), 15));
% p2 = bitor(bitshift(raw(i+2), 4), bitand(bitshift(raw(i+1), -4), 15));
% dat(ceil(i/1.5)) = p1;
% dat(ceil(i/1.5)+1) = p2;
% end
%%dat = reshape(dat2, [2560, 2160]);
fclose(fid);
%Verify dat = I
all(dat == I)