Matlab matrix interpolation with 4 known values - matlab

I have 4 known (corner) values of an matrix:
grid = [2 5
5 8];
This values are my corners and I want to interpolate between them, that I get a non-squared matrix, e.g. a 350x250 matrix.
I searched some familiar questions but I couldnt find a solution or wasnt able to transfer it to my problem. I found the interp2 function but not how to tell that I only have the 4 corner values?
I made an easy example to show what I need and what doesnt work (or what I am doing wrong):
test = [2 0 0 0 8
0 0 0 0 0
6 0 0 0 12 ];
[X, Y] = meshgrid(1:5,1:3);
M = interp2(X,Y,test,X,Y);
The resulting matrix is exactly the same as the input matrix test. How can I interpolate the zeros? In general my Input is only this:
grid = [2 8; 6 12];

After long thinking I found a solution:
x = 350;
y = 250;
V = [2 8
6 12];
[X, Y] = meshgrid(1:2,1:2);
a = linspace(1,2,x);
Xq = a(ones(1,y),:); % oder repmat([1 n], y);
b = linspace(1,2,y)';
Yq = b(:,ones(1,x));
M = interp2(X,Y,V,Xq,Yq);
I hope it helps anybody who has the same problem, I didnt understood that the final size is only in the last two parameters present.

Related

How to compute 1D convolution in Matlab?

Suppose I have 2 vectors, data vector:
x=[2 1 2 1]
and weights vector
y=[1 2 3]
I want Matlab to convolve these vectors in sense of 1D neural network, i.e. run y as window against x and compute convolutions:
If I run built-in function conv then I get
>> conv(x,y)
ans =
2 5 10 8 8 3
which contains correct values in the middle but has something unknown at margins. Manual for conv function looks completely different with what I want.
If I run
>> conv(x,y, 'same')
ans =
5 10 8 8
I also get something strange.
You were very close to solving it by specifying the 3rd input to conv, but instead of 'same' you should've used 'valid':
x = [2 1 2 1];
y = [1 2 3];
conv(x,y,'valid')
ans =
10 8
Just reverse the filter:
x = [2,1,2,1];
y = [1,2,3];
z = conv(x,flip(y),'valid');

Generation of cubic grid

I am trying to generate a cubic grid in Matlab so that I can produce a grid of M x N x Q cubes with M, N and Q being integer numbers. I don't need to plot it but rather to produce a B-Rep of the grid (vertex matrix and faces matrix - with no duplicate internal faces). I have tried two approaches:
Copy and translate points in the X, Y, Z direction, eliminate duplicate points and try to generate the new topology (I have no idea how).
Use the Matlab Neuronal Neural Network toolbox, specifically the gridplot function that produces a 3D grid of points but the faces matrix cannot be generated from this function.
Any suggestions?
Thank you.
Update
The vertex matrix contains all 8 points of each cube and the faces matrix all 6 faces of each cube. I can generate that with the following code:
clc
clear
fac = [1 2 3 4;
4 3 5 6;
6 7 8 5;
1 2 8 7;
6 7 1 4;
2 3 5 8];
vert_total = [];
face_total = fac;
for x = 0 : 1
for y = 0 : 1
for z = 0 : 1
vert = [1 1 0;
0 1 0;
0 1 1;
1 1 1;
0 0 1;
1 0 1;
1 0 0;
0 0 0];
vert(:,1) = vert(:,1) + x;
vert(:,2) = vert(:,2) + y;
vert(:,3) = vert(:,3) + z;
vert_total = [vert_total; vert];
face = face_total(end-5:end,:);
face_total = [face_total; face+8];
end
end
end
The problem with this code is that it contains duplicate vertex and duplicate faces. Eliminating the repeated vertex is pretty straightforward using the unique function, but I don't know how to handle the topology (faces matrix) when I eliminate the repeated points (obviously, some of the faces should be eliminated as well).
Any sugestions with that?
You can create the 3D grid, and then keep only those at 6 faces. Someone else may point a better way than this.
M = 5; N = 6; Q = 7;
[X, Y, Z] = ndgrid(1:M, 1:N, 1:Q); % 3D
faces = X==1 | X==M | Y==1 | Y==N | Z==1 | Z==Q;
X = X(faces);
Y = Y(faces);
Z = Z(faces);
Now [X Y Z] are coordinates for faces.

Singular value decomposition approximation

I was asked in school to do a SVD on the matrix:
A = [1 3 1 2;
0 2 1 4;
6 5 2 1]
and then: calculate an approximation of A called A_hat by setting the third singular value σ_3 to zero.
I have done the SVD, but I'm kind of clueless about the second part. Can somebody please help me?
Assuming MATLAB (or Octave):
A = [1 3 1 2;
0 2 1 4;
6 5 2 1];
[U,S,V] = svd(A);
S(3,3) = 0;
A_hat = U*S*V';
This gives:
A_hat =
1.37047 2.50649 1.03003 2.30320
-0.20009 2.26654 0.98378 3.83625
5.90727 5.12352 1.99248 0.92411

matlab - find indices of elements in x

I have a matrix x of size Nx2 (contains (x,y) coordinates) and a matrix c of size Px1 (P<=N) that contains certain x-coordinates which I'm interested in. For example:
x = [10 3; 21 9; 98 54; 4 30; 37 12];
c = [4 98];
I want to get the coordinates of the elements in c (in the above case [4 3]). How can I do this? I've only found a way when c is a 1x1 matrix (i.e. a scalar).
ismember can be used for testing membership of multiple values. You can slice the N-by-2 matrix to search only x-coordinates.
coords = [1 2; 3 4; 5 6; 7 8];
c = [3 7 99];
[v i] = ismember(c, coords(:, 1));
i =
[2 4 0]
i should contain the indices where values in c appear as the x-coordinate in coords, or a 0 if the element is not found.
If you have a recent version of Matlab, you can replace v with ~.

Getting all pixel coordinates of a vector inside a image

I have an intensity/greyscale image, and I have chosen a pixel inside this image. I want to send vectors starting from this pixel in all directions/angles, and I want to sum all the intensities of the pixels touching one vector, for all vectors.
After this step I would like to plot a histogram with the intensities on one axis and the angle on the other axis. I think I can do this last step on my own, but I don't know how to create these vectors inside my greyscale image and how to get the coordinates of the pixels a vector touches.
I previously did this in C++, which required a lot of code. I am sure this can be done with less effort in MATLAB, but I am quite new to MATLAB, so any help would be appreciated, since I haven't found anything helpful in the documentation.
It might not be the best way to solve it, but you can do it using a bit of algebra, heres how...
We know the Point-Slope formula of a line passing through point (a,b) with angle theta is:
y = tan(theta) * (x-a) + b
Therefore a simple idea is to compute the intersection of this line with y=const for all const, and read the intensity values at the intersection. You would repeat this for all angles...
A sample code to illustrate the concept:
%% input
point = [128 128]; % pixel location
I = imread('cameraman.tif'); % sample grayscale image
%% calculations
[r c] = size(I);
angles = linspace(0, 2*pi, 4) + rand;
angles(end) = [];
clr = lines( length(angles) ); % get some colors
figure(1), imshow(I), hold on
figure(2), hold on
for i=1:length(angles)
% line equation
f = #(x) tan(angles(i))*(x-point(1)) + point(2);
% get intensities along line
x = 1:c;
y = round(f(x));
idx = ( y<1 | y>r ); % indices of outside intersections
vals = diag(I(x(~idx), y(~idx)));
figure(1), plot(x, y, 'Color', clr(i,:)) % plot line
figure(2), plot(vals, 'Color', clr(i,:)) % plot profile
end
hold off
This example will be similar to Amro's, but it is a slightly different implementation that should work for an arbitrary coordinate system assigned to the image...
Let's assume that you have matrices of regularly-spaced x and y coordinates that are the same size as your image, such that the coordinates of pixel (i,j) are given by (x(i,j),y(i,j)). As an example, I'll create a sample 5-by-5 set of integer coordinates using MESHGRID:
>> [xGrid,yGrid] = meshgrid(1:5)
xGrid =
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
yGrid =
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
Next we can define a line y = m*(x - a) + b passing through the coordinate system by selecting some values for the constants and computing y using the x coordinates of the grid:
>> a = 0;
>> b = 1;
>> m = rand
m =
0.5469
>> y = m.*(xGrid(1,:)-a)+b
y =
1.5469 2.0938 2.6406 3.1875 3.7344
Finally, we find the y points in the grid that differ from the points computed above by less than the grid size:
>> index = abs(yGrid-repmat(y,size(yGrid,1),1)) <= yGrid(2,1)-yGrid(1,1)
index =
1 0 0 0 0
1 1 1 0 0
0 1 1 1 1
0 0 0 1 1
0 0 0 0 0
and use this index matrix to get the x and y coordinates for the pixels crossed by the line:
>> xCrossed = xGrid(index);
>> yCrossed = yGrid(index);