Imagesc ButtonDownFcn problems in MATLAB, using custom toolbar action - matlab

I'm trying to use the ButtonDownFcn on an imagesc figure in MATLAB. I want to enable this function by clicking on a custom button I have created on the toolbar.
The ButtonDownFcn will call methods that will cause it to return the position of the pixel selected using the ButtonDownFcn, so that I can graph how that pixel changes through time.
NOTES:
- I am using GUIDE in matlab
- imagesc is plotting a 3D matrix. I already have implemented code that allows me to travel through how the image changes through time, using a button created in GUIDE.
What I am struggling with, at the moment, is the ButtonDownFcn of the imagesc. I've read over and over on how to do this (through research on the internet), but I can't seem to get it to work.
Any help is appreciated.
Here is my code:
% --------------------------------------------------------------------
function ui_throughTime_ClickedCallback(hObject, eventdata, handles)
% hObject handle to ui_throughTime (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
valS = get(handles.txt_zaxis,'string');
display(valS);
val = str2num(valS);
d = handles.data;
m = imagesc(d(:,:,val),'parent',handles.axis, 'HitTest', 'off','buttondownfcn',{#getPlace, handles});
set(handles.axis,'buttondownfcn',{#getPlace, handles,m});
function getPlace(hObject,handles,event_obj,place)
% data = randn(120,160);
% ax = axes;
% imagesc(data,);
if (gcf == place)
pause(1);
cursor = get(handles.axis,'CurrentPoint'); % get point
% Get X and Y from point last clicked on the axes
x = (cursor(1,1));
y = (cursor(1,2));
disp(['x = ' num2str(x) ' y = ' num2str(y)]);
end

Here is a simple example:
%% Init
fig_h = figure('CloseRequestFcn', 'run = 0; delete(fig_h);');
rgb = imread('peppers.png');
run = 1; t = 0;
%% Loop
while run
t = t + 0.05;
imagesc(rgb*sin(t), 'ButtonDownFcn', 'disp(''Clicked'')');
pause(0.01);
end
Above the 'ButtonDownFcn' of the image is being used so the 'HitTest' property of the image must be 'On'.
Below is the case that the 'ButtonDownFcn' of the axes are used and since the image is in front of the axes, 'HitTest' property of the image should be 'Off' or the axes won't be selectable.
%% Loop
ax = axes;
while run
t = t + 0.05;
imagesc(rgb*sin(t), 'Parent', ax, 'HitTest', 'Off');
set(ax, 'ButtonDownFcn', 'disp(''Clicked'')')
pause(0.01);
end
It's also possible to use the figure 'ButtonDownFcn' and again the image 'HitTest' should be 'Off'. However in this case clicked points of outside of the image ( or interested area) should be filtered programmatically.
Hope it helps.

Related

Print ONLY plot on MATLAB GUI

How can I print ONLY the plot created by my MATLAB GUI into a PDF document?
I know about the function available online called export_fig, but we are not allowed to make use of externally coded tools for this.
I currently have the following
function PrintButton_Callback(hObject, eventdata, handles)
set(gcf,'PaperType','A4','PaperOrientation','landscape','PaperPositionMode','auto');
print(get(handles.Axes,'Parent'), '-dpdf','Results.pdf');
However, this results in my entire GUI figure being saved.
How can I select ONLY the plot made by my axes ("Axes")?
The print command only accepts a figure as handle parameter ...
To print specified axis only a trick is to copy this axis to a new temporary figure using copyobj and use print command on the new figure.
Here is some sample code:
%% -- Test code
function [] = TestPrint()
%[
% Create figure with two axes
fig = figure(1); clf;
ax1 = subplot(1,2,1);
plot(rand(1, 12));
ax2 = subplot(1,2,2);
plot(rand(1, 12));
% Print the whole figure
print(fig, '-dpdf', 'figure.pdf');
% Print ONLY second axis
printAxis(ax2, '-dpdf', 'axis.pdf');
%]
end
%% --- Print specified axis only
% NB: Accept same arguments as 'print' except for first one which now is an axis.
function [] = printAxis(ax, varargin)
%[
% Create a temporary figure
visibility = 'on'; % You can set it to off if you want
tempFigure = figure('Visible', visibility);
cuo = onCleanup(#()clearTempFigure(tempFigure)); % Just to be sure to destroy the figure
% Copy selected axis to the temporary figure
newAx = copyobj(ax, tempFigure);
% Make it fill whole figure space
set(newAx, 'OuterPosition', [0 0 1 1]);
% Print temporary figure
print(tempFigure, varargin{1:end});
%]
end
function [] = clearTempFigure(h)
%[
if (ishandle(h)), delete(h); end
%]
end
Disable axes visibility: set(gca,'Visible','off') before printing.

Trying to do find the centroid of a section of an image in Matlab

I am trying to find a way to draw a box around a section of an image in Matlab and find the centroid of that image. I would ideally want the "new" section to show up next to my original image, then I can to the centroid of that "new" image.
Here is my code:
% --- Executes on button press in pushbutton15.
function pushbutton15_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton15 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
A = imread('PET_MRI_Brain_Tumor.jpg');
Z = imshow(A)
Ibw = im2bw(A);
Ibw = imfill(Ibw,'holes');
Ilabel = bwlabel(Ibw);
stat = regionprops(Ilabel,'centroid');
imshow(Z); hold on;
for x = 1: numel(stat)
plot(stat(x).Centroid(1),stat(x).Centroid(2),'bx');
end
e = imellipse(gca,[55 10 120 120])
BW = createMask(e,Z)
Here is the image that I am trying to put a mask over and find the centroid of that section.
Once you have a BW mask like this:
e = imellipse(gca,[55 10 120 120])
BW = createMask(e,Z)
or that has created with any other method (e.g. imfreehand or some type of segmentation algorithm), you can use 'regionprops':
s = regionprops(BW, 'Centroid');
If there is only one area/"region" in the BW image, the centroid is just:
s(1).Centroid

Finding pixel location of centroid in a region

I have an image in Matlab where I am finding the all the centroids in it. There are multiple centroids in the image and I am using 'imellipse' to seclude one of them. I am trying to find the pixel location of one of centroids. Having the location pop-up in the command window of Matlab will be good enough.
Here is my code:
% --- Executes on button press in pushbutton15.
function pushbutton15_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton15 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
A = imread('PET_MRI_Brain_Tumor.jpg');
Z = imshow(A)
Ibw = im2bw(A);
Ibw = imfill(Ibw,'holes');
Ilabel = bwlabel(Ibw);
stat = regionprops(Ilabel,'centroid');
imshow(Z); hold on;
for x = 1: numel(stat)
plot(stat(x).Centroid(1),stat(x).Centroid(2),'bx');
end
e = imellipse(gca,[55 10 120 120])
BW = createMask(e,Z)
Here is the picture where I am trying to extrapolate the pixel location of the centroid marker.
http://imgur.com/DnSQTUi

Handling multiple plots in MATLAB

I am using plot(X) whereX is an n-by-k matrix, which produces k plots with n points.
How do I show the legend for this plot? More importantly, is there an easy way to show checkboxes to show or not show certain plots?
I think you can find this section of Documentation useful.
GUI that Displays and Graphs Tabular Data
http://www.mathworks.com/help/techdoc/creating_guis/bropmbk-1.html
Please use this body for plot_callback function in tableplot.m file to get a dirty implementation of the flexible legend.
function plot_callback(hObject, eventdata, column)
% hObject Handle to Plot menu
% eventdata Not used
% column Number of column to plot or clear
colors = {'b','m','r'}; % Use consistent color for lines
colnames = get(htable, 'ColumnName');
colname = colnames{column};
lgidx = get(haxes, 'UserData');
if isempty(lgidx)
lgidx = false(size(colnames));
end
if get(hObject, 'Value')
% Turn off the advisory text; it never comes back
set(hprompt, 'Visible', 'off')
% Obtain the data for that column
ydata = get(htable, 'Data');
set(haxes, 'NextPlot', 'Add')
% Draw the line plot for column
hplot = plot(haxes, ydata(:,column),...
'DisplayName', colname,...
'Color', colors{column});
lgidx(column) = true;
else % Adding a line to the plot
% Find the lineseries object and delete it
hplot = findobj(haxes, 'DisplayName', colname);
lgidx(column) = false;
delete(hplot);
end
if any(lgidx)
legend(haxes, colnames{lgidx} );
else
legend(haxes, 'off')
end
set(haxes, 'UserData', lgidx);
end
An example:
x = cumsum(rand(100,3)-0.5); %# three series with 100 points each
h = plot(x);
legend(h, {'first' 'second' 'third'})

How can I put a background image in a movie in matlab

I need to put a background image in a movie created using MATLAB?
I have posted below an example code of how I am generating a movie in Matlab. I need to add a background image to this movie. Thanks for your help.
for i=1:128
for j=1:128
p(i,j,:)=randn(1,200);
end
end
[u,v,w]=size(p);
frm_r=1:128;
frm_c=1:128;
figure; j=1;
for t=1:w
surface(frm_c,frm_r,p(:,:,t),'EdgeColor','none');
pause(0.1)
colorbar;
F(j) = getframe;
j=j+1;
end
movie(F,1,50)
If you have access to MATLAB code that creates movie, you can place an axes with IMAGE or IMSHOW as a background and make axes on the top of it transparent.
Here is a simple example:
im = image; % create image object (default pic)
imax = get(im,'parent'); % get image axes handle
axis ij
set(imax,'position',[0 0 1 1]) % make it to fill the whole figure
ax = axes; % new axes
h = plot(ax,rand(100),'ro'); % initial plot
for i=1:20
set(h,'ydata',rand(100,1)); % change the data in a loop
pause(0.1)
end
You can get get better answer if you show your code how you create a movie.
EDIT:
I simplified the code in your answer a little. For example you don't need loops to fill up 3D array. And you don't need to repeat surface function in the loop. Just change zdata property.
Try this code (substitute yourimage.jpg to real file name):
p = randn(128,128,200);
[u,v,w]=size(p);
frm_r=1:128;
frm_c=1:128;
figure;
im = imshow('yourimage.jpg'); % create and display image object from a file
imax = get(im,'parent'); % get image axes handle
set(imax,'position',[0 0 1 1]) % make it to fill the whole figure
ax = axes('color','none'); % new axes
hsurf = surface(frm_c,frm_r,p(:,:,1),'EdgeColor','none','Parent',ax);
colorbar;
xlim([1 u])
ylim([1 v])
j=1;
for t=1:w
set(hsurf,'zdata',p(:,:,t))
F(j) = getframe;
j=j+1;
end
movie(F,1,50)