Распределение функции по единственному размеру массива в MATLAB?

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

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

img = imread('whatever.jpg');
s = size(img);
for i=1:s(1)
  for j=1:s(2)
    bw_img(i,j) = mean(img(i,j,:));
  end
end

Я хотел бы выразить это как что-то как:

bw = on(color, 3, @mean);

или

bw(:,:,1) = mean(color);

Существует ли короткий способ сделать это?


Править: По-видимому, mean уже делает это; я хочу смочь сделать это для любой функции, которую я записал. Например,
...
  filtered_img(i,j) = reddish_tint(img(i,j,:));
...

где

function out = reddish_tint(in)
  out = in(1) * 0.5 + in(2) * 0.25 + in(3) * 0.25;
end
7
задан gnovice 12 May 2017 в 05:12
поделиться

4 ответа

Многие основные функции MATLAB, такие как MEAN, MAX, MIN, SUM и т. д., предназначены для работы в определенном измерении:

bw = mean(img,3);  %# Mean across dimension 3

Вы также можете воспользоваться тем фактом, что Арифметические операторы MATLAB предназначены для работы в поэлементном виде на матрицах. Например, операция в вашей функции reddish_tint может быть применена ко всем пикселям вашего изображения с помощью этой одной строки:

filtered_img = 0.5.*img(:,:,1)+0.25.*img(:,:,2)+0.25.*img(:,:,3);

Чтобы обработать более общий случай, когда вы хотите применить функцию к произвольному размеру N-мерной матрицы, вы, вероятно, захотите написать свою функцию так, чтобы она принимала дополнительный входной аргумент для того, с каким измерением работать (как это делают вышеупомянутые функции MATLAB) и затем использует некоторую простую логику (т.е. операторы if-else) и элемент-мудрые матричные операции для применения ее вычислений к правильному размеру матрицы.

Хотя я бы не предлагал его использовать, есть быстрое и грязное решение, но оно довольно уродливое и вычислительно более дорогое. Вы можете использовать функцию NUM2CELL для сбора значений вдоль размерности массива в ячейки массива ячеек, а затем применить свою функцию к каждой ячейке с помощью функции CELLFUN:

cellArray = num2cell(img,3);  %# Collect values in dimension 3 into cells
filtered_img = cellfun(@reddish_tint,cellArray);  %# Apply function to each cell
7
ответ дан 6 December 2019 в 08:14
поделиться

Если вы постоянно пытаетесь применить функцию к вектору, состоящему из трех измерений в блоке изображений, я рекомендую использовать пару reshapes, например:

Img = rand(480,640,3);

sz = size(Img);
output = reshape(myFavoriteFunction(reshape(Img,[prod(sz(1:2)),sz(3)])'),sz);

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

edit. Приведенный выше код будет аварийно завершен, если вы введете изображение, имеющее только один слой: Функция ниже может исправить это.

function o = nLayerImage2MatrixOfPixels(i)
%function o = nLayerImage2MatrixOfPixels(i)
s = size(i);
if(length(s) == 2)
  s3 = 1;
else
  s3 = s(3);
end
o = reshape(i,[s(1)*s(2),s(3)])';
3
ответ дан 6 December 2019 в 08:14
поделиться

Ну, если вас интересует только умножение векторов, вы можете просто использовать точечное произведение, например, так:

bw(:,:,1)*[0.3;0.2;0.5]

заботясь о том, чтобы формы ваших векторов соответствовали.

2
ответ дан 6 December 2019 в 08:14
поделиться

Вы можете использовать BSXFUN по крайней мере для некоторых задач. Она выполняет поэлементную операцию среди двух массивов, расширяя размер 1 - размера до соответствия размеру в другом массиве. Функция 'reddish tint' станет

reddish_image = bsxfun(@times,img,cat(3,0.5,0.25,0.25));
filtered_img = sum(reddish_image,3);

Все, что требуется для работы вышеприведенного утверждения, это чтобы третье измерение img имело размер 1 или 3. Количество и размер других измерений можно выбирать произвольно.

4
ответ дан 6 December 2019 в 08:14
поделиться
Другие вопросы по тегам:

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