Как разделить изображение на блоки в MATLAB?
У меня есть изображение 256x256, и я хочу разделить его на 4 блока по 128x128 каждый и адресовать их как A1-A4. Теперь я хочу называть их отдельно и выполнять некоторые операции над ними. Я знаю, что это можно сделать с помощью функции blkproc
, но как именно?
Я называю blkproc
следующим образом:
B=blkproc(I,[4 4],?)
Что мне помещать вместо "?", и как я могу адресовать 4 созданных блока?
Ответы
Ответ 1
Так как blockproc
(и устаревшие blkproc
) являются обеими функциями в Image Processing Toolbox, я подумал, что добавлю базовое решение MATLAB, которое не требует дополнительных панелей инструментов...
Если вы хотите разделить матрицу на подматрицы, один из способов - использовать mat2cell
, чтобы разбить матрицу вверх и сохранить каждую подматрицу в ячейке массива ячеек. Для вашего случая синтаксис будет выглядеть следующим образом:
C = mat2cell(I, [128 128], [128 128]);
C
теперь представляет собой массив ячеек 2 на 2, причем каждая ячейка хранит подматрицу 128 на 128 I
. Если вы хотите выполнить операцию в каждой ячейке, вы можете использовать функцию cellfun
. Например, если вы хотите принять среднее значение значений в каждой подматрице, вы должны сделать следующее:
meanValues = cellfun(@(x) mean(x(:)), C);
Первым аргументом является дескриптор функции в анонимная функция, который сначала преобразует каждую подматрицу в вектор-столбец, а затем принимает среднее значение. Вывод представляет собой матрицу 2 на 2 для средних значений для каждой подматрицы. Если функция, которую вы передаете на cellfun
, создает выходные данные разных размеров или типов для каждой ячейки, тогда cellfun
будет иметь проблемы с конкатенацией и будет вызывать ошибку:
??? Error using ==> cellfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.
Если вы добавите ..., 'UniformOutput', false);
в конец вашего вызова к cellfun
, то вывод в приведенном выше случае вместо этого будет массивом ячеек 2 на 2, содержащим результаты выполнения операции на каждой подматрице.
Ответ 2
blockproc
- новое имя blkproc
(которое устарело). Его можно использовать для применения функции к каждому блоку изображения. Например, если вы хотите разделить матрицу я на блоки 8x8 и вычислить среднее значение для каждого блока, вы сделаете следующее:
B=blockproc(I, [8 8], @(x) mean(x.data(:)));
B - это матрица, содержащая средства блоков.
Здесь можно отметить две вещи:
-
Спецификатор [8 8]
определяет размер блоков, а не количество блоков.
-
Вы не получаете доступ к самим блокам вне функции, которую вы передаете blockproc
. Если вам нужны сами блоки, вы должны сделать то, что предложил Адриен:
A1=I(1:128, 1:128);
A2=I(129:256, 1:128);
A3=I(1:128, 129:256);
A4=I(129:256, 129:256);
Конечно, в реальной программе вы должны, вероятно, сделать это, используя цикл.
Ответ 3
Если myImage
- ваше изображение 256x256, не будет ли оно
image_top_left = myImage(1:128,1:128);
image_top_right = myImage(1:128,129:256);
image_bottom_left = myImage(129:256,1:128);
image_bottom_right = myImage(129:256,129:256);
?
Ответ 4
Это лучше для вас, чтобы ваша программа работала для всех размеров изображений не только для 256 * 256.
[row, col]=size(your_image);
mr = round(row/2); % median of rows
mc = round(col/2); % median of columns
% Now divide your image and call each of them separately and do what ever you want
top_left = your_image(1:mr , 1:mc);
top_right = your_image(1:mr , (mc+1):col);
bot_left = your_image((mr+1):row , 1:mc);
bot_right = your_image((mr+1):row , (mc+1):col);
% final stage is to combining these parts again to return to its original shape
Back_to_original = [top_left,top_right ; bot_left,bot_right];
% надеюсь, что это будет полезно для вас.