Calculating mean shift vector in MATLAB - matlab

I'm looking for an elegant way to calculate the mean shift vector for a uint8(960x540x3) image in MATLAB. The meanshift vector is given by
S_h is the neighborhood we are looking in given by a circle of radius h. In MATLAB I have built logical mask (s_mask) with those properties.
w(x_i) is the value of the probability map for a pixel with x-y coordinates. This is a scalar value. w is a 960x540 matrix.
x is the center of the neighborhood circle. I'm interested in finding a fast method in calculating such a vector with preferably no for loops but just matrix multiplications.

Related

Calculating geodesic distance in MATLAB

I want to calculate geodesic distance between non-adjacent nodes in an directed graph. As in the following matrix (W), zeros reperesent that those nodes are non-adjacent and other values show weights of the edges corresponding nodes. I calculated the distance according to the following equation:
I used the MATLAB function graphshortestpath(). However, I'm afraid this function couldn't provide what I am looking for. So the question is what is another way to calculate such a distance? Is there another function in MATLAB for that? Is it possible that making the matrix sparse affects final result?
Program code:
N=6; % Size of matrix W
W=[0,0.797944993710195,0,0,0,0;0.495326358306295,0,0.164911895411107,0,0,0;0,0.0530273831645896,0,0.00901073533222818,0,0;0,0,0.00709165683115063,0,0.438584093809830,0;0,0,0,0.397895339311598,0,0.000916573989905329;0,0,0,0,0.00104307323830613,0]; %Connectivity matrix
Geo_dist=zeros(N); %temporary variable for geodesic distance measurement
W_sparse=sparse(W); %Making W sparse because the matlab function works only with sparse matrix
for g=1:N
for h=1:N
if W(g,h)==0 & g~=h;
Geo_dist(g,h)=graphshortestpath(W_sparse,g,h,'directed',false);
end
end
end
Can you use bwdistgeodesic or graydist in the Image Processing Toolbox directly on the image grid?
https://www.mathworks.com/help/images/ref/graydist.html
https://www.mathworks.com/help/images/ref/bwdistgeodesic.html
Or if you prefer something smoother, imsegfmm will let you use fast marching method to compute the geodesic distance if you look at the doc example:
https://www.mathworks.com/help/images/ref/imsegfmm.html
I'm assuming in my response that you have gridded image data and that this isn't a graph of arbitrary connectivity since this is tagged "image-processing".

Doing PCA and Whitening with matlab

My task is to do PCA and whitening transform with given 2dimentional 5000data.
What I understand with PCA is analyzing the main axis of the data with covariance Matrix's Eigen Vector and rotate the main axis to the x axis!
So here's what I did.
[BtEvector,BtEvalue]=eig(MYCov);% Eigen value and vector using built-in function
I first calculated eigen values and vectors. The result was
BtEvalue=[4.027487815706757,0;0,8.903923357227459]
and
BtEvector=[0.033937679569230,-0.999423951036524;-0.999423951036524,-0.033937679569230]
So I figured out that the main axis will have eigen value of 8.903923357227459 and eigen vector of [-0.999423951036524,-0.033937679569230] which is the second corresponding term.
After then, because it's two dimentional data, I let cos(theta) as -0.9994.. and sin(theta)=-0.033937. Because I thought the main axis of the data(eigen vector [-0.999423951036524,-0.033937679569230]) has to be x axis I made rotational axis R= [cos(-Theta)-sin(-theta);sin(-theta) cos(-theta)]. Let original data sets A=>2*5000, I did A*R to get rotated data.
Also, For whitening case, using Cholesky whitening, I made whitening transformation matrix as inv(Covariance Matrix).
Is there something wrong with my algorithm? Could someone testify if there's error or misunderstanding please? Thank you a lot in advance.
Since your data is two-dimensional, the covariance matrix that you calculated is not accurate. If you only calculate the covariance with respect to one axis (say x), you're assuming that the covariance along the y axis is identity. This is obviously not true. Although you've attempted to address this, there's a sound procedure that you can use (I've explained below).
Unfortunately, this is a common mistake. Have a look at this paper, where it is explained exactly how the covariance should be calculated.
In summary, you can calculate the covariance along each axis (Sx and Sy). Then approximate the 2D covariance of the vectorized matrix as kron(Sx,Sy). This will be a better approximation of the 2D covariance.

Get nearest point on a sphere in MATLAB

I want to get the point on a n-dimensional sphere, which is nearest to a given point p with the same dimension.
My sphere is created by the dot-product of a positive definite Matrix A.
All points on the sphere are characterized by:
x'*A*x = const
Mathematically, I am searching for the x where
(p-x)'*A*(p-x)
is minimal. (x is a point on the sphere)
I didn't find any MATLAB function for this problem, nor do I have an idea on how to solve this problem in n dimensions.

Understanding L2-norm in MATLAB

I have two matrices, x and y, which are the same size. They are two estimations of the same data field. I want to quantify the difference between them across the whole matrix. Is norm(x-y,2) how this is normally done? What units is this in - if x and y are velocities in mm/sec, and I want to turn the L2-norm into a percentage of some reference velocity, does that make any sense?
Should this belong in Math?
Norm 2 of a matrix in Matlab is equal to root square of sum of squares of all elements. The all norm functions do not change units( its because you apply both square and root-square).
If you want compare the result with a reference velocity, it is better to use other measures like RMS (Root Mean Square). It is similar to norm but you should normalize the sum of squares before applying the root square. (this measure also does not change units)
The RMS of this matrix can be interpreted as :
How much velocity is changed at each place (x and y) in average.(the unit is mm/sec)
I'm not sure what you mean by "quantify the difference", so this is what I do know...
norm(x) == norm(x, 2)
Equivalent since L2 norm is default. From matlab help
n = norm(X) returns the 2-norm or maximum singular value of matrix X.
So, if the max singular value of the difference of your two matrices is what you want, then you have the right function.
norm(X,2) or just norm(X) will give you the l2 norm or the euclidian norm of X. X can be a matrix or a Vector. Be it a vector or a matrix, norm will be calculated by first squaring all elements, then summing them up and taking a square root yielding a single value as the answer. What you are trying to do will in some sense give you the magnitude of the difference between the two matrices. The units will be same as that of matrix elements.

Sampling uniformly from many circles on the sphere efficiently in matlab

I have a 3-by-N matrix X whose columns are vectors on the unit sphere (i.e., the Euclidean length of each vector is 1), and I have a 1-by-N vector Theta whose entries are all angles between 0 and pi. For each i, there is a circle on the sphere centered at X(:,i) defined as the set of all points that have the angle Theta(i) with X(:,i). I would like to get one uniform sample from the circle for each i, avoiding for loops because they can be slow in Matlab. I know that in vectorized Matlab code I can easily get one sample each from all circles with angles in Theta if I assume the center of all circles is [0,0,1], and then I know how to get a rotation matrix (using Rodrigues rotation formula) that rotates [0,0,1] to another desired vector x, so for each i, I can just apply this rotation matrix to the sample point I obtained assuming [0,0,1] was the center.
I would like to this for all i without for loops, i.e. using array/matrix/vector notation.
If you're using Rodrigues' rotation formula, you're trying to convert from axis-angle representation to rotation matrices. You're in luck. I happen to have written fast vectorized code to do exactly what I believe you're asking about. You can can find the code here: axang2rotmat.m. Use is pretty straightforward (read the help):
n = 1e3; % Number of axis-angles and rotation matrices
th = pi*rand(1,n); % Random rotation angles between 0 and pi
v = normc(rand(3,n)); % Random rotation vectors, normalized across columns
R = axang2rotmat(v,th); % Generate n rotation matrices, R is 3-by-3-n
Note, the above code is just to demonstrate the use of axang2rotmat and won't give you uniformly sampled rotation matrices (See Miles, Biometrika 1962 for details on why and workaround). I recommend that you calculate random rotation matrices directly, however. You can us another of my functions for that: randrotmat.m.
I also have code to convert back from rotation matrices to axis-angle and check if a particular matrix is a rotation matrix here.