МАТЛАБ:Извлеките несколько частей матрицы без использования циклов

StackOverflow https://stackoverflow.com/questions/906077

  •  05-09-2019
  •  | 
  •  

Вопрос

У меня огромная 2D-матрица, и я хотел бы извлечь из нее 15 различных частей размером 100x100.У меня есть два вектора x и y, в которых сохраняются верхние левые индексы частей.Я использовал что-то вроде этого:

result = cam1(x(1:end):(x(1:end)+99), y(1:end):(y(1:end)+99));

но в результате получается просто матрица 100x100 вместо 15x100x100.Почему?

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

Есть ли у вас какое-нибудь элегантное решение?Спасибо.

Это было полезно?

Решение

Есть несколько способов сделать это без циклов.Большинство решений предполагают расширение векторов Икс и й в более крупные матрицы индексов и, вероятно, будет использовать одну или несколько функций РЕПМАТ, BSXFUN, или СУБ2ИНД.Хороший учебник по индексации матрицы можно найти здесь.

Однако, поскольку вы попросили элегантный решение, вот оно несколько необычное.Оно использует анонимные функции а также функции МАССИВFUN и КОТ:

indexFcn = @(r,c) cam1(r:(r+99),c:(c+99));
result = arrayfun(indexFcn,x,y,'UniformOutput',false);
result = cat(3,result{:});

ОБЪЯСНЕНИЕ:

Первая строка создает анонимная функция.Это простая однострочная функция, которую можно создать «на лету», без необходимости помещения ее в m-файл.Функция определяет два входа р и с которые используются для извлечения подматрицы 100х100 из камера 1.Переменная индексFcn хранит указатель функции который используется для вызова функции.Обратите внимание, что значения камера 1 используемые анонимной функцией, статический.Даже если значения переменной камера 1 измениться, анонимная функция по-прежнему использует значения, которые были в камера 1 когда функция была создана.

Вторая строка вызывает ARRAYFUN, который применяет функцию к каждому элементу массива.ARRAYFUN перебирает каждую запись в Икс и й, передавая значения в индексFcn.Вывод сохраняется в результат, массив ячеек из 15 элементов, где каждая ячейка содержит матрицу размером 100 на 100.

Третья строка использует функцию CAT для объединения матриц размером 100 на 100 в матрицу размером 100 на 100 на 15.

Другие советы

Поскольку это, очевидно, домашнее задание, я не дам вам полного ответа.

Существует несколько способов индексации в матрице.Если у вас есть набор разбросанных индексов, вам нужно использовать один индекс.Таким образом, если

A = rand(5,6)
A =
      0.81472      0.09754      0.15761      0.14189      0.65574      0.75774
      0.90579       0.2785      0.97059      0.42176     0.035712      0.74313
      0.12699      0.54688      0.95717      0.91574      0.84913      0.39223
      0.91338      0.95751      0.48538      0.79221      0.93399      0.65548
      0.63236      0.96489      0.80028      0.95949      0.67874      0.17119

A(3:4,3:4)

даст подматрицу 2x2 из A.Но мы также можем найти эту подматрицу как

reshape(A([13 14 18 19]),[2 2])
ans =
      0.95717      0.91574
      0.48538      0.79221

Почему я выбрал этот набор индексов?Для ответа вам нужно будет прочитать о sub2ind.

[I,J] = ndgrid(3:4,3:4);
sub2ind([5 6],I(:),J(:))
ans =
    13
    14
    18
    19

В конце концов, похоже, вам нужен массив 15x100x100 из извлеченных частей.Итак, создайте необходимый массив индексов из частей, которые я показал.В конце вам нужно будет окончательно изменить форму, чтобы придать ей правильную форму.

Этого должно хватить для того, чтобы закончить домашнее задание.

Вы думаете, что все слишком сложно, попробуйте это:mat2cell

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top