Polar to Cartesian Coordinates (Matlab) - matlab

Initially, I transformed the image from cartesian to polar coordinates. It worked well. Finally, when I need to transform the image back to cartesian coordinates, it is not working. Could someone help me to transform the image back to cartesian coordinates?
I want to tranform this image to cartesian circle
f = fullfile(imagefolder, filename(i).name);
I=imread(f);
imageSize = size(I);
ci = [250, 200, 130];
[xx,yy] = ndgrid((1:imageSize(1))-ci(1),(1:imageSize(2))-ci(2));
mask = uint8((xx.^2 + yy.^2)<ci(3)^2);
c = uint8(zeros(size(I)));
c(:,:,1) = I(:,:,1).*mask;
c(:,:,2) = I(:,:,2).*mask;
c(:,:,3) = I(:,:,3).*mask;
imshow(c);
threshold = 128;
Igray = rgb2gray(c);
img = Igray>threshold;
imshow(Igray);
[a,b] = size(img);
row = a/ 2;
col = b/ 2;
[X,Y] = meshgrid((1:b) - col, (1:a) - row);
[theta, rho] = cart2pol(X, Y);
rangeR = linspace(0, max(rho(:)), 200);
rangeTH = linspace(-pi, pi, 200);
[c, d] = meshgrid(rangeTH, rangeR);
img1 = griddata(theta, rho, double(img), c, d);
figure
imshow(img);
title('Original Image')
SE = strel("disk",2)
open=imerode(img1,SE);
close=imclose(open,SE);
y= medfilt2(close);
IblurX1 = imgaussfilt(y,[5 5]);
bin=im2bw(IblurX1);
figure,imshow(bin)

Related

Unexpected result when calculating mean curvature in MatLab

I am running simulations of a protein/membrane system, and want to quantify the degree of membrane deformation. I have averaged the membrane surface on a grid during the simulation, which results in a text file with three columns, containing the x, y, and z points of the membrane. I then convert this information to a mesh surface in matlab, which I then use to calculate the gaussian and/or mean curvature. The problem is, I'm getting similar values at the very beginning of the simulation, when the surface (membrane) is very flat, and at the end, when it is completely deformed. Unless I'm misunderstanding what curvature is, this is not correct and I believe I am doing something wrong in the matlab portion of this process. Here's the script where I loop over many frames (each of which is a different file containing x,y,z coordinates of the averaged membrane) and convert it to a mesh:
https://pastebin.com/reqWAz01
for i = 0:37
file = strcat('cg-topmem_pos-', num2str(i), '.out');
A = load(file);
x = A(:,1);
y = A(:,2);
z = A(:,3);
xv = linspace(min(x), max(x), 20);
yv = linspace(min(y), max(y), 20);
[X,Y] = meshgrid(xv, yv);
Z = griddata(x,y,z,X,Y);
[K,H,Pmax,Pmin] = surfature(X,Y,Z);
M = max(max(H))
if i == 0
fileID = fopen('Average2-NoTMHS-5nmns.txt', 'a');
fprintf(fileID, '%f %f\n',M);
fclose(fileID);
else
fileID = fopen('Average2-NoTMHS-5nmns.txt', 'a');
fprintf(fileID, '\n%f %f\n',M);
fclose(fileID);
end
end
Then using the following calculates curvature:
https://pastebin.com/5D21PdBQ
function [K,H,Pmax,Pmin] = surfature(X,Y,Z),
% SURFATURE - COMPUTE GAUSSIAN AND MEAN CURVATURES OF A SURFACE
% [K,H] = SURFATURE(X,Y,Z), WHERE X,Y,Z ARE 2D ARRAYS OF POINTS ON THE
% SURFACE. K AND H ARE THE GAUSSIAN AND MEAN CURVATURES, RESPECTIVELY.
% SURFATURE RETURNS 2 ADDITIONAL ARGUMENTS,
% [K,H,Pmax,Pmin] = SURFATURE(...), WHERE Pmax AND Pmin ARE THE MINIMUM
% AND MAXIMUM CURVATURES AT EACH POINT, RESPECTIVELY.
% First Derivatives
[Xu,Xv] = gradient(X);
[Yu,Yv] = gradient(Y);
[Zu,Zv] = gradient(Z);
% Second Derivatives
[Xuu,Xuv] = gradient(Xu);
[Yuu,Yuv] = gradient(Yu);
[Zuu,Zuv] = gradient(Zu);
[Xuv,Xvv] = gradient(Xv);
[Yuv,Yvv] = gradient(Yv);
[Zuv,Zvv] = gradient(Zv);
% Reshape 2D Arrays into Vectors
Xu = Xu(:); Yu = Yu(:); Zu = Zu(:);
Xv = Xv(:); Yv = Yv(:); Zv = Zv(:);
Xuu = Xuu(:); Yuu = Yuu(:); Zuu = Zuu(:);
Xuv = Xuv(:); Yuv = Yuv(:); Zuv = Zuv(:);
Xvv = Xvv(:); Yvv = Yvv(:); Zvv = Zvv(:);
Xu = [Xu Yu Zu];
Xv = [Xv Yv Zv];
Xuu = [Xuu Yuu Zuu];
Xuv = [Xuv Yuv Zuv];
Xvv = [Xvv Yvv Zvv];
% First fundamental Coeffecients of the surface (E,F,G)
E = dot(Xu,Xu,2);
F = dot(Xu,Xv,2);
G = dot(Xv,Xv,2);
m = cross(Xu,Xv,2);
p = sqrt(dot(m,m,2));
n = m./[p p p];
% Second fundamental Coeffecients of the surface (L,M,N)
L = dot(Xuu,n,2);
M = dot(Xuv,n,2);
N = dot(Xvv,n,2);
[s,t] = size(Z);
% Gaussian Curvature
K = (L.*N - M.^2)./(E.*G - F.^2);
K = reshape(K,s,t);
% Mean Curvature
H = (E.*N + G.*L - 2.*F.*M)./(2*(E.*G - F.^2));
H = reshape(H,s,t);
% Principal Curvatures
Pmax = H + sqrt(H.^2 - K);
Pmin = H - sqrt(H.^2 - K);
Any help would be greatly appreciated. I'm afraid that there is some issue between how the mesh is created and how curvature is calculated, but I am not matlab literate and could use some help. Thanks very much.

matlab image rotation code

I'm beginner in computer vision. I'm trying to do a rotate transformation using matlab. My code is
I = imread('Koala.jpg');
rows = size(I, 1);
cols = size(I, 2);
deg = 45;
deg = deg * pi / 180;
C = uint8(zeros(size(I)));
mid = ceil([rows+1 cols+1] / 2);
[x1, x2] = meshgrid(1:rows, 1:cols);
M = [cos(deg) sin(deg); -sin(deg) cos(deg)];
X = bsxfun(#minus, [x1(:) x2(:)], mid) * M;
X = round(bsxfun(#plus, X, mid));
x1 = X(:, 1);
x2 = X(:, 2);
x1(x1<1) = 1;
x2(x2<1) = 1;
x1(x1>rows) = rows;
x2(x2>cols) = cols;
X = [x1(:) x2(:)];
m = 1;
for i=1:rows
for j=1:cols
C(X(m, 1), X(m, 2), :) = I(i, j, :);
m = m + 1;
end
end
This works but in the result there are many pixeles without values. I guess, when I do "X2 = X*M", the range of the image on the transformation it's not same of the source and many values lost
If you have the Image Processing Toolbox, I would just use imrotate to do the rotation for you.
out = imrotate(I, 45);
Otherwise, I would try to vectorize your approach and use interp2. You can rotate all of the pixel centers by the specified angle and then sample at these rotated point.
% Compute the coordinates of all pixel centers
[x, y] = meshgrid(1:size(I, 2), 1:size(I, 1));
% Compute the rotation matrix
R = [ cos(deg) sin(deg);
-sin(deg) cos(deg)];
xy = [x(:), y(:)];
% Compute the middle point
mid = mean(xy, 1);
% Subtract off the middle point
xy = bsxfun(#minus, xy, mid);
% Rotate all of these coordinates by the desired angle
xyrot = xy * R;
% Reshape the coordinate matrices
xy = reshape(xy, [size(x), 2]);
xyrot = reshape(xyrot, [size(x), 2]);
% Interpolate the image data at the rotated coordinates
out = interp2(xy(:,:,1), xy(:,:,2), I, xyrot(:,:,1), xyrot(:,:,2));

Matlab - slice 3D volume

I need to slice a 3D volume (200x200x500 matrix) and plot the result. I tried following the example from Mathworks reported here, but the resulting slice is empty (it shouldn't be)... Do you have suggestions on how to fix this? Thanks!
Here is the code I am using and the resulting slice:
xmin = 1;
ymin = 1;
zmin = 1;
xmax = 200;
ymax = 200;
zmax = 499;
hslice = surf(linspace(xmin,xmax,100),...
linspace(ymin,ymax,100),...
zeros(100));
rotate(hslice,[100,100,250],-45)
xd = get(hslice,'XData');
yd = get(hslice,'YData');
zd = get(hslice,'ZData');
delete(hslice);
x = 1:200;
y = 1:200;
z = 1:499;
figure;
colormap(jet);
h = slice(x,y,z,V1,xd,yd,zd);
h.FaceColor = 'interp';
h.EdgeColor = 'none';
h.DiffuseStrength = 0.8;
This will draw a slice at x=100
v=randn(200,200,500);
[x,y,z] = meshgrid(1:200,1:200,1:500);
h=slice(x,y,z,v,100,[],[]);
set(h,'EdgeColor','none')
like wise you can place additional slices at y or z if you replace the [] with coordinates for e.h. y and z.

MATLAB - Approximating the integral with hemisphere domain with sample data

The integral part of the rendering equation performs an integral over a hemisphere range (with respect to solid angle).
I can generate samples that carry the value of corresponding integrand with this code:
n = 10;
rho_s = 0.5;
rho_d = 0.5;
light_phi = degtorad(30);
light_theta = degtorad(60);
[lx ly lz] = sph2cart(light_phi, light_theta, 1);
refDir = cat(3, -lx, -ly, lz);
normal = cat(3, 0, 0, 1);
[sample_phi sample_theta] = meshgrid(0:12:360, 0:3:90);
[sample_x sample_y sample_z] = sph2cart(degtorad(sample_phi), degtorad(sample_theta), 1);
viewDir = cat(3, sample_x, sample_y, sample_z);
dotRL = sum(bsxfun(#times, viewDir, refDir), 3);
dotRL = max(dotRL, 0);
brdf_s = rho_s*(n+2)*(dotRL.^n)/(2*pi);
brdf_d = rho_d/pi;
brdf = brdf_s + brdf_d;
x = sample_x.*brdf; y = sample_y.*brdf; z = sample_z.*brdf;
mesh(x, y, z);
line([0 lx],[0 ly],[0 lz]);
axis equal; axis vis3d;
xlim([-1 1]); ylim([-1 1]); zlim([0 1]);
The question I face now is how to do the integral or approximation with these samples?

How to plot a hyper plane in 3D for the SVM results?

I just wondering how to plot a hyperplane of the SVM results.
For example, here we are using two features, we can plot the decision boundary in 2D. But if how can we plot a hyperplane in 3D if we use 3 features?
load fisheriris;
features = meas(1:100,:);
featureSelcted = features(1:100,1:2); % For example, featureSelcted = features(1:100,1:3) can not be plotted
groundTruthGroup = species(1:100);
svmStruct = svmtrain(featureSelcted, groundTruthGroup, ...
'Kernel_Function', 'rbf', 'boxconstraint', Inf, 'showplot', true, 'Method', 'QP');
svmClassified = svmclassify(svmStruct,featureSelcted,'showplot',true);
A similar solution in R can be found at svm-fit-hyperplane, but a Matlab implementation would be handy.
Here is a function to plot 3D SVM results in MATLAB.
function [] = svm_3d_matlab_vis(svmStruct,Xdata,group)
sv = svmStruct.SupportVectors;
alphaHat = svmStruct.Alpha;
bias = svmStruct.Bias;
kfun = svmStruct.KernelFunction;
kfunargs = svmStruct.KernelFunctionArgs;
sh = svmStruct.ScaleData.shift; % shift vector
scalef = svmStruct.ScaleData.scaleFactor; % scale vector
group = group(~any(isnan(Xdata),2));
Xdata =Xdata(~any(isnan(Xdata),2),:); % remove rows with NaN
% scale and shift data
Xdata1 = repmat(scalef,size(Xdata,1),1).*(Xdata+repmat(sh,size(Xdata,1),1));
k = 50;
cubeXMin = min(Xdata1(:,1));
cubeYMin = min(Xdata1(:,2));
cubeZMin = min(Xdata1(:,3));
cubeXMax = max(Xdata1(:,1));
cubeYMax = max(Xdata1(:,2));
cubeZMax = max(Xdata1(:,3));
stepx = (cubeXMax-cubeXMin)/(k-1);
stepy = (cubeYMax-cubeYMin)/(k-1);
stepz = (cubeZMax-cubeZMin)/(k-1);
[x, y, z] = meshgrid(cubeXMin:stepx:cubeXMax,cubeYMin:stepy:cubeYMax,cubeZMin:stepz:cubeZMax);
mm = size(x);
x = x(:);
y = y(:);
z = z(:);
f = (feval(kfun,sv,[x y z],kfunargs{:})'*alphaHat(:)) + bias;
t = strcmp(group, group{1});
% unscale and unshift data
Xdata1 =(Xdata1./repmat(scalef,size(Xdata,1),1)) - repmat(sh,size(Xdata,1),1);
x =(x./repmat(scalef(1),size(x,1),1)) - repmat(sh(1),size(x,1),1);
y =(y./repmat(scalef(2),size(y,1),1)) - repmat(sh(2),size(y,1),1);
z =(z./repmat(scalef(3),size(z,1),1)) - repmat(sh(3),size(z,1),1);
figure
plot3(Xdata1(t, 1), Xdata1(t, 2), Xdata1(t, 3), 'b.');
hold on
plot3(Xdata1(~t, 1), Xdata1(~t, 2), Xdata1(~t, 3), 'r.');
hold on
% load unscaled support vectors for plotting
sv = svmStruct.SupportVectorIndices;
sv = [Xdata1(sv, :)];
plot3(sv(:, 1), sv(:, 2), sv(:, 3), 'go');
legend(group{1},group{end},'support vectors')
x0 = reshape(x, mm);
y0 = reshape(y, mm);
z0 = reshape(z, mm);
v0 = reshape(f, mm);
[faces,verts,colors] = isosurface(x0, y0, z0, v0, 0, x0);
patch('Vertices', verts, 'Faces', faces, 'FaceColor','k','edgecolor', 'none', 'FaceAlpha', 0.5);
grid on
box on
view(3)
hold off
end
Example plot:
% load data
load fisheriris;
% train svm using three features for two species
svmStruct = svmtrain(meas(1:100,1:3),species(1:100),'showplot','false','kernel_function','rbf',...
'boxconstraint',1,'kktviolationlevel',0.05,'tolkkt',5e-3);
% run function described above
svm_3d_matlab_vis(svmStruct,meas(1:100,1:3),species(1:100))