Как распаковать 12-битный номер «Mono12Packed» - PullRequest
1 голос
/ 18 октября 2019

У меня есть данные от датчика изображения (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]);

Несмотря на то, что второй способ намного быстрее (на удивление для меня), оба они ужасно медленные. Я уверен, что это может быть ускорено за счет векторизации цикла, я просто не знаю, как.

Или, может быть, есть другое решение, как распаковать такие данные, поскольку они кажутся довольно распространенными.

Кстати, кто-нибудь может мне объяснить, почему данные упорядочены таким образом, а не «подряд»?

Спасибо

1 Ответ

1 голос
/ 18 октября 2019

Векторизованная версия вашего цикла 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...