Вычитание вложенных массивов выдает ошибку памяти в MATLAB - PullRequest
0 голосов
/ 29 октября 2011

Я пытаюсь добиться очень простой вещи в MATLAB. У меня есть последовательность изображений в массиве 4D в следующем формате: (номер кадра, высота, ширина, RGB).

Мой стек довольно маленький, его размер: 99 480 640 3

То, чего я пытаюсь добиться, - это определить, было ли изменение движения между n последовательными изображениями (изображения, снятые неподвижной камерой вокруг движущихся объектов).

Для этого моей наиболее очевидной идеей является вычитание разных изображений в стеке и их сохранение в другом стеке.

Вот очень простой код, который я пытался запустить:

vec = 1:size(stack,1)-5
dif = uint8(squeeze(abs(stack(vec,:,:,:) - stack(vec+5,:,:,:))));

Однако из-за ошибки памяти.

Error using  - 
Out of memory. Type HELP MEMORY for your options.

Если я не использую сжатие (нужно ли здесь использовать сжатие?), Я даже получаю системную ошибку Windows по поводу нехватки памяти.

В качестве запасного варианта я написал цикл for, который, кажется, работает, но только если я использую приведение uint8. Если нет, ему не хватает памяти и системная ошибка Windows.

for i = 1:size(stack,1)-5   
    dif(i,:,:,:) = uint8(abs(stack(i,:,:,:) - stack(i+5,:,:,:)));
end

Кроме того, для обработки этого небольшого набора данных (всего 99 кадров) требуется 20 секунд.

Можете ли вы сказать мне, как мне написать функцию, которая не пытается сохранить все в памяти? Эта команда должна требовать очень мало памяти для сравниваемых двух изображений, однако MATLAB пытается делать все операции в памяти по какой-то причине. Весь набор данных должен занимать 91 МБ в памяти, поэтому это не должно быть проблемой.

Кроме того, вы можете объяснить, нужно ли мне использовать сжатие или нет? Когда я пытаюсь получить одно изображение, тогда

dif = stack(1,:,:,:) - stack(5,:,:,:);

создает массив 4D, а

dif = squeeze(stack(1,:,:,:) - stack(5,:,:,:));

создает формат изображения. Но в приведенном выше цикле for он дает одинаковые результаты как со сжатием, так и без него. Почему это происходит?

1 Ответ

2 голосов
/ 29 октября 2011

Что касается SQUEEZE, stack является 4-мерной матрицей, поэтому dif = stack(1,:,:,:) - stack(5,:,:,:); также является 4D-матрицей, но первое измерение одноэлементное.Поэтому, когда вы присваиваете результат в существующей матрице (с индексированием), элементы заполняются по порядку, и любые одноэлементные измерения не действуют.Однако, помещая результат в новую переменную, форма 4D-матрицы сохраняется ...

Вам следует знать о ваших типах данных, если все значения являются целыми числами в диапазоне [0,255], затем приведитевесь стек изображений как UINT8 для начала.Как я упоминал в комментариях, для четырехмерной двойной матрицы таких размеров потребуется около 700 МБ непрерывной памяти.

Теперь в цикле for вы должны предварительно выделить матрицу dif:

dif = zeros([99-5 480 640 3],'uint8');
for i = 1:size(stack,1)-5   
    dif(i,:,:,:) = abs( stack(i,:,:,:) - stack(i+5,:,:,:) );
end

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...