Получить матрицу, состоящую из каждого квадрата - PullRequest
0 голосов
/ 09 января 2019

Я хочу получить матрицу, состоящую из каждого квадрата 3х3 в матрице. Матрица представляет собой # канал по m на n. Конечным результатом является матрица размером #channels x (size1-2)*(size2-2) x 9. Я могу сделать это не векторным способом с помощью следующего кода:

clear
size1 = 10;
size2 = 10;
matrix = 1:size1*size2;
matrix =reshape(matrix,[size1 size2]);
matrix_withdraw = 1:(88*size1*size2);
matrix_withdraw = reshape(matrix_withdraw,[88 size1 size2]);
tic
iter = 1;
for ii = 1:size1-2
    for jj = 1:size2-2
        locs(ii,jj,:,:) = matrix(ii:ii+2,jj:jj+2);
        method1(:,iter,:) = reshape(matrix_withdraw(:,ii:ii+2,jj:jj+2),[88,9]);
        iter = iter+1;
    end
end
locs = permute(locs,[3 4 1 2]);

Это очевидно довольно медленно для больших размеров матриц. Я хочу векторизовать это. Мне удалось получить решение, которое работает, но оно не очень чистое

locs2 = ones(size1*(size2-2),1)+(0:size1*(size2-2)-1)';
temp = 1:size1*(size2-2);
temp = mod(temp,size1);
temp = (temp>(size1-2)) | (temp==0);
locs2(temp,:) = [];
locs3 = reshape(locs2,[1 1 (size1-2) (size2-2)]);
locs3(2,1,:,:) = reshape(locs2+1,[1 1 (size1-2) (size2-2)]);
locs3(3,1,:,:) = reshape(locs2+2,[1 1 (size1-2) (size2-2)]);
locs3(:,2,:,:) = locs3(:,1,:,:)+size1;
locs3(:,3,:,:) = locs3(:,2,:,:)+size1;
locs3 = permute(locs3,[1 2 4 3]);
locs3 = vec(locs3);
method2 = matrix_withdraw(:,locs3);
method2 = reshape(method2,[88,9,64]);
method2 = permute(method2,[1 3 2]);

Method1 и method2 эквивалентны и дают одинаковые результаты. Метод2 также в 10 раз быстрее, чем метод1. У меня вопрос, есть ли более чистый способ сделать это?

1 Ответ

0 голосов
/ 09 января 2019

Если у вас есть набор инструментов для обработки изображений, вы можете использовать im2col, чтобы получить каждый блок в виде столбца, а затем reshape в качестве 4-D массива:

blockSize = [3 3];
locs = reshape(im2col(matrix, blockSize), [blockSize size(matrix)-blockSize+1]);

Или вы можете сделать это напрямую, создав 4-D индексный массив, используя неявное одноэлементное расширение . Для этого не требуется никаких наборов инструментов:

m = 3; n = 3; % block size
[M, N] = size(matrix);
ind = (1:m).'+(0:n-1)*M + reshape(0:M-m, 1, 1, []) + reshape((0:N-n)*M, 1, 1, 1, []);
locs = matrix(ind);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...