Problems with performing image translation in MATLAB - matlab

I'm trying to do image translation using MATLAB, and the image doesn't move at all. My code is:
myPic = imread('pic.jpg');
x = 250;
y = 375;
trans = affine2d([1 0 0; 0 1 0; x y 1]);
outputPic = imwarp(myPic, trans);
imshow(myPic)
axis on
figure()
imshow(outputPic)
axis on
isequal(myPic,outputPic) %evaluates to 1!!!
When I do the same for a rotation affine matrix, it worked. Why doesn't this work?
here's what happens when I print both pics:

In order for this to work, you'll need to define an 'OutputView' parameter.
This parameter sets the size and location of the output image in world coordinate system, using imref2d function.
Example:
myPic = imread('peppers.png');
x = 250;
y = 375;
%defines transformations
trans = affine2d([1 0 0; 0 1 0; x y 1]);
eyeTrans= affine2d([1 0 0; 0 1 0; 0 0 1]);
%initializes imref2d object
outView = imref2d([size(myPic,1)+y,size(myPic,2)+x]);
outputPic1 = imwarp(I,trans,'OutputView',outView)
outputPic2 = imwarp(I,eyeTrans,'OutputView',outView)
%display result
figure,
subplot(1,2,1); imshow(outputPic2); title('original')
subplot(1,2,2); imshow(outputPic1); title('translated')
Result:

Related

binary mask for the coordinates using MATLAB

I need to create a binary mask. I have some coordinates and I make those coordinates and inside that region equal to 1, and background equal to zero.
Here is what I have done, but the problem is ROI located not in the correct position and located on the right bottom of the image. I appreciate if someone could point me to the right direction.
function [X,Y, BW] = Create_mask(X,Y,im)
X = round(X);
Y = round(Y);
X ( X < 1 ) = 1;
Y ( Y < 1 ) = 1;
BW = im > 255;
for p = 1:length(X)
BW(Y(p),X(p)) = 1;
end
for n = 0:(1/round(sqrt((X(end)-X(1))^2 + (Y(end)-Y(1))^2 ))):1
xn = round(X(1) +(X(end) - X(1))*n);
yn = round(Y(1) +(Y(end) - Y(1))*n);
BW(yn,xn) = 1;
end
se = strel('disk',10);
BW = imclose(BW,se);
BW = imdilate(BW,se);
BW = imfill(BW,'holes');
im( im < 255 ) = 0;
im = imclose(im,se);
BW = BW * 255;
BW = im2uint8(BW);
% BW = imresize(BW, [256 256],'nearest');
figure;
imshow(BW);
% close all;
end
Here is the output the function:
I was expecting to be similar to this image. This is not the exact solution but it shows my expectation.
X and Y coordinates are attached here, The first col is X and the second Y.
you can do this by calling function inpolygon, try this
function mask=createmask(x,y, cmin, cmax, dx)
if(nargin<3)
cmin=min([x(:) y(:)]);
end
if(nargin<4)
cmax=max([x(:) y(:)]);
end
if(nargin<5)
dx=(cmax-cmin)/100;
end
if(length(dx)==1)
dx=[dx dx];
end
[xi,yi]=meshgrid(cmin(1):dx(1):cmax(1),cmin(2):dx(2):cmax(2));
mask=reshape(inpolygon(xi(:),yi(:),x(:),y(:)), size(xi));
to test
xv = [0 3 3 0 0 NaN 1 1 2 2 1];
yv = [0 0 3 3 0 NaN 1 2 2 1 1];
mask=createmask(xv,yv, [-1 -1], [4 4]);
imagesc(mask)

Struggling with while loop (computer graphics)

Working on a little project to do with computer graphics. So far I have (I think) everything in order as the code below patches my world to the screen fine.
However, I have a final hurdle to jump: I would like the code to patch for different values of theta. In the code, it is set at 2*pi/4 but I would like to iterate and patch for every angle between 0:pi/4:2*pi. However, when I try to put the code in a for or while loop it doesn't seem to do what I expect, that is, to patch with one angle, then patch with another etc.
Really stuck I have tried a lot of stuff and now I'm just without any ideas. Would really appreciate any help or suggestions.
function world()
% Defining House Vertices
house_verts = [-5, 0, -5;
5, 0, -5;
5, 10, -5;
0,15,-5;
-5,10,-5;
-5,0,5;
5,0,5;
5,10,5;
0,15,5;
-5,10,5];
% Sorting out the homeogenous co-ordinates
ones = [1,1,1,1,1,1,1,1,1,1];
ones=transpose(ones);
house_verts = [house_verts, ones];
house_verts = transpose(house_verts);
% House faces
house_faces = [1,2,3,4,5;
2,7,8,3,3;
6,7,8,9,10;
1,6,10,5,5;
3,4,9,8,8;
4,5,10,9,9;
1,2,7,6,6];
world_pos = [];
% creating a street
street_vector = [1,0,1]; % the direction of the street
orthog_street_vector = [-1,0,1];
for i = 1:15
% current_pos1 and 2 will be the positions of the two houses
% opposite each other on the street
current_pos1 = 30*i*street_vector + 50*orthog_street_vector;
current_pos2 = 30*i*street_vector - 50*orthog_street_vector;
world_pos = [world_pos;current_pos1;current_pos2];
end
% initialising world vertices and faces
world_verts = [];
world_faces = [];
% Populating the street
for i =1:size(world_pos,1)
T = transmatrix(world_pos(i,:)); % a translation matrix
s = [1,1/2 + rand(),1];
S=scalmatrix(s); % a matrix for a random scaling of the height (y-coordinate)
Ry = rotymatrix(rand()*2*pi); % a matrix for a random rotation about the y-axis
A = T*Ry*S; % the compound transformation matrix to take the house into the world
obj_faces = size(world_verts,2) + house_faces; %increments the basic house faces to match the current object
obj_verts = A*house_verts;
world_verts = [world_verts, obj_verts]; % adds the vertices to the world
world_faces = [world_faces; obj_faces]; % adds the faces to the world
end
% initialising aligned vertices
align_verts = [];
% Aligning the vertices to the particular camera at angle theta
for elm = world_verts
x = 350 + 350*cos(2*pi/4);
z = 350 + 350*sin(2*pi/4);
y = 80;
u = [x,y,z];
v = [250,0,250];
d = v - u;
phiy = atan2(d(1),d(3));
phix = -atan2(d(2),sqrt(d(1)^2+d(3)^2));
T = transmatrix([-u(1),-u(2),-u(3)]);
Ry = rotymatrix(phiy);
Rx = rotxmatrix(phix);
A = Rx*Ry*T;
align_verts = [align_verts, A*elm];
end
% initialising projected vertices
proj_verts=[];
% Performing the projection
for elm = align_verts
proj = projmatrix(10);
projverts = proj*elm;
projverts = ((10/projverts(3))*projverts);
proj_verts = [proj_verts,projverts];
end
% Displaying the world
for i = 1:size(world_faces,1)
for j = 1:size(world_faces,2)
x(j) =proj_verts(1,world_faces(i,j));
z(j) = proj_verts(2,world_faces(i,j));
end
patch(x,z,'w')
end
end
function T = transmatrix(p)
T = [1 0 0 p(1) ; 0 1 0 p(2) ; 0 0 1 p(3) ; 0 0 0 1];
end
function S = scalmatrix(s)
S = [s(1) 0 0 0 ; 0 s(2) 0 0 ; 0 0 s(3) 0 ; 0 0 0 1];
end
function Ry = rotymatrix(theta)
Ry = [cos(theta), 0, -sin(theta),0;
0,1,0,0;
sin(theta),0,cos(theta),0;
0,0,0,1];
end
function Rx = rotxmatrix(phi)
Rx = [1, 0, 0, 0;
0, cos(phi), -sin(phi), 0;
0, sin(phi), cos(phi), 0;
0, 0, 0, 1];
end
function P = projmatrix(f)
P = [1,0,0,0
0,1,0,0
0,0,1,0
0,0,1/f,0];
end
Updated code: managed to get the loop to work but now there is some bug i don't understand when it does a full rotation again any help would be great.
function world()
% Defining House Vertices
house_verts = [-5, 0, -5;
5, 0, -5;
5, 10, -5;
0,15,-5;
-5,10,-5;
-5,0,5;
5,0,5;
5,10,5;
0,15,5;
-5,10,5];
% Sorting out the homeogenous co-ordinates
ones = [1,1,1,1,1,1,1,1,1,1];
ones=transpose(ones);
house_verts = [house_verts, ones];
house_verts = transpose(house_verts);
% House faces
house_faces = [1,2,3,4,5;
2,7,8,3,3;
6,7,8,9,10;
1,6,10,5,5;
3,4,9,8,8;
4,5,10,9,9;
1,2,7,6,6];
world_pos = [];
% creating a street
street_vector = [1,0,1]; % the direction of the street
orthog_street_vector = [-1,0,1];
for i = 1:15
% current_pos1 and 2 will be the positions of the two houses
% opposite each other on the street
current_pos1 = 30*i*street_vector + 50*orthog_street_vector;
current_pos2 = 30*i*street_vector - 50*orthog_street_vector;
world_pos = [world_pos;current_pos1;current_pos2];
end
% initialising world vertices and faces
world_verts = [];
world_faces = [];
% Populating the street
for i =1:size(world_pos,1)
T = transmatrix(world_pos(i,:)); % a translation matrix
s = [1,1/2 + rand(),1];
S=scalmatrix(s); % a matrix for a random scaling of the height (y-coordinate)
Ry = rotymatrix(rand()*2*pi); % a matrix for a random rotation about the y-axis
A = T*Ry*S; % the compound transformation matrix to take the house into the world
obj_faces = size(world_verts,2) + house_faces; %increments the basic house faces to match the current object
obj_verts = A*house_verts;
world_verts = [world_verts, obj_verts]; % adds the vertices to the world
world_faces = [world_faces; obj_faces]; % adds the faces to the world
end
% initialising aligned vertices
align_verts = [];
% initialising projected vertices
proj_verts=[];
% Aligning the vertices to the particular camera at angle theta
theta = 0;
t = 0;
while t < 100
proj_verts=[];
align_verts = [];
for elm = world_verts
x = 300 + 300*cos(theta);
z = 300 + 300*sin(theta);
y = 80;
u = [x,y,z];
v = [200,0,200];
d = v - u;
phiy = atan2(d(1),d(3));
phix = -atan2(d(2),sqrt(d(1)^2+d(3)^2));
T = transmatrix([-u(1),-u(2),-u(3)]);
Ry = rotymatrix(phiy);
Rx = rotxmatrix(phix);
A = Rx*Ry*T;
align_verts = [align_verts, A*elm];
end
% Performing the projection
for elm = align_verts
proj = projmatrix(6);
projverts = proj*elm;
projverts = ((6/projverts(3))*projverts);
proj_verts = [proj_verts,projverts];
end
% Displaying the world
for i = 1:size(world_faces,1)
for j = 1:size(world_faces,2)
x(j) = proj_verts(1,world_faces(i,j));
z(j) = proj_verts(2,world_faces(i,j));
end
patch(x,z,'w')
pbaspect([1,1,1]); % adjusts the aspect ratio of the figure
end
title('Projected Space', 'fontsize', 16, 'interpreter', 'latex')
xlabel('$x$', 'fontsize', 16, 'interpreter', 'latex')
ylabel('$z$', 'fontsize', 16, 'interpreter', 'latex')
zlabel('$y$', 'fontsize', 16, 'interpreter', 'latex')
axis([-5,5,-5,2,0,5]) % sets the axes limits
view(0,89)
pause(0.0000001)
theta = theta + 0.01;
clf
end
end
function T = transmatrix(p)
T = [1 0 0 p(1) ; 0 1 0 p(2) ; 0 0 1 p(3) ; 0 0 0 1];
end
function S = scalmatrix(s)
S = [s(1) 0 0 0 ; 0 s(2) 0 0 ; 0 0 s(3) 0 ; 0 0 0 1];
end
function Ry = rotymatrix(theta)
Ry = [cos(theta), 0, -sin(theta),0;
0,1,0,0;
sin(theta),0,cos(theta),0;
0,0,0,1];
end
function Rx = rotxmatrix(phi)
Rx = [1, 0, 0, 0;
0, cos(phi), -sin(phi), 0;
0, sin(phi), cos(phi), 0;
0, 0, 0, 1];
end
function P = projmatrix(f)
P = [1,0,0,0
0,1,0,0
0,0,1,0
0,0,1/f,0];
end

Add different color line plots to gscatter plots in for loop

I have the following code:
limits = [-1 1 -1 1];
g1 = [1;2;3;4;5;6;7;8];
col = [1 1 0; 1 0 1; 0 1 1; 1 0 0; 0 1 0; 0 0 1; 0 0 0; 0.5 0.3 0.1];
sym = 'vvvv^^^^';
sym2 = 'xxxxxxxx';
points = 30;
for i = 1:8;
mhuR(i,1) = mean(HSRXdistpR(i,:));
mhuR(i,2) = mean(HSRYdistpR(i,:));
mhuL(i,1) = mean(HSRXdistpL(i,:));
mhuL(i,2) = mean(HSRYdistpL(i,:));
mhuX(i,1) = mean(TotxcomHSRpX(i,:));
mhuX(i,2) = mean(TotxcomHSRpY(i,:));
CR{i} = cov(HSRXdistpR(i,:),HSRYdistpR(i,:));
CL{i} = cov(HSRXdistpL(i,:),HSRYdistpL(i,:));
CX{i} = cov(TocomXdistp(i,:),TocomYdistp(i,:));
ellipR{i} = uncertEllip(CR{i},mhuR(i,:),points);
ellipL{i} = uncertEllip(CL{i},mhuL(i,:),points);
ellipX{i} = uncertEllip(CX{i},mhuX(i,:),points);
end
figure; hold on
scatter(HSRXdistbR2,HSRYdistbR2,'ko'); hold on
scatter(HSRXdistbL2,HSRYdistbL2,'ko'); hold on
scatter(TocomXdistb2,TocomYdistb2,'kx'); hold on
gscatter(HSRXp2(:,1),HSRYp2(:,1),g1,col,sym), hold on
gscatter(HSRXp2(:,2),HSRYp2(:,2),g1,col,sym), hold on
gscatter(copHSRXp2(:,2),copHSRYp2(:,2),g1,col,sym2), hold on
for i = 1:8;
plot(ellipR{i}(:,1),ellipR{i}(:,2),col(i,:)), hold on
plot(ellipL{i}(:,1),ellipL{i}(:,2),col(i,:)), hold on
plot(ellipX{i}(:,1),ellipX{i}(:,2),col(i,:)), hold on
end
vline(0)
hline(0)
legend('base','base','base','-0.04m', '-0.08m', '-0.12m', '-0.16m', '0.04m', '0.08m', '0.12m', '0.16m');
title({'xCoM and left and right foot placement relative',...
'to xCoM per perturbation, for all subjects'})
axis(limits)
xlabel('x displacement (scaled)');
ylabel('y displacement (scaled)');`
I'm trying to get the line plots (second for loop) to have the same colors as the scatter plot data (the uncertainty ellipses each belong to their own scatter point). However, it won't allow me to use the colors from the col matrix. Am I missing something here?
Error:
Data must be a single matrix Y or a list of pairs X,Y.
Not trying to define the colors works fine, but of course the colors don't match.
Try replacing each of those erroring lines with this:
plot(ellipR{i}(:,1),ellipR{i}(:,2),'Color',col(i,:));

How do I flip a function across its center line?

Say a defined function begins with point (a,b) and ends with point (c,d). How do I flip this function about its vertical center line (described by x = (c-a)/2)?
Thanks in advance!
c = 5.2;
alpha = 0;
R = [cosd(alpha) sind(alpha) 0; -sind(alpha) cosd(alpha) 0; 0 0 1];
l1_vector = [-sqrt(3)*c; 0; 0];
l1_prime = R*l1_vector;
iter = 1;
for i=1:1201
R = [cosd(alpha) sind(alpha) 0; -sind(alpha) cosd(alpha) 0; 0 0 1];
l1_prime = R*l1_vector;
a = l1_prime(1)
b = l1_prime(2);
alpha = alpha+.1;
data1(iter,1:2)=[a,b];
iter=iter+1;
end
a = data1(:,1);
b = data1(:,2);
plot(wrev(a)+a(end)-a(1),b)
axis equal
Depends how your function is defined really, but if you have a vector of x values and another with corresponding function values y, then
plot(x,y)
plots the function normally, and
plot(a,b,2*a(end)-a(1)-cumsum([0;diff(a)]),b)
plots the flipped and translated function.

3D rotation of a sphere around a fixed point in Matlab

I have a sphere centered on the origin of the axes. I use the rotate3d function to allow its rotation. However, when I rotate it, it seems to move in the space with having a fixed point for the rotation. I would like to fix the origin as rotation center. How can I achieve it?
Here is my code:
function ex
global state;
fh = figure('Menu','none','Toolbar','none','Units','characters',...
'Renderer','OpenGL');
hPanAni = uipanel('parent',fh,'Units','characters','Position',...
[22.6 10.4 53 23],'title','Controls','FontSize',11,...
'FontAngle','italic','FontWeight','bold');
hIniAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.75 0.5 0.12],'String','Spin',...
'FontSize',10,'Callback',#hIniAniCallback);
hFinAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.5 0.5 0.12],'String','Stop',...
'FontSize',10,'Callback',#hFinAniCallback);
hResetAni = uicontrol(hPanAni,'Style','pushbutton','Units','normalized',...
'Position',[0.14 0.25 0.5 0.12],'String','Reset',...
'FontSize',10,'Callback',#hResetAniCallback);
hPantSim = uipanel('Parent',fh,'Units','characters',...
'Position',[107.87 8 157.447 42],'BorderType','none','title',...
'Screen','FontSize',11,'FontAngle','italic',...
'FontWeight','bold');
hPantSimInt = uipanel('Parent',hPantSim,'Units','normalized','Position',...
[0 0 1 1],'BorderType','line','BackgroundColor','k');
axes('units','normalized','position',[0,0,1,1],'Parent',...
hPantSimInt);
stars = rand(60,2);
scatter(stars(:,1),stars(:,2),6,'y','Marker','+');
axis off;
ah4 = axes('Parent',hPantSimInt,'Units','normalized','Position',...
[0 0 1 1],'Color','none','Visible','off','DataAspectRatio',...
[1 1 1],'NextPlot','add');
T1 = 0:pi/1000:2*pi;
Fin = numel(T1);
if (Fin>1000)
Incr = floor(Fin/1000);
else
Incr = 1;
end
Y = zeros(numel(T1),3);
Y(:,1) = 7000*cos(T1);
Y(:,2) = 7000*sin(T1);
R_esf = 6378;
[x_esf,y_esf,z_esf] = sphere(50);
x_esf = R_esf*x_esf;
y_esf = R_esf*y_esf;
z_esf = R_esf*z_esf;
props.FaceColor= 'texture';
props.EdgeColor = 'none';
props.Parent = ah4;
surface(x_esf,y_esf,z_esf,props);
handles.psat = line('parent',ah4,'XData',Y(1,1), 'YData',Y(1,2),...
'ZData',Y(1,3),'Marker','o', 'MarkerSize',10,'MarkerFaceColor','b');
line([0 1.5*R_esf],[0 0],[0 0],'LineWidth',3,'Color','g');
line([0 0],[0 1.5*R_esf],[0 0],'LineWidth',3,'Color','g');
line([0 0],[0 0],[0 1.5*R_esf],'LineWidth',3,'Color','g');
pbaspect([1 1 1]);
axis vis3d;
rotate3d(ah4);
view([atan2(Y(1,2),Y(1,1)),0]);
az = 0;
k = 2;
ind_ini = 0;
state = 0;
function hIniAniCallback(hObject,evt)
tic;
if (ind_ini == 1)
return;
end
ind_ini = 1;
state = 0;
while (k<=Fin)
set(handles.psat,'XData',Y(k,1),'YData',Y(k,2),'ZData',Y(k,3));
pause(0.002);
if (k == Fin)
toc;
end
k = k + Incr;
if (state == 1)
state = 0;
break;
end
end
end
function hFinAniCallback(hObject,evt)
ind_ini = 0;
state = 1;
end
function hResetAniCallback(hObject,evt)
set([handles.psat],'Visible','off');
ind_ini = 0;
state = 1;
az = 0;
k = 2;
handles.psat = line('parent',ah4,'XData',Y(1,1), 'YData',Y(1,2),...
'ZData',Y(1,3),'Marker','o', 'MarkerSize',10,'MarkerFaceColor','b');
end
end
The problem is that the 3d rotation is done with respect to the center of your axes, and not with respect to the origin. After you add the green lines along the axes, the limits of the x,y,z axes is automatically changed, the center of sphere is no longer positioned in the center of the figure. Add the following line after drawing all the lines:
ax_limits = 2*[-R_esf R_esf];
set (ah4, 'xlim', ax_limits, 'ylim', ax_limits, 'zlim', ax_limits)
The '2' factor is just to prevent the sphere from filling your axes tightly. You can set it to whatever value you need.