I have used mat2cell to create a 12 x 13 x 5 cell matrix where each cell contains a 29 x 29 x 29 cube.
How do I generate a new 3D cell matrix containing only the central 21 x 21 x 21 cube of each 29 x 29 x 29 cube?
i.e. so the new matrix is still 12 x 13 x 5 but each one contains a 21 x 21 x 21 of central voxels of original cube?
To crop an indivual block, you can use a simple indexing expression:
c=4 % cut of c rows on each side.
for ix=1:numel(X)
X{ix}=X{ix}(1+c:end-c,1+c:end-c,1+c:end-c);
end
If you are aiming for a solution with a better Performance, I recommend switching to multi dimensional matrices:
c=4
Y=reshape(X,29,12,29,13,29,5);
%now the first block is squeeze(Y(:,1,:,1,:,1))
%now cut to smaller blocks:
Y=Y(1+c:end-c,:,1+c:end-c,:,1+c:end-c,:);
Related
Hello I'm working with MATLAB and I have a "z" column vector that has dimension of (9680 x 1). I want to reshape it in order to have an array "z" of dimension (44 x 220). I'm doing the following:
z=reshape(z,44,220);
I also tried:
z=reshape(z,[44,220]);
But the output is not right (at least the first row). I can see it by comparing the output matrix with the initial vector.
I just need the 220 first positions of the column vector to be the length of the first row of the matrix, then the next 220 positions of the vector to be the second row of the matrix and so on till obtaining 44 rows.
What am I doing wrong? Thanks for your help.
Matlab stores the matrix values in column major format (this is important during reshape). Since you want row major, you need to do
z = reshape(z, [220 44]).';
i.e. transpose afterwards.
I'd use Andreas H.'s approach.
As an alternative, there's a vec2mat function in the Communications Toolbox that does just that, and even fills missing values if needed:
>> x = 11:18;
>> vec2mat(x,4) %// no padding needed
ans =
11 12 13 14
15 16 17 18
>> vec2mat(x,5) %// padding needed; with 0 by default
ans =
11 12 13 14 15
16 17 18 0 0
>> vec2mat(x,5,-1) %// padding needed; with specified value
ans =
11 12 13 14 15
16 17 18 -1 -1
I have a matrix and i want to consider it has 4 sub matrices which are placed together. How can I find the middle element of each sub matrix when they are together?
consider the matrix below. It is built by 4 sub matrices.
1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36
I want to get their middle elements so i could have:
8, 11, 26, 29
From what I have understood this might work for you and this is a demo, so use your own parameters -
Code
%%// Input matrix
A = rand(44,44);
%%/ Number of submatrices needed
num_submat = 16;%%// 4 for your example case
%%/ Number of submatrices along row and column
num_submat1= sqrt(num_submat);
%%// Middle element indices along each direction
v1 = floor(size(A,2)/(2*num_submat1))+1:size(A,2)/(num_submat1):size(A,2);
%%// Middle elements
middle_ele = A(v1,v1)
It is always helpful to know that matrix indexing in matlab goes columnwise eg,
indOrd = [1,4,7;2,5,8;3,6,9]
where the number is the index order and not related to your example. indOrd(4) would return 4. Try to use this to find the index locations.
Assuming that each submatrix has odd size 2n+1, the coordinates of the center of one submatrix alone are [n+1, n+1]. If your have a square with M*M submatrices (M=2 in your case), the coordinates are [n+1+i*(2*n+1), n+1+j*(2*n+1)], i and j taken independently in the range 0:M-1.
Turning back to Matlab, it is now quite easy to generate all indices of the centers of the submatrices grouped in the matrix A:
n = floor(size(A,1)/(2*M));
xc = n+1+reshape(repmat(0:M-1,M,1),[],1);
yc = n+1+reshape(repmat((0:M-1)',1,M),[],1);
centers = A(yc, xc);
For even-sized submatrix, you have to choose which element is the center, the modification is quite easy to do then.
nodes = [0 1 2 3 4 4 3 7 7 2 10 11 11 10 14 14 1 17 18 19 19 18 22 22 17 25 26 26 25 29 29]; This is the standard plot for a depth 4 tree. It is in a loop, and gets drawn 10 times. Now, each of these 10 times some numerical computations are done and different numbers are come up with. These numbers all point to some word tags in a main array. Each time these numbers change, the words indexed also change, and I already know how they are to be placed in the tree. How do I label the tree with these strings then ?
I guess, the general question is how to label a tree with a bunch of strings?
A bit of a hack is to look at plotted points and, assuming they have a 1-1 correspondence with the nodes in your vector, use their coordinates to plot text.
treeplot([0 1 1]); % plot your tree
c = get(gca, 'Children'); % get handles to children
% grab X and Y coords from the second child (the first one is axes)
x = get(c(2), 'XData');
y = get(c(2), 'YData');
Now you can plot whatever at these coordinates. If labels is a cell array of labels, then you can display them next to the nodes as follows:
text(x, y, labels, 'VerticalAlignment','bottom', ...
'HorizontalAlignment','right')
While using MATLAB 2D filter funcion filter2(B,X) and convolution function conv(X,B,''), I see that the filter2 function is essentially 2D convolution but with a rotation by 180 degrees of the filter coefficients matrix. In terms of the outputs of filter2 and conv2, I see that the below relation holds true:
output matrix of filter2 = each element negated of output of conv2
EDIT: I was incorrect; the above relation does not hold true in general, but I saw it for a few cases. In general, the two output matrices are unrelated, due to the fact that 2 entirely different kernels are obtained in both which are used for convolution.
I understand how 2D convolution is performed. What I want to understand is the implication of this in image processing terms. How do I visualize what is happening here? What does it mean to rotate a filter coefficient matrix by 180 degrees?
I'll start with a very brief discussion of convolution, using the following image from Wikipedia:
As illustrated, convolving two 1-D functions involves reflecting one of them (i.e. the convolution kernel), sliding the two functions over one another, and computing the integral of their product.
When convolving 2-D matrices, the convolution kernel is reflected in both dimensions, and then the sum of the products is computed for every unique overlapping combination with the other matrix. This reflection of the kernel's dimensions is an inherent step of the convolution.
However, when performing filtering we like to think of the filtering matrix as though it were a "stencil" that is directly laid as is (i.e. with no reflections) over the matrix to be filtered. In other words, we want to perform an equivalent operation as a convolution, but without reflecting the dimensions of the filtering matrix. In order to cancel the reflection performed during the convolution, we can therefore add an additional reflection of the dimensions of the filter matrix before the convolution is performed.
Now, for any given 2-D matrix A, you can prove to yourself that flipping both dimensions is equivalent to rotating the matrix 180 degrees by using the functions FLIPDIM and ROT90 in MATLAB:
A = rand(5); %# A 5-by-5 matrix of random values
isequal(flipdim(flipdim(A,1),2),rot90(A,2)) %# Will return 1 (i.e. true)
This is why filter2(f,A) is equivalent to conv2(A,rot90(f,2),'same'). To illustrate further how there are different perceptions of filter matrices versus convolution kernels, we can look at what happens when we apply FILTER2 and CONV2 to the same set of matrices f and A, defined as follows:
>> f = [1 0 0; 0 1 0; 1 0 0] %# A 3-by-3 filter/kernel
f =
1 0 0
0 1 0
1 0 0
>> A = magic(5) %# A 5-by-5 matrix
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
Now, when performing B = filter2(f,A); the computation of output element B(2,2) can be visualized by lining up the center element of the filter with A(2,2) and multiplying overlapping elements:
17*1 24*0 1*0 8 15
23*0 5*1 7*0 14 16
4*1 6*0 13*0 20 22
10 12 19 21 3
11 18 25 2 9
Since elements outside the filter matrix are ignored, we can see that the sum of the products will be 17*1 + 4*1 + 5*1 = 26. Notice that here we are simply laying f on top of A like a "stencil", which is how filter matrices are perceived to operate on a matrix.
When we perform B = conv2(A,f,'same');, the computation of output element B(2,2) instead looks like this:
17*0 24*0 1*1 8 15
23*0 5*1 7*0 14 16
4*0 6*0 13*1 20 22
10 12 19 21 3
11 18 25 2 9
and the sum of the products will instead be 5*1 + 1*1 + 13*1 = 19. Notice that when f is taken to be a convolution kernel, we have to flip its dimensions before laying it on top of A.
I have a matrix say:
Q = [05 11 12 16 25;
17 18 02 07 10;
04 23 20 03 01;
24 21 19 14 09;
06 22 08 13 15]
I would like to list out all the possible 3x3 matrices. Some examples are:
11 12 16;
18 2 7;
23 20 3
and
5 11 12;
17 18 2;
4 23 20;
etc.. Basically all the possible 3-by-3 matrices.
How do I do it? I must use a for loop?
If you have the Image Processing Toolbox, you can use the function IM2COL:
subMats = im2col(Q,[3 3]);
Each column of subMats contains the elements of a 3-by-3 matrix extracted from Q. Each of these columns can be reshaped into a 3-by-3 matrix as follows:
Q1 = reshape(subMats(:,1),[3 3]); %# Reshape column 1 into a 3-by-3 matrix
I'm guessing this is homework (if not, please forgive me), so here are some hints.
Draw out the structure of your 5x5 matrix.
Start in the upper left and draw a 3x3 submatrix within that 5x5. What are the elements covered by that matrix?
Go to the upper right. What elements are covered there?
Now go to the lower left. What about there?
Do you see how to cover the whole thing?