Я относительно новичок в Matlab и обработке изображений, поэтому, пожалуйста, потерпите меня.
Я пытаюсь охарактеризовать шум в изображении, в частности, путем усреднения fft области, где этот шум возникает с высокой вероятностью.
img = img(1:40,1:100)
imshow(img);
ffts = blockproc(img, [20 20], @(block_struct) fftshift(fft2(block_struct.data)));
// fft = imresize(ffts, [40 100], 'nearest');
По сути, этот код берет верхнюю левую часть изображения размером 40 x 100, а затем выполняет блочную обработку для каждой части 20 x 20 этой области, вычисляя fft2. Надеюсь, моя логика пока звучит хорошо.
Что мне интересно, так это то, есть ли способ выполнить средний fft2 из 20 x 20 частей матрицы 40 x 100 fft с помощью встроенной функциональности Matlab. Я знаю, что это можно сделать относительно легко с помощью циклов, но я хотел бы, чтобы решение в моем коде было как можно более компактным.
Я немного прочитал руководство и очевидно, что есть пара функций Matlab, которые могут это сделать; Однако я пока не совсем уверен в своей заявке. Приветствуются любые направления!
1 ответ
Это легко сделать в 3 строчки кода.
Линия 1
Сначала используйте im2col
, чтобы изменить форму каждой отдельной окрестности блока 20 х 20 в один столбик. Таким образом, на выходе будет матрица 400 x N
, где каждый столбец обозначает уникальную окрестность блока, которая была преобразована в столбец. В каждом столбце будет 400 строк, так как в каждой окрестности 400 элементов (20 x 20
). N
будет общим количеством уникальных блоков в вашем изображении 40 x 100
. Это составит 10, так как мы можем уместить 2 блока по горизонтали и 5 блоков по вертикали, учитывая требование 20 x 20
.
Строка # 2
Что хорошо в выводе im2col
, так это то, что i th строка im2col
сообщает вам i th элемент для каждого блока вашего изображения. Таким образом, все, что вам нужно сделать, это взять каждую строку и получить среднее значение по всем столбцам . На выходе будет вектор 400 x 1
, который обозначает ваше среднее значение БПФ для всех блоков. Этого можно добиться, используя mean
и указав, что мы хотите усреднить по второму измерению (второй параметр - 2
), то есть по столбцам.
Строка № 3
Затем нам нужно преобразовать это обратно в матрицу 20 x 20
, поэтому используйте reshape
для этого. Мы указываем, что выходной матрицей является 20 x 20
, учитывая вектор элементов 400 x 1
.
Один вопрос, который вы можете задать, заключается в том, гарантирует ли это переупорядочение правильное переупорядочение нашего блока БПФ. Это гарантировано, потому что, когда im2col
построил каждый блок в столбец, он продвигается в порядке основного столбца . Это означает, что для одного столбца блоков мы строим их построчно. Как только мы получаем наш набор отдельных блоков 20 x 20
, эти блоки располагаются таким образом, что они выбираются в порядке возрастания столбцов. Это означает, что из одного блока 20 x 20
создается вектор-столбец 400 x 1
, где столбцы блока 20 x 20
накладываются друг на друга слева направо. Следовательно, выполняя mean
и reshape
, пространственные положения для каждого блока действительно соответствуют друг другу и, таким образом, дадут правильный ответ.
Без лишних слов, вот код:
colBlocks = im2col(ffts, [20 20], 'distinct'); %// Line 1
meanCol = mean(colBlocks, 2); %// Line 2
fftBlockAverage = reshape(meanCol, [20 20]); %// Line 3
Незначительный побочный эффект
Поскольку БПФ является комплексным по своей природе, выполняя усреднение, вы усредняете реальную и мнимую составляющие отдельно. Вот как MATLAB обрабатывает среднее значение комплексных данных. Я не уверен, какой анализ вы будете выполнять после вычисления среднего блока 2D БПФ, но имейте это в виду, прежде чем продолжить свой анализ.
Примечание
Divakar в предыдущем ответе создал более эффективную реализацию im2col
. Это особенно полезно, если у вас не установлен Image Processing Toolbox. Вы можете проверить эту реализацию здесь. Было показано, что время между этой функцией и im2col
MATLAB на порядок быстрее.
Бенчмаркинг
В качестве бонуса вот тест с использованием его кода. Результаты измерения времени были получены с использованием матрицы 40 x 100
, в которой встроенная функция im2col
была рассчитана по времени, а пользовательская функция Divakar - после. Результаты показывают, что его метод быстрее. Это может быть очень полезно при рассмотрении изображений большего размера. Однако, если вы ищете лаконичности, используйте то, что я написал. Если вы хотите чего-то быстрого, воспользуйтесь его методом.
Код сравнения
%// Input Parameters
nrows = 20;
ncols = 20;
A = rand(40,100);
disp('------------------------- With IM2COL');
tic
B1 = im2col(A,[nrows ncols],'distinct');
toc,clear B1
disp('----------------- With CUSTOM-BUILT IM2COL');
tic
B2 = im2col_distinct(A,[nrows ncols]);
toc,clear B2
Результаты
------------------------- With IM2COL
Elapsed time is 0.026914 seconds.
----------------- With CUSTOM-BUILT IM2COL
Elapsed time is 0.004186 seconds.
im2col
и если производительность во время выполнения важна, позвольте мне предложить ему альтернативу - stackoverflow.com/a/25454746/3293881, что показалось быстрее на нескольких тестах, которые мне удалось выполнить.
Похожие вопросы
Связанные вопросы
Новые вопросы
image
Тег изображения предназначен для вопросов, связанных с загрузкой, форматированием, сохранением, сжатием и отображением изображений в контексте исходного кода. Этот тег также следует использовать для помощи при использовании различных библиотек изображений. Вопросы о конкретных форматах изображений должны включать теги для этих форматов. Включите теги, чтобы указать, относится ли вопрос к конвертации, обработке и т. Д.
20 x 20
теперь, когда вы вычислили все20 x 20
2D БПФ изображения?