Display a tree structure inside a box in MATLAB - user-interface

I have a problem to see the tree structure created by the following code. I want the tree box fulfills the interior of the pane which handle is hPanLeft. However, if I use normalized units, I get NaN and Inf for the Position property of the tree structure. I do not understand what is wrong.
function example
import javax.swing.*
import javax.swing.tree.*;
f = figure;
hPanRight = uipanel('Parent',f,'Units','normalized','Position',...
[0.5 0 0.5 0.5]);
hPanLeft = uipanel('Parent',f,'Units','normalized','Position',...
[0 0.5 0.5 0.5]);
[tree, container]= uitree('v0');
set(container,'Parent',hPanLeft);
set(tree, 'Units', 'normalized');
set(tree,'Position',[0 0 1 1]);
get(tree,'Position'),
root = uitreenode('v0','root','MAIN',[],false);
Nodo1 = uitreenode('v0','Nodo1','LEAF 1',[],true);
Nodo2 = uitreenode('v0','Nodo2','LEAF 2',[],true);
Nodo3 = uitreenode('v0','Nodo3','LEAF 3',[],true);
root.add(Nodo1);
root.add(Nodo2);
root.add(Nodo3);
treeModel = DefaultTreeModel(root);
tree.setModel(treeModel);
jtree = handle(tree.getTree,'CallbackProperties');
tree.setSelectedNode(root);
end

You want to set the position property of the container not the tree object handle:
[tree,container] = uitree('v0');
set(container, 'Parent',hPanLeft);
set(container, 'Units','normalized', 'Position',[0 0 1 1]);
Just remember that UITREE is an undocumented function. You might want to read this series of articles on this component.

Related

2D Image transformations by pixel

I am trying to do a translation, euclidian, similarity, affine and projective transformation on an image pixel by pixel. the input for my program is the image name and the transformation matrix.
This is my code
function imagetrans(name, m)
Image = imread(name);
[rows, cols] = size(Image);
newImage(1:rows,1:cols) = 1;
for row = 1 : rows
for col = 1 : cols
if(Image(row,col) == 0)
point = [row;col;1];
answer = m * point;
answer = int8(answer);
newx = answer(1,1);
newy = answer(2,1);
newImage(newx,newy) = 0;
end
end
end
imshow(newImage);
end
This is the image
Right now I am testing just a translation matrix.
matrix =
1 0 7
0 1 2
0 0 1
when I pass the image and matrix through the function my result is just a little black line
What am I doing wrong?
Using the matlab debugger, I noticed that that you are casting to int8, which is too small too represent all indices. So, you should use int32/int64 or uint32/uint64 instead, i.e.
answer = uint8(answer);
should be
answer = uint32(answer);
Please try to use the Matlab debugger before asking the question: why does it not work?

How to save the size of image in txt file with matlab

I want to find the size of an image (height, width, and area) and save the size value in txt file. I tried this command:
img = imread('TN4.jpg');
abu=rgb2gray(img);
imwrite(abu,'abu.jpg');
cb=imclearborder(abu);
imwrite(cb,'cb.jpg')
thresh=graythresh(cb);
b=im2bw(cb,thresh);
imwrite(b,'b.jpg');
bw=bwareaopen(b,100);
bwfill=imfill(bw,'holes');
imwrite(bwfill,'bw.jpg');
s = regionprops(bwfill,'BoundingBox');
out = bsxfun(#times,img,uint8(bwfill));
objects=cell(numel(s),1);
for idx = 1:numel(s)
bb=floor(s(idx).BoundingBox);
objects{idx} = out(bb(2):bb(2)+bb(4), bb(1):bb(1)+bb(3),:);
end
k1=objects{1};
c1=rgb2gray(k1);
t1=graythresh(c1);
biner1=im2bw(c1,t1);
[height, width] = size(biner1);
a1 = bwarea(biner1);
h1=height(biner1);
w1=width(biner1);
X = [(h1);(w1);(a1)];
save datagrading.txt X -ascii
but i got warning massage
??? Index exceeds matrix dimensions.
Error in ==> exercise at 35
h1=height(biner1);
can anyone help me?
Thank you
height and width are scalars yet (it looks like to me...) you are assuming that they are functions.... no they're not functions. Just use height and width on its own and place it into your X matrix:
[height, width] = size(biner1);
a1 = bwarea(biner1);
%h1=height(biner1); %// Remove
%w1=width(biner1); %// Remove
X = [height;width;a1]; %// Change
save datagrading.txt X -ascii
Since you have multiple objects and you want to save the height, width and area of these objects, just loop over each one, find the quantities you desire, place them into an overall matrix and save it:
X = zeros(3, numel(objects));
for k = 1 : numel(objects)
k1=objects{k}; %// Change
c1=rgb2gray(k1);
t1=graythresh(c1);
biner1=im2bw(c1,t1);
[height, width] = size(biner1);
a1 = bwarea(biner1);
X(:,k) = [height;width;a1];
end
save datagrading.txt X -ascii
X is now a 3 x s matrix where s is the total number of objects you have. Therefore, each column contains the height, width and area of each object.
You declared
[height, width] = size(biner1);
So height(biner1) will refer to the biner1-th element of height, which is not existent.
Use X = [(height);(width);(a1)]; instead.

Image Based Visual Servoing algorithm in MATLAB

I was trying to implement the IBVS algorithm (the one explained in the Introduction here) in MATLAB myself, but I am facing the following problem : The algorithm seems to work only for the cases that the camera does not have to change its orientation in respect to the world frame.For example, if I just try to make one vertex of the initial (almost) square go closer to its opposite vertex, the algorithm does not work, as can be seen in the following image
The red x are the desired projections, the blue circles are the initial ones and the green ones are the ones I get from my algorithm.
Also the errors are not exponentially dereasing as they should.
What am I doing wrong? I am attaching my MATLAB code which is fully runable. If anyone could take a look, I would be really grateful. I took out the code that was performing the plotting. I hope it is more readable now. Visual servoing has to be performed with at least 4 target points, because else the problem has no unique solution. If you are willing to help, I would suggest you take a look at the calc_Rotation_matrix() function to check that the rotation matrix is properly calculated, then verify that the line ds = vc; in euler_ode is correct. The camera orientation is expressed in Euler angles according to this convention. Finally, one could check if the interaction matrix L is properly calculated.
function VisualServo()
global A3D B3D C3D D3D A B C D Ad Bd Cd Dd
%coordinates of the 4 points wrt camera frame
A3D = [-0.2633;0.27547;0.8956];
B3D = [0.2863;-0.2749;0.8937];
C3D = [-0.2637;-0.2746;0.8977];
D3D = [0.2866;0.2751;0.8916];
%initial projections (computed here only to show their relation with the desired ones)
A=A3D(1:2)/A3D(3);
B=B3D(1:2)/B3D(3);
C=C3D(1:2)/C3D(3);
D=D3D(1:2)/D3D(3);
%initial camera position and orientation
%orientation is expressed in Euler angles (X-Y-Z around the inertial frame
%of reference)
cam=[0;0;0;0;0;0];
%desired projections
Ad=A+[0.1;0];
Bd=B;
Cd=C+[0.1;0];
Dd=D;
t0 = 0;
tf = 50;
s0 = cam;
%time step
dt=0.01;
t = euler_ode(t0, tf, dt, s0);
end
function ts = euler_ode(t0,tf,dt,s0)
global A3D B3D C3D D3D Ad Bd Cd Dd
s = s0;
ts=[];
for t=t0:dt:tf
ts(end+1)=t;
cam = s;
% rotation matrix R_WCS_CCS
R = calc_Rotation_matrix(cam(4),cam(5),cam(6));
r = cam(1:3);
% 3D coordinates of the 4 points wrt the NEW camera frame
A3D_cam = R'*(A3D-r);
B3D_cam = R'*(B3D-r);
C3D_cam = R'*(C3D-r);
D3D_cam = R'*(D3D-r);
% NEW projections
A=A3D_cam(1:2)/A3D_cam(3);
B=B3D_cam(1:2)/B3D_cam(3);
C=C3D_cam(1:2)/C3D_cam(3);
D=D3D_cam(1:2)/D3D_cam(3);
% computing the L matrices
L1 = L_matrix(A(1),A(2),A3D_cam(3));
L2 = L_matrix(B(1),B(2),B3D_cam(3));
L3 = L_matrix(C(1),C(2),C3D_cam(3));
L4 = L_matrix(D(1),D(2),D3D_cam(3));
L = [L1;L2;L3;L4];
%updating the projection errors
e = [A-Ad;B-Bd;C-Cd;D-Dd];
%compute camera velocity
vc = -0.5*pinv(L)*e;
%change of the camera position and orientation
ds = vc;
%update camera position and orientation
s = s + ds*dt;
end
ts(end+1)=tf+dt;
end
function R = calc_Rotation_matrix(theta_x, theta_y, theta_z)
Rx = [1 0 0; 0 cos(theta_x) -sin(theta_x); 0 sin(theta_x) cos(theta_x)];
Ry = [cos(theta_y) 0 sin(theta_y); 0 1 0; -sin(theta_y) 0 cos(theta_y)];
Rz = [cos(theta_z) -sin(theta_z) 0; sin(theta_z) cos(theta_z) 0; 0 0 1];
R = Rx*Ry*Rz;
end
function L = L_matrix(x,y,z)
L = [-1/z,0,x/z,x*y,-(1+x^2),y;
0,-1/z,y/z,1+y^2,-x*y,-x];
end
Cases that work:
Ad=2*A;
Bd=2*B;
Cd=2*C;
Dd=2*D;
Ad=A+1;
Bd=B+1;
Cd=C+1;
Dd=D+1;
Ad=2*A+1;
Bd=2*B+1;
Cd=2*C+1;
Dd=2*D+1;
Cases that do NOT work:
Rotation by 90 degrees and zoom out (zoom out alone works, but I am doing it here for better visualization)
Ad=2*D;
Bd=2*C;
Cd=2*A;
Dd=2*B;
Your problem comes from the way you move the camera from the resulting visual servoing velocity. Rather than
cam = cam + vc*dt;
you should compute the new camera position using the exponential map
cam = cam*expm(vc*dt)

Skipping some axis labels in a plot with imagesc

I have created a big heat map using matlab's imagesc command. It plots the error output for each combination of the values in x and y axes. As can be seen in the figure there are too many axes labels. This might become even denser as I plan to increase the number of points in both x and y axes - which means I will get more outputs on a finer grid.
I want to be flexible with the labels, and skip some of them. I want to do this for both X and Y. I also want to be flexible with the "ticks" and draw either all of them or maybe skip some of them. Keep in mind that both the X and Y values are not increasing in order, at first the increment is 0.01 for 9 points, then 0.1, then 1 or 3 or whatever. I will change these increments too.
I tried to show what I want the graph look like in the second image. I want roughly the labels shown in red boxes only. As I said these are not set values, and I will make the increments smaller which will lead to denser plot.
Thank you for your help.
OS: Windows 7, 8 (64 bit)
Matlab version: Matlab 2014 a
You can manipulate the ticks and labels like this:
ticksarray=[1 33 41 100 ...] % edit these to whatever you want
tickslabels={'1', '33', '41', '100'; ...} % match the size of both arrays
set(gca,'XTick',ticksarray)
set(gca,'XTickLabel',tickslabels)
The same thing applies to the y-axis.
Small working example:
x=1:100;
y=2*x.^2-3*x+2;
plot(x,y)
ticksarray=[1 33 41 100];
tickslabels={'1', '33', '41', '100'};
set(gca,'XTick',ticksarray)
set(gca,'XTickLabel',tickslabels)
Example:
figure(1)
load clown
subplot(211)
imagesc(X);
subplot(212)
imagesc(X);
h = gca;
Now you can either set a maximum number of labels per axis:
%// define maximum number of labels
maxLabel = 3;
h.XTick = linspace(h.xlim(1),h.xlim(2),maxLabel);
h.YTick = linspace(h.ylim(1),h.ylim(2),maxLabel);
or define how many labels should be skipped:
%// define number of labels to skip
skipLabel = 2;
h.XTick = h.XTick(1:skipLabel:end);
h.YTick = h.YTick(1:skipLabel:end)
You can also get a different number of ticks and labels, more complicated though:
maxLabel = 3;
maxTicks = 6;
h.XTick = linspace(h.xlim(1),h.xlim(2),maxTicks);
h.YTick = linspace(h.ylim(1),h.ylim(2),maxTicks);
h.XTickLabel( setdiff( 1:maxTicks, 1:maxTicks/maxLabel:maxTicks ) ) = repmat({''},1,maxTicks-maxLabel);
h.YTickLabel( setdiff( 1:maxTicks, 1:maxTicks/maxLabel:maxTicks ) ) = repmat({''},1,maxTicks-maxLabel);
If you use a prior version of Matlab 2014b, then you will need the set command to set all properties:
%// define maximum number of labels
maxLabel = 3;
Xlim = get(h,'Xlim');
Ylim = get(h,'Ylim');
set(h,'XTick', linspace(Xlim(1),Xlim(2),maxLabel));
set(h,'YTick', linspace(Ylim(1),Ylim(2),maxLabel));
%// or define number of labels to skip
skipLabel = 2;
XTick = get(h,'XTick');
YTick = get(h,'YTick');
set(h,'XTick', XTick(1:skipLabel:end));
set(h,'YTick', YTick(1:skipLabel:end));
%// or combined
maxLabel = 3;
maxTicks = 6;
Xlim = get(h,'Xlim');
Ylim = get(h,'Ylim');
set(h,'XTick', linspace(Xlim(1),Xlim(2),maxTicks));
set(h,'YTick', linspace(Ylim(1),Ylim(2),maxTicks));
XTickLabel = cellstr(get(h,'XTickLabel'));
YTickLabel = cellstr(get(h,'YTickLabel'));
XTickLabel( setdiff( 1:maxTicks, 1:maxTicks/maxLabel:maxTicks ),: ) = repmat({''},1,maxTicks-maxLabel);
YTickLabel( setdiff( 1:maxTicks, 1:maxTicks/maxLabel:maxTicks ),: ) = repmat({''},1,maxTicks-maxLabel);
set(h,'XTickLabel',XTickLabel);
set(h,'YTickLabel',YTickLabel);
After applying the second method proposed by #thewaywewalk I got the second figure below. Apparently the labels need to be structured as well, because they only take the first so many labels.
Then I tried to manipulate the labels as shown below, and got the third image.
skipLabel = 2;
XTick = get(h,'XTick');
YTick = get(h,'YTick');
set(h,'XTick', XTick(1:skipLabel:end));
set(h,'YTick', YTick(1:skipLabel:end));
XTickLabel = get(h,'XTickLabel');
labelsX = cell( length(1: skipLabel:length(XTick)) , 1);
j = 1;
for i = 1: skipLabel:length(XTick)
labelsX{j} = XTickLabel(i, :);
j = j + 1;
end
set(h,'XTickLabel', labelsX);
YTickLabel = get(h,'YTickLabel');
labelsY = cell( length(1: skipLabel:length(YTick)) , 1);
j = 1;
for i = 1: skipLabel:length(YTick)
labelsY{j} = YTickLabel(i, :);
j = j + 1;
end
set(h,'YTickLabel', labelsY);
The Y axis labels seem to be in place as before (right next to tick), however the X axis labels seem to be shifted to the left a little. How can I correct this?
Another note: How can I change the scientific values into normal numbers? Also, probably there is a better approach at manipulating the labels.

matlab plot graph of data over an image

What I would like to do is plot an image of a graph (from say a pdf file or a scanned image). Next, I would like to overlay an axis on the graph in the image, and then plot data on that axis (over the image).
Using imtool, I know the coordinates of the graph in the image (x range = ~52-355 pixels, and y range = 23(top) - 262(bottom) pixels in this case).
This is what I have tried:
I = imread('C:\MATLAB\R2014a\help\images\ref\ftrans2_fig.png');
I = squeeze(uint8(mean(I,3)));
figure, imshow(I)
[rows, cols] = size(I);
x_data = (-1 : .01 : +1)';
y_data = 1 - x_data.^2;
h1 = axes('Position',([52, 23, 355-52, 262-23] ./ [cols, rows, cols, rows] ));
set(h1, 'Color', 'none')
hold on
plot(x_data, y_data, '-rx')
Question: Knowing the pixel coordinates of the graph in the image, how do I determine the proper position of the axis in the figure, (my code fails to account for the actual size of the figure box, the gray border around the image). I have to do this for several images and sets of data, so I would like an automated method, assuming I find the coordinates of the graphs in the image ahead of time.
Thanks for your reply! (1st time posting, please be kind)
You may be able to solve your problem by forcing the image onto the same axis as the plot. Try this:
I = imread('C:\MATLAB\R2014a\help\images\ref\ftrans2_fig.png');
I = squeeze(uint8(mean(I,3)));
[rows, cols] = size(I);
x_data = (-1 : .01 : +1)';
y_data = 1 - x_data.^2;
h1 = axes('Position',([52, 23, 355-52, 262-23] ./ [cols, rows, cols, rows] ));
set(h1, 'Color', 'none')
hold on
image(I, 'Parent', h1);
plot(h1, x_data, y_data, '-rx')
That should at ensure that the plot axis and the image axis have the same origin, as they will be one and the same. You may need to adjust your sizing code. Let me know if that doesn't do it for you.
Good Luck!
I think I have it figured out.
It would have been easier if I could use:
figure, h1=imshow(I)
get(h1,'Position')
but that results in "The name 'Position' is not an accessible property for an instance of class 'image'."
Instead, this appears to work:
I = imread('C:\MATLAB\R2014a\help\images\ref\ftrans2_fig.png');
I = squeeze(uint8(mean(I,3)));
in_mag = 300;
figure, imshow(I, 'Border', 'tight', 'InitialMagnification', in_mag)
[rows, cols] = size(I);
x_data = (-1 : .01 : +1)';
y_data = 1 - x_data.^2;
% Coord of graph in image pixels
x_0 = 50; x_max = 354; y_0 = 262; y_max = 23;
h1 = axes('Position',([x_0, rows-y_0, x_max-x_0, y_0-y_max] ...
./ [cols, rows, cols, rows] ));
set(h1,'Color','none')
hold on
plot(x_data, y_data, '-rx')
ylim([0,1.4])
set(gca,'YColor', [0 0 1], 'XColor', [0 0 1])
However, if anybody has a better idea, I would be very happy to explore it!
Thanks

Resources