YUV video processing in Matlab - matlab

I am using this function I got from the internet:
>>[Y,U,V]=yuv_import('test.yuv',[176 144],150,0)
I got this from: Convert YUV CIF 4:2:0 video file to image files
It prints out the Y, U and V components of the yuv file test.yuv. When I typed:
>>Y
It displayed:
Y =
Columns 1 through 5
[144x176 double] [144x176 double] [144x176 double] [144x176 double] [144x176 double]
...............
Columns 146 through 150
[144x176 double] [144x176 double] [144x176 double] [144x176 double] [144x176 double]
And..
>>size(Y)
displayed:
ans =
1 150
Doing the same for U and V components also showed the same results.
And also..
>>Y(150)
displayed:
ans =
[144x176 double]
What I want is make an array for Y, U and V that has the dimensions [numberOfFrames height width] or [150 144 176]. How can I do this?

Your outputs are cell-arrays.
>> Y = cat(3, Y{:} );
should do the trick for you.

Related

cellarray of matrix multiplication vectorization

I have A and B a cell array of matrices inside. I want to obtain C
A =
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
B =
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
[18x18 double]
K = magic(18);
In for loop:
C = cell(8,1);
for ii = 1:8
C{ii} = K*A{ii}'*B{ii};
end
How can I do this in a vectorized form (cell)?
Although it's possible,
K = repmat({K}, 8,1);
C = spblkdiag(K{:}) * spblkdiag(A{:}).' * spblkdiag(B{:});
C = reshape(nonzeros(C), 18,[]);
C = mat2cell(C, 18,18 * ones(8,1))';
I'd still suggest you use a loop.

Assigning a value from a cell array to a numerical arrray

How to assign a value from a cell array to a numerical array efficiently? A and B are always square matrices of any size. For simplicity I just allocated small matrices. If for example A{1}=[2 3 8]; then I want allocate value 8 in second row and third column of the B matrix.
E.g.,
Input
A=[1x3 double] [1x3 double] [1x3 double] [1x3 double]
[1x3 double] [1x3 double] [1x3 double] [1x3 double]
[1x3 double] [1x3 double] [1x3 double] [1x3 double]
[1x3 double] [1x3 double] [1x3 double] [1x3 double]
B=zeros(4,4);
A{1}=[2 3 8];
A{2}=[3 4 7];
and so on...
Output
B(2,3)=8;
B(3,4)=7;
and so on...
Use spconvert:
B = full(spconvert(cat(1, A{:})));
You can do this without loops:
B=zeros(4,4);
A{1}=[2 3 8];
A{2}=[3 4 7];
C = cell2mat(A);
C = reshape(C,3,size(C,2)/3)';
indices = sub2ind(size(B), C(:,1), C(:,2));
B(indices) = C(:,3);
For your example this results in:
B =
0 0 0 0
0 0 8 0
0 0 0 7
0 0 0 0
Using sub2ind and indexing
%// creating a sample cell array. Replace this with your actual cell array
A = {[1 2 8] [1 1 4]; [2 1 5] [2 2 1]};
%// Reshaping the cell array to kx3 matrix
Amat = cat(1,A{:}); %// from luis' answer
%// taking first column as row sub, 2nd col as col sub
%// The subs are converted into linear indices to the size of A or B
ind = sub2ind(size(A),Amat(:,1),Amat(:,2));
%// You have done this (helps in fixing the dimensions of B)
B = zeros(size(A));
%// Taking last col of 'Amat' as values and assigning to corresponding indices
B(ind) = Amat(:,3);
Results:
>> B
B =
4 8
5 1
I would suggest looping once over the A cells to find the maximum index values, let's say max_i,max_j.
Then initialize B like:
B=zeros(max_i,max_j)
And loop again over the A cells and assign th values to the corresponding B elements.
Edit: Added example code:
max_i=0
max_j=0
for k=1:size(A,1)
for l=1:size(A,2)
max_i=max([A{k,l}(1),max_i])
max_j=max([A{k,l}(2),max_j])
end
B=zeros(max_i,max_j)
for k=1:size(A,1)
for l=1:size(A,2)
B(A{k,l}(1),A{k,l}(2))=A{k,l}(3)
end

matrix operation where the values can be expressed as a set

Is it possible to obtain a matrix as follows??
The input vectors are X(column vector) and Y(row vector)
X=[2 Y=[5 3 1 2 4]-1*5 vector
4
5
3
1]-5*1 vector
both vectors have the index values as elements. Now I want to have a 5*5 matrix which is as follows:
Z= (2,5) (2,3) (2,1) (2,2) (2,4)
(4,5) (4,3) (4,1) (4,2) (4,4)
(5,5) (5,3) (5,1) (5,2) (5,4)
(3,5) (3,3) (3,1) (3,2) (3,4)
(1,5) (1,3) (1,1) (1,2) (1,4)
Z-5*5 matrix
is it possible to obtain a matrix like this using matlab...pls help....i have no idea how to do this....thanks in advance...
Here's an alternative solution using a cell array instead of a regular array:
XX=meshgrid(X);
YY=meshgrid(Y);
C=reshape(num2cell([XX(:) YY(:)],2),numel(X),[]);
The outcome will be a 5x5 cell array,
C =
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
[1x2 double] [1x2 double] [1x2 double] [1x2 double] [1x2 double]
each element will contain the 2 numbers. For example:
C{2,2}
ans =
4 3
Maybe this is what you want:
Z = cat(3, repmat(X, 1, size(Y,2)), repmat(Y, size(X,1), 1));
This builds a 3D-array Z such that Z(m,n,:) gives the m,n entry of your "matrix".
However, depending on what you want to achieve, there are probably better ways to do it.

All possible Intersections of cells in cell array : MATLAB.

Consider a cell array ,
H = [ {N1x1} {N2x1} {N3x1} ...{Nmx1} ]
How does get (efficiently) all pairwise intersections of these cells?
Not sure how efficient this will be.
N = numel(H);
[ii jj] = ndgrid(1:N);
result = arrayfun(#(n) intersect(H{ii(n)},H{jj(n)}), 1:N^2, 'uni', 0);
result = reshape(result,N,N);
Example:
H = {[1 2 3], [2 3], [4 5]};
gives
result =
[1x3 double] [1x2 double] [1x0 double]
[1x2 double] [1x2 double] [1x0 double]
[1x0 double] [1x0 double] [1x2 double]
>> result{1,1}
ans =
1 2 3
>> result{1,2}
ans =
2 3
>> result{1,3}
ans =
Empty matrix: 1-by-0
[..]
This also works if H is a multidimensional cell array.
You could also use two for loops. Then you could save half operations explotiing the symmetry of the result.

Matlab: Randomize and Split

I have following data matrix in Matlab, I am trying to actually split this into multiple segments by passing a variable to a matlab function. But before splitting I would like to shuffle the matrix. The size of my matrix is 150X4
s.data
5.1000 3.5000 1.4000 0.2000
4.9000 3.0000 1.4000 0.2000
4.7000 3.2000 1.3000 0.2000
4.6000 3.1000 1.5000 0.2000
5.0000 3.6000 1.4000 0.2000
..
s =
data: [150x4 double]
labels: [150x1 double]
Coming from R environment I find MatLab is very strange. Initially I thought the columns in matrix has a relationshop like in a R dataframe but thats wrong in my assumption.
or you can do:
perm=randperm(numel(data)); % generate a random permutation
data = reshape(data(perm),size(data)); % apply it to data
new_data=data(randsample(1:length(data),length(data)),:)
Complementing the shuffle answers, in order to split your data into matrices of 15x2 each, you can use mat2cell:
data = rand(150,4); %# generates a random 150x4 matrix
rowdiv = repmat(15,1,10); %# size of each chunk in rows. Must sum to 150
coldiv = repmat(2,1,2); %# size of each chunk in cols. Must sum to 4
datacell = mat2cell(data, rowdiv, coldiv)
It will return a cell with 20 matrices, which are accessed by datacell{x,y}:
datacell =
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
[15x2 double] [15x2 double]
B = repmat(A,M,N) creates a large matrix B consisting of an M-by-N tiling of copies of A. We are using it here to generate an exact division of the rows and columns, repeating element 15 ten times and 2 twice, respectively. But, you don't need to do an exact division. You can set chunks with different sizes. Row with different size:
rowdiv =
15 15 15 15 15 15 15 15 16 14
Will return:
datacell =
[15x4 double]
[15x4 double]
[15x4 double]
[15x4 double]
[15x4 double]
[15x4 double]
[15x4 double]
[15x4 double]
[16x4 double]
[14x4 double]