Более быстрая версия dec2bin функционирует для преобразования многих элементов?

Я читаю растровый файл и преобразовываю каждое из значений RGB в пределах от от 0 до 255 к двоичному файлу.

Таким образом, битовый массив 240 на 320 будет иметь 230 400 значений RGB для преобразования. Исходная dec2bin функция была слишком медленной, таким образом, я записал свое собственное, поскольку я знаю, что мое значение всегда будет между от 0 до 255.

Но прохождение через 230 400 значений все еще займет приблизительно 6 секунд на моей машине, и единственный цветной битовый массив займет приблизительно 2,3 секунды.

Там должен так или иначе ускорить вещи быть младше 1 секунды или еще лучших 0,5 секунд, поскольку каждый msec значит мое приложение?

Вот мой код:

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++. Действительно ли это желательно?

Спасибо.

8
задан Amro 28 August 2012 в 13:58
поделиться

4 ответа

Еще более быстрый способ - использовать таблицы поиска. Поскольку вы знаете, что все значения имеют интенсивность от 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 
10
ответ дан 5 December 2019 в 12:10
поделиться

Разве вы не можете использовать bitand для получения битов напрямую?

s(0) = 256 bitand input
s(1) = 128 bitand input
s(2) = 64 bitand input

и т. Д.

0
ответ дан 5 December 2019 в 12:10
поделиться

Вариант №1: Перебрать каждый пиксель и использовать BITGET

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

Вариант № 2: Векторизованное решение с BITGET

Можно создать векторизованное решение, в котором вы перебираете каждый бит вместо каждого пикселя , выполняя операцию 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-мерной (n-на-m) или 3-мерной (n-на-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
4
ответ дан 5 December 2019 в 12:10
поделиться

This kind of problem (perform a per-element operation on a large array, because Matlab's built-in code is too slow) sometimes calls for a solution in Java, since Matlab runs on a JRE and converting/passing array arguments is usually a fairly fast operation.

gnovice's solution sounds like it works for you, but if you run into a situation you can't solve in pure Matlab, and you're proficient in Java, consider writing a custom JAR file. It's pretty easy. (well, a whole lot easier than trying to interface C++ to Matlab!)

0
ответ дан 5 December 2019 в 12:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: