Deconvolution of sound using matlab - matlab

[y,fs]=wavread('C:\Users\Mohamed\Desktop\sinesweeprec.wav')
[x,fs]=wavread('C:\Users\Mohamed\Desktop\sinesweep.wav')
a=fft(x)
b=fft(y)
h=ifft(b/a)
So I use this code in order to get the impulse response of a room but I get this error ('Error using / Matrix dimensions must agree')
can someone please help and how to solve it.

You might want to do ./ to do per element division.
h = ifft(b./a)
Remember in 2D, if you do matrix multiplication:
3x4 * 4x3 = 3x3 matrix. And a 3x4 * 3x4 isn't possible, but you could to a per pixel multiplication to have 3x4 .* 3x4 = 3x4

Related

Matrix multiplication using sym function error in MATLAB

When multiplied A = eye(3,3) with x = sym('x',[3,3]) as in this form (A.*x), I got a result. But when multiply A = eye(3,3) with y = sym('y',[3,2]) I got an error while from the matrix multiplication point of view it is correct. Why it is so?
.* is not matrix multiplication, it is element-wise multiplication. You want to do A*x.

Vectorize Matrix and vector operation in Matlab

I'm trying to vectorize the following code in Matlab. I've never had to vectorize with a matrix involved. Doing some research it seems I should use bsxfun but I'm having a hard trying to understand how it works in my example. I've tried a few things but can't seem to figure it out. Below is the non-vectorized code that runs and produces the output I want.
# W is 500 x 100 matrix
# delta is 100 x 1 vector
# alpha is scalar
for i = 1: 100
W(:,i) = W(:, i) - (alpha * delta(i));
end
Any help is appreciated! Thanks.
Easy with bsxfun:
W = bsxfun(#minus, W, alpha*delta.');
This works as follows: delta is transformed into a row vector (.') and multiplied by the scalar alpha. The obtained row vector is subtracted from each row of W using bsxfun. You can view bsxfun as an "implicit repmat": it replicates the row alpha*Delta.' as many times as needed to match the size of W; and then it does the subtraction (#minus).

Calculating the essential matrix from two sets of corresponding points

I'm trying to reconstruct a 3d image from two calibrated cameras. One of the steps involved is to calculate the 3x3 essential matrix E, from two sets of corresponding (homogeneous) points (more than the 8 required) P_a_orig and P_b_orig and the two camera's 3x3 internal calibration matrices K_a and K_b.
We start off by normalizing our points with
P_a = inv(K_a) * p_a_orig
and
P_b = inv(K_b) * p_b_orig
We also know the constraint
P_b' * E * P_a = 0
I'm following it this far, but how do you actually solve that last problem, e.g. finding the nine values of the E matrix? I've read several different lecture notes on this subject, but they all leave out that crucial last step. Likely because it is supposedly trivial math, but I can't remember when I last did this and I haven't been able to find a solution yet.
This equation is actually pretty common in geometry algorithms, essentially, you are trying to calculate the matrix X from the equation AXB=0. To solve this, you vectorise the equation, which means,
vec() means vectorised form of a matrix, i.e., simply stack the coloumns of the matrix one over the another to produce a single coloumn vector. If you don't know the meaning of the scary looking symbol, its called Kronecker product and you can read it from here, its easy, trust me :-)
Now, say I call the matrix obtained by Kronecker product of B^T and A as C.
Then, vec(X) is the null vector of the matrix C and the way to obtain that is by doing the SVD decomposition of C^TC (C transpose multiplied by C) and take the the last coloumn of the matrix V. This last coloumn is nothing but your vec(X). Reshape X to 3 by 3 matrix. This is you Essential matrix.
In case you find this maths too daunting to code, simply use the following code by Y.Ma et.al:
% p are homogenius coordinates of the first image of size 3 by n
% q are homogenius coordinates of the second image of size 3 by n
function [E] = essentialDiscrete(p,q)
n = size(p);
NPOINTS = n(2);
% set up matrix A such that A*[v1,v2,v3,s1,s2,s3,s4,s5,s6]' = 0
A = zeros(NPOINTS, 9);
if NPOINTS < 9
error('Too few mesurements')
return;
end
for i = 1:NPOINTS
A(i,:) = kron(p(:,i),q(:,i))';
end
r = rank(A);
if r < 8
warning('Measurement matrix rank defficient')
T0 = 0; R = [];
end;
[U,S,V] = svd(A);
% pick the eigenvector corresponding to the smallest eigenvalue
e = V(:,9);
e = (round(1.0e+10*e))*(1.0e-10);
% essential matrix
E = reshape(e, 3, 3);
You can do several things:
The Essential matrix can be estimated using the 8-point algorithm, which you can implement yourself.
You can use the estimateFundamentalMatrix function from the Computer Vision System Toolbox, and then get the Essential matrix from the Fundamental matrix.
Alternatively, you can calibrate your stereo camera system using the estimateCameraParameters function in the Computer Vision System Toolbox, which will compute the Essential matrix for you.

Creating Filter's Laplacian Matrix and Solving the Linear Equation for Image Filtering

I have an optimization problem to solve in order to filter an image.
I created a Linear Equation of the problem which deals with Sparse Matrices.
At first I will show the problem.
First, the Laplacian (Adjacency) matrix of the problem:
The matrix Dx / Dy is the forward difference operator -> Hence its transpose is the backward difference operator.
The matrix Ax / Ay is diagonal matrix with weights which are function of the gradient of the image (Point wise, namely the value depends only on the gradient on that pixel by itself).
The weights are:
Where Ix(i) is the horizontal gradient of the input image at the i-th pixel (When you vectorize the input image).
Assuming input Image G -> g = vec(G) = G(:).
I want to find and image U -> u = vec(U) = U(:) s.t.:
My questions are:
How can I build the matrices Dx / Dy / Ax / Ay effectively (They are all sparse)?
By setting M = (I + \lambda * {L}_{g}), Is there an optimized way to create M directly?
What would be the best way to solve this linear problem in MATLAB? Is there a way to by pass memory limitations (Namely, dealing with large images and still be able to solve it)?
Is there an Open Source library to solve it under limited memory resources? Any library with MATLAB API?
Thank You.
Given your comments, let's answer each question in a synopsis and go from there:
I will answer that question below using sparse and other related functions
Using (1), we can definitely build M in an optimized way.
Simply put, the \ operator is the best thing to use when solving an inverse. MathWorks have spent so much time trying to optimize it, and it pretty much uses LAPACK and BLAS under the hood, that you would be insane not to use it. The only time you wouldn't be able to use it is answered in (4).
There are some MATLAB scripts that can handle solving the matrix iteratively, like the Successive Overrelaxation technique, but you should only use those if your run out of memory (i.e. if \ doesn't give you an answer). With the sparse representation of the matrices, this shouldn't (hopefully) happen, so let's avoid using those functions for now.
Going back to your question, we can produce a sparse representation of L_g very nicely. Given the definition of Dx and Dy, we can use the sparse version of the eye command called speye. Therefore, Dx and Dy can be calculated by Dx = diff(speye(size(inputImage))); As an example, this is what would be produced if you tried doing this on a 7 x 5 image.
>> diff(speye(7,5))
ans =
(1,1) -1
(1,2) 1
(2,2) -1
(2,3) 1
(3,3) -1
(3,4) 1
(4,4) -1
(4,5) 1
(5,5) -1
As you can see, we are referencing only non-zero entries. Row 1, column 1 has a coefficient of -1, row 1, column 2 has a coefficient of 1 and so on. As for your Ax and Ay, that's also very easy to do. We have a diagonal matrix and we can set each of the entries manually. All we would do is specify a set of row indices, column indices, and what the values are at each point. Therefore, we can do that by:
inputImage = im2double(inputImage); %//Important
rows = 1 : numel(inputImage); %// Assuming a 2D matrix
cols = rows; % // Row and column indices are the same
valuesDx = exp(-(gradX(rows).^2 / 2*sigma*sigma ));
valuesDy = exp(-(gradY(rows).^2 / 2*sigma*sigma ));
The reason for the first call is because we want to make sure that the pixels are in double precision, as finding the inverse in MATLAB requires that you do this. It also ensures we don't overflow the type as we are normalizing the intensities between 0 and 1. You may have to adjust your standard deviation to reflect this. Now we just need to construct our Ax and Ay matrices, and let's put it together with Dx and Dy:
numberElements = numel(inputImage);
Ax = sparse(rows, cols, valuesDx, numberElements, numberElements);
Ay = sparse(rows, cols, valuesDy, numberElements, numberElements);
identity = speye(numberElements, numberElements);
Dx = diff(identity);
Dy = Dx.'; %// Transpose
The reason why I'm transposing Dx to get Dy is because the difference operator in the vertical direction should simply be the transpose (makes sense to me). These should all be sparse representations of each of the matrices you want. Matrix operations can also be performed on sparse matrices, including multiplication and the inverse. As such:
Lg = Dx.' * Ax * Dx + Dy.' * Ay * Dy;
You can now solve for u via:
u = (identity + lambda*Lg) \ g;
This assumes that g is structured with your pixels in your image in column-major format. The way I sampled the pixels to build Ax and Ay naturally follows this. As such, do g = inputImage(:);, assuming that we have converted to double and normalized between 0 and 1.
When you finally solve for u, you can reshape it back to an image by doing:
u = reshape(u, size(inputImage, 1), size(inputImage, 2));
u may also be sparse, so if you want the original image back, cast it using full():
u = full(u);
Hope this helps!

How to normalize a matrix of 3-D vectors

I have a 512x512x3 matrix that stores 512x512 there-dimensional vectors. What is the best way to normalize all those vectors, so that my result are 512x512 vectors with length that equals 1?
At the moment I use for loops, but I don't think that is the best way in MATLAB.
If the vectors are Euclidean, the length of each is the square root of the sum of the squares of its coordinates. To normalize each vector individually so that it has unit length, you need to divide its coordinates by its norm. For that purpose you can use bsxfun:
norm_A = sqrt(sum(A .^ 2, 3)_; %// Calculate Euclidean length
norm_A(norm_A < eps) == 1; %// Avoid division by zero
B = bsxfun(#rdivide, A, norm_A); %// Normalize
where A is your original 3-D vector matrix.
EDIT: Following Shai's comment, added a fix to avoid possible division by zero for null vectors.