I would like to convert a video file using rgb2gray on the videoframes, thing is i'm not completely sure how.
I have got this script file, playing the video file using a slider:
%-------------------------------------------------------------------
function frametracking()
%# read all frames at once
filename = uigetfile('*.avi');
vid = VideoReader(filename);
numImgs = get(vid, 'NumberOfFrames');
frames = read(vid);
% Make the UI
mx = numImgs-1;
hFig = figure('Menubar','none');
uicontrol('Style','slider', 'Parent',hFig, ...
'Callback',#slider_callback, ...
'Units','pixels', 'Position',[150 0 260 20], ...
'Value',1, 'Min',1, 'Max',mx, 'SliderStep',[1 10]./mx);
pB1 = uicontrol(hFig, 'Position',[150 20 130 20], ...
'Units','pixels', ...
'String','Select file', ...
'Callback',#button1_callback);
pB2 = uicontrol(hFig, 'Position',[280 20 130 20], ...
'Units','pixels', ...
'String','Calibrate', ...
'Callback',#button2_callback);
eT1 = uicontrol(hFig, 'Style','edit',...
'Units','pixels',...
'Position',[490 400 60 20],...
'CallBack',#edit1_callback,...
'String','');
eT2 = uicontrol(hFig, 'Style','edit',...
'Units','pixels',...
'Position',[490 370 60 20],...
'CallBack',#edit2_callback,...
'String','');
eT3 = uicontrol(hFig, 'Style','edit',...
'Units','pixels',...
'Position',[490 370 60 20],...
'CallBack',#edit3_callback,...
'String','');
hAx = axes('Parent',hFig,'units','pixels',...
'Position',[80 80 400 400]);
grayframe = rgb2gray(frames(:,:,:,1));
hMainImg = imshow(grayframe(:,:,:,1), 'Parent',hAx);
%# callback functions
function slider_callback(src,~)
val = round(get(src,'Value')); %# starting index
%# update the thumbnails
for ii = 1 : numel(hMainImg)
set(hMainImg(ii), 'CData',frames(:,:,:,ii+val-1))
drawnow
end
end
function click_callback(src,~)
%# update the main image
% grayframe = rgb2gray(frames(:,:,:,1));
set(hMainImg, 'CData',get(src,'CData'));
drawnow
end
function button1_callback(src,~)
end
end
%-------------------------------------------------------------------
At line 40 i've added: grayframe = rgb2gray(frames(:,:,:,1));, this makes the first frame gray. How do I make this count for all frames? My goal is to track an object in the videoframe, so I want to convert the frames to binary images aswell, and apply a additional filter like edge detection or something similar.
Thanks in advance
for i=1:numImgs
frames(:,:,:,i)=rgb2gray(frames(:,:,:,i));
end
I'd rather get rid of rgb2gray and vectorize it
GRAYframes = uint8(mean(RGBframes,3));
1- construct a VideoReader object
2- read each frame and convert it to grayscale using RGB2GRAY
3- playback the video
clear
clc
obj = VideoReader('xylophone.mp4');
nFrames = obj.NumberOfFrames;
vidHeight = obj.Height;
vidWidth = obj.Width;
mov(1:nFrames) =struct('cdata',zeros(vidHeight,vidWidth,1,'uint8'),...
'colormap',[]);
% Read one frame at a time.
for k = 1 : nFrames
mov(k).cdata =rgb2gray( read(obj,k));
end
implay(mov);
Related
I tried to write an animation code in Matlab that repeats itself in every two seconds. The core animation scheme is as below:
Please take care the gif is repeating the core animation, originally there is only one cycle.
Here is the code:
% Figure settings
h= figure(2);
set(h, 'Position', [100 50 1200 750])
set(h,'Toolbar','None','Menubar','None')
set(h,'Name','Animation')
set(gcf,'doublebuffer','off');
set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual',...
'climmode','manual','alimmode','manual');
xlim([-200 1350])
ylim([-250 800])
set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);
%Parameters
diameter = 60; %spot çapı
RamanX = 350; %ölçüm noktssı x konumu
nOfSpots = 4; %spot sayısı
spotCount = 0; %toplam spot sayısı
initPos = [50 150;50 300; 50 450; 50 600]; %konum 1
posII = [350 150;350 300; 350 450; 350 600]; %konum 2
Choice = rand(1,4)<.5; %Ölçüm sonunda verilen karar
deltaY2 = 100; % spotlar arası mesafe
x11 = zeros(nOfSpots,2);
x22 = zeros(nOfSpots,2);
x22a = zeros(nOfSpots,2);
x22b = zeros(nOfSpots,2);
for i=1:nOfSpots
x11(i,:) = [RamanX 150*(i-1)];
x22(i,:) = [800 50+deltaY2*(i-1)];
end
for i=1:nOfSpots/2
x22a(2*i-1,:) = [1280 -270+250*(i-1)];
x22a(2*i,:) = [1075 -270+250*(i-1)];
x22b(2*i-1,:) = [1280 220+250*(i-1)];
x22b(2*i,:) = [1075 220+250*(i-1)];
end
%Add 4 Circles to initial position
for i=1:nOfSpots
% Drag & Drop elipsler yerleştiriliyor
spot(i) = imellipse(gca, [initPos(i,1),initPos(i,2),diameter,diameter]);
spotCount = spotCount+1;
%elips özellikleri
setFixedAspectRatioMode(spot(spotCount), 'TRUE');
setResizable(spot(spotCount),0);
posSpot(spotCount,:) = getPosition(spot(i));
end
%Move Circles to posII
r = sqrt(sum(bsxfun(#minus,posII(:,1),initPos(:,1)).^2,2));
v = 30;
stepsize = ceil(r/v);
xstep = (posII(:,1)-initPos(:,1))/stepsize;
for i=1:stepsize
for j=1:nOfSpots
setPosition(spot(j), [initPos(j,1)+xstep(j)*i, initPos(j,2), diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
pause(0.15)
end
%Move Circles to posIII
velocity = 30;
r2a = sqrt(sum(bsxfun(#minus,x22a,x11).^2,2));
stepsize2a = max(ceil(r2a/velocity));
r2b = sqrt(sum(bsxfun(#minus,x22a,x11).^2,2));
stepsize2b = max(ceil(r2b/velocity));
% Eğer öllçüm seçimi 1 ise taşı
for i=1:nOfSpots
if(Choice(i))
xstep2(i) = (x22a(i,1)-x11(i,1))./stepsize2a;
ystep2(i) = (x22a(i,2)-x11(i,2))./stepsize2a;
else
xstep2(i) = (x22b(i,1)-x11(i,1))./stepsize2b;
ystep2(i) = (x22b(i,2)-x11(i,2))./stepsize2b;
end
end
stepsize2 = max([stepsize2a stepsize2b]);
% Eğer ölçüm seçimi 0 ise taşı
for i=1:stepsize2
for j=1:nOfSpots
if(Choice(j))
setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
end
pause(0.15)
end
for i=1:stepsize2
for j=1:nOfSpots
if(~Choice(j))
setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
end
pause(0.15)
end
if(spotCount > 0)
for i=1:4
delete(spot(i))
end
end
The code doing this is a script not a function, say "animation.m". Now I am trying repeat this code in every 2 seconds. I tried to use loops with tic - toc commands, but the loop does not go to other cycle before finishing "animation.m". I need to get it work in the background.
One of my friend suggested me to use trigger. But, honestly, I could not apply the trigger command for my code even when I functionalized it.
Any help?
Edit:
The graphical flow chart of the problem is below:
I created an example that shows how it could be done.
Modifying your code, to draw just "one animated step" was too much work.
I decided to used your code to create all frames from advance (for example purpose).
I guess you are going to realize, that implementing background animation in Matlab is more difficult than you thought (unless I missed some hidden Matlab feature).
Matlab has very limited threading support, so I used a periodic timer.
My code sample does the following:
Build animation - create a cell array of all animated images.
You should avoid it, because it takes to much time (and memory).
I used it instead of modifying your code to draw one animated image.
Setup a periodic timer object with 0.2 seconds period (0.2 as an example).
I added a loop that illustrates the foreground processing (calculating sin(x) as an example).
Notice: I added small pause in the "foreground processing" loop.
The timer invokes a callback function every 0.2 seconds.
In the callback function the next animated frame is shown.
The timer is used for simulating a background execution.
You should replace the imshow, with your "animation step" function, that draws the frame (instead of showing a frame created from advance).
Here is the code sample (with your modified code included):
function TimerAnimation()
%Build set of images for animation.
[h_figure, Frames] = BuildAnimation();
t = timer;
t.TimerFcn = #timerFcn_Callback; %Set timer callback function
t.ExecutionMode = 'fixedRate'; %Set mode to "singleShot" - execute TimerFcn only once.
t.StartDelay = 0.1; %Wait 0.1 second from start(t) to executing timerFcn_Callback.
t.Period = 0.2; %Set period to 0.2 seconds.
%Turn on figure visibility
set(h_figure, 'Visible', 'on');
frame_counter = 1;
start(t) %Start timer;
%Do some other job...
%The animation is executed in the background (kind of in the background).
for x = 1:20000
y = sin(x/10000); %Calculate somthing...
if (mod(x, 100) == 0)
disp(['sin(', num2str(x/10000), ') = ', num2str(y)]); %Display somthing...
end
if (~isvalid(h_figure))
%Break loop if user closed the animation figure.
break;
end
%Must insert pause to "tight loop", allowing animation to run.
pause(0.01);
end
stop(t) %Stop timer;
delete(t); %Delete timer object.
if (~isvalid(h_figure))
close(h_figure);
end
%Timer function is executed every period of 0.2 seconds.
function timerFcn_Callback(mTimer, ~)
%Increse animation frame counter.
%figure(h_figure); %Set fo h_figure to be active figure.
h_axes = get(h_figure, 'CurrentAxes'); %Get axes of h_figure
imshow(Frames{frame_counter}, 'Parent', h_axes); %Display frame number frame_counter.
drawnow; %Force refresh.
frame_counter = mod(frame_counter, length(Frames)) + 1; %Advance to next frame (cyclically).
end
end
function [h, Frames] = BuildAnimation()
%Build set of images for animation.
%h - return handle to figure
%Frames - return cell array of animation images.
counter = 1;
% Figure settings
%h = figure(2);
%Create invisible figure.
h = figure('Visible', 'off');
set(h, 'Position', [100 50 1200 750])
set(h,'Toolbar','None','Menubar','None')
set(h,'Name','Animation')
set(gcf,'doublebuffer','off');
set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual',...
'climmode','manual','alimmode','manual');
xlim([-200 1350])
ylim([-250 800])
set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);
%Parameters
diameter = 60; %spot ?ap?
RamanX = 350; %?l??m noktss? x konumu
nOfSpots = 4; %spot say?s?
spotCount = 0; %toplam spot say?s?
initPos = [50 150;50 300; 50 450; 50 600]; %konum 1
posII = [350 150;350 300; 350 450; 350 600]; %konum 2
Choice = rand(1,4)<.5; %?l??m sonunda verilen karar
deltaY2 = 100; % spotlar aras? mesafe
x11 = zeros(nOfSpots,2);
x22 = zeros(nOfSpots,2);
x22a = zeros(nOfSpots,2);
x22b = zeros(nOfSpots,2);
for i=1:nOfSpots
x11(i,:) = [RamanX 150*(i-1)];
x22(i,:) = [800 50+deltaY2*(i-1)];
end
for i=1:nOfSpots/2
x22a(2*i-1,:) = [1280 -270+250*(i-1)];
x22a(2*i,:) = [1075 -270+250*(i-1)];
x22b(2*i-1,:) = [1280 220+250*(i-1)];
x22b(2*i,:) = [1075 220+250*(i-1)];
end
%Add 4 Circles to initial position
for i=1:nOfSpots
% Drag & Drop elipsler yerle?tiriliyor
spot(i) = imellipse(gca, [initPos(i,1),initPos(i,2),diameter,diameter]);
spotCount = spotCount+1;
%elips ?zellikleri
setFixedAspectRatioMode(spot(spotCount), 'TRUE');
setResizable(spot(spotCount),0);
posSpot(spotCount,:) = getPosition(spot(i));
end
%Move Circles to posII
r = sqrt(sum(bsxfun(#minus,posII(:,1),initPos(:,1)).^2,2));
v = 30;
stepsize = ceil(r/v);
xstep = (posII(:,1)-initPos(:,1))/stepsize;
for i=1:stepsize
for j=1:nOfSpots
setPosition(spot(j), [initPos(j,1)+xstep(j)*i, initPos(j,2), diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
%pause(0.15)
%Get frame, convert frame to image, and store image in Frames
Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end
%Move Circles to posIII
velocity = 30;
r2a = sqrt(sum(bsxfun(#minus,x22a,x11).^2,2));
stepsize2a = max(ceil(r2a/velocity));
r2b = sqrt(sum(bsxfun(#minus,x22a,x11).^2,2));
stepsize2b = max(ceil(r2b/velocity));
% E?er ?ll??m se?imi 1 ise ta??
for i=1:nOfSpots
if(Choice(i))
xstep2(i) = (x22a(i,1)-x11(i,1))./stepsize2a;
ystep2(i) = (x22a(i,2)-x11(i,2))./stepsize2a;
else
xstep2(i) = (x22b(i,1)-x11(i,1))./stepsize2b;
ystep2(i) = (x22b(i,2)-x11(i,2))./stepsize2b;
end
end
stepsize2 = max([stepsize2a stepsize2b]);
% E?er ?l??m se?imi 0 ise ta??
for i=1:stepsize2
for j=1:nOfSpots
if(Choice(j))
setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
end
% pause(0.15)
%Get frame, convert frame to image, and store image in Frames
Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end
for i=1:stepsize2
for j=1:nOfSpots
if(~Choice(j))
setPosition(spot(j), [posII(j,1)+xstep2(j)*i, posII(j,2)+ystep2(j)*i, diameter, diameter] )
posSpot(spotCount,:) = getPosition(spot(j));
end
end
% pause(0.15)
%Get frame, convert frame to image, and store image in Frames
Frames{counter} = frame2im(getframe(h));counter = counter + 1;
end
if(spotCount > 0)
for i=1:4
delete(spot(i))
end
end
imshow(Frames{1})
end
Example for what I meant by "drawing just one animated step":
function TimerAnimation2()
%Initiazlie animation.
param = InitAnimation();
%Same code as in previous example.
t = timer;t.TimerFcn = #timerFcn_Callback;t.ExecutionMode = 'fixedRate';t.StartDelay = 0.1;t.Period = 0.2;start(t)
for x = 1:20000;if (~isvalid(param.h)), break;end;pause(0.01);end
stop(t);delete(t);if (isvalid(param.h)), close(param.h);end
%Timer function is executed every period of 0.2 seconds.
function timerFcn_Callback(mTimer, ~)
%Animation single step
param = StepAnimation(param);
end
end
function param = InitAnimation()
h = figure;
set(h, 'Position', [100 50 1200 750]);set(h,'Toolbar','None','Menubar','None');set(h,'Name','Animation');set(gcf,'doublebuffer','off');
set(gca, 'xlimmode','manual','ylimmode','manual','zlimmode','manual', 'climmode','manual','alimmode','manual');
xlim([-200 1350]);ylim([-250 800]);set(gca,'xtick',[],'ytick', [], 'Position', [0 0 1 1]);
%Initialize param struct (param struct keeps animation parameters).
param.h = h;
param.x = 10;
param.y = 10;
%Draw rectangle in position x, y
h_axes = get(param.h, 'CurrentAxes');
rectangle('Position', [param.x param.y 20 20], 'Parent', h_axes);
end
%Example fo single animation step
%Get exsiting animation param as input, and retuen updated param as output.
function param = StepAnimation(param)
h_axes = get(param.h, 'CurrentAxes');
%Update param (to be used in next StepAnimation).
param.x = param.x + 10;
param.y = param.y + 10;
if (param.x > 500), param.x = 10;end
if (param.y > 500), param.y = 10;end
%Draw rectangle in position x, y
rectangle('Position', [param.x param.y 20 20], 'Parent', h_axes)
drawnow; %Force refresh.
end
Display
G3.vardisp= uicontrol('Style','edit',...
'Position', [520 280 30 30],...
'String','0');
Slider
G3.slide = uicontrol('style','slide',...
'unit','pix',...
'position',[400 280 120 30],...
'min',-10,'max',10,'val',1,...
'sliderstep',[1/20 1/10],...
'callback',{#sl_call3,G3});
callback for Slider
function [] = sl_call3(varargin)
[l,G3] = varargin{[1,3]}; % calling handle and data structure.
set(G3.vardisp,'String',get(l,'value'))
vbrilho=get(l,'value')
subplot('Position',[.35, 0.575, 0.375, 0.375])
x4.head_mod=(vcontraste*x4.head)+(vbrilho*10);
imshow(x4.head_mod)
end
button
filtro.medfiltbtn1 = uicontrol('Parent',hsp,...
'Style', 'pushbutton',...
'String', 'medfilt2_1',...
'Position',[0 35 80 30],...
'callback',{#teste,1});
callback for button
function []= teste(varargin)
[t1] = varargin{[3]};
while t1==1
subplot('Position',[.35, 0.575, 0.375, 0.375])
x4.head_modf=imnoise(x4.head_mod,'gaussian',0,0.01);
t1=0;
imshow(x4.head_modf)
end
When the code is run the imnoise can be applied over the x4.head_mod, but I can't apply the equation (vcontraste*x4.head)+(vbrilho*10) over imnoise. I want somehow to nest both results.
I have got a GUI, which imports the data from a *.xls file and plots graph. The last thing I cannot do is the data refreshing, because my xls file updates each 15 sec. I want my GUI to update input data each 20 seconds. How can I do that? And also I would like to have a button which will have an ability to pause/run data updating.
function viewSTUEP
global hPlot hChoice raw
handles.F = figure('Name','viewSTUEP', 'Position',[100 20 900 550], ...
'Color',[0.8 0.8 0.8], 'NumberTitle','off', 'Resize','off');
uicontrol('Style','pushbutton', 'Position',[690 510 94 30], ...
'FontSize',12, 'String','Load', 'Callback',#LoadData);
uicontrol('Style','pushbutton', 'Position',[790 510 94 30], ...
'FontSize',12, 'String','Save plot', 'Callback',#SaveAs);
uicontrol('Style', 'pushbutton', 'Position', [690 475 94 30], ...
'FontSize',12, 'String','Update', 'Callback',#UpdatePlot);
uicontrol('Style','pushbutton', 'Position',[790 475 94 30], ...
'FontSize',12, 'String','Close', 'Callback',{#Close,handles});
set(handles.F, 'CloseRequestFcn', {#Close,handles})
set(gcf, 'Toolbar', 'figure');
clear raw, raw(1,:) = {''};
hPlot = axes('Position',[0.06 0.08 0.68 0.9], 'Visible','on');
uicontrol('Style','text', 'Position',[690 432 130 35], ...
'BackgroundColor',[0.8 0.8 0.8], 'FontSize',12, ...
'HorizontalAlignment','left', 'String','Columns for plot:');
hChoice = uicontrol('Style','listbox', 'Position',[690 420 204 22], ...
'FontSize',12, 'String',raw(1,:), 'Min',1, 'Max',1);
function Close(hObject, eventdata, handles)
delete(handles.F);
function LoadData(hObject, eventdata)
global hChoice raw xdat
[fname, pname] = uigetfile('*.xls','Select a data file');
if fname ~= 0
filename = strcat(pname, fname);
[numeric,text,raw] = xlsread(filename);
num = length(raw(1,:));
if (num > 21) num = 21; end
posY = 442 - (20*num);
set(hChoice, 'String',raw(1,:));
set(hChoice, 'Max',num);
set(hChoice, 'Position',[690 posY 204 (20*num)]);
xdat = datenum(0,0,0,0,0,cell2mat(raw(2:end,6)));
end
function UpdatePlot(hObject, eventdata)
global hPlot hChoice raw xdat
if ~isempty(raw)
cols = get(hChoice,'Value');
plot(hPlot, xdat,cell2mat(raw(2:end,cols(1))), 'LineWidth',2), datetick('x','HH:MM')
grid on
if (length(cols) > 1)
colors = 'brgcmyk'; c = 2;
hold(hPlot, 'on')
for k = cols(2:end)
plot(hPlot, xdat,cell2mat(raw(2:end,k)),colors(c),'LineWidth',2)
c = c+1; if (c > 7) c = 1; end
end
hold(hPlot, 'off')
end
legend(hPlot, raw(1,cols), 'Interpreter','none','Location','SouthEast')
xlabel(hPlot, 'Time in minutes:');
ylabel(hPlot, 'Temperature in C:');
end
function SaveAs(hObject, eventdata, handles)
[Save,savename] = uiputfile('*.eps','Save plot as: ')
fname=fullfile(savename,Save);
print('-depsc','-r300','-noui',fname)
I think you should use a timer object - see here
Unfortunately, I have two loops. that's why my code makes the first loop run and only when it is finished, it makes the second loop run.
But I want the gui to show the data simultaneously: in the hAxes and in the loading1.
How can I make it?
hFigure = figure('units','pixels','position',[300 300 424 470],'menubar','none',...
'name','start processing','numbertitle','off','resize','off');
hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]);
loading1 = uicontrol('style','text','unit','pix','position',[0 72 424 40],...
'backgroundcolor','r','fontsize',20);
%% shows the data on hAxes
for i = 5:100
if mod(i,2) == 0
set(hAxes,'Color','b');
else
set(hAxes,'Color','g');
end
drawnow;
end
%% shows the data on loading1
for i=1:200
image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
set(loading1,'string',image2);
drawnow;
end
this code is of Peter:
function test1
hFigure = figure('units','pixels','position',[300 300 424 470],'menubar','none','name','start processing','numbertitle','off','resize','off');
% Your other setup calls
hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]);
loading1 = uicontrol('style','text','unit','pix','position',[0 72 424 40],'backgroundcolor','r','fontsize',20);
c = 1;
t = timer('TimerFcn', #color_change_fcn,'StartDelay',1.0);
start(t);
for i=1:200
image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
set(loading1,'string',image2);
drawnow;
end
function color_change_fcn
if mod(c,2) == 0
set(hAxes,'Color','b');
else
set(hAxes,'Color','g');
end
drawnow;
c = c + 1;
end
end
It doesn't work (doesn't show the hAxes). I saw it doesn't make the color_change_fcn run (I tried to write: disp('test') in the first row of color_change_fcn function, but it prints nothing.
This seems to be related to your previous question, where you want the two loops to be running simultaneously (well at least appear to be that way).
Building on #Peter's answer, consider the following working example:
function timerDemo()
%# prepare GUI
hFig = figure('Menubar','none', 'Resize','off');
axes('XLim',[0 1], 'YLim',[0 1], 'Visible','off', ...
'Units','normalized', 'Position',[0.1 0.2 0.8 0.6])
hTxt = uicontrol('Style','text', 'FontSize',24, ...
'Units','normalized', 'Position',[0 0.9 1 0.1]);
hPatch = patch([0 0 1 1 0],[0 1 0 1 0],'k');
%# colors to cycle through
c = 1;
clr = lines(4);
%# create timer
delay = 0.5;
hTimer = timer('Period',delay, 'StartDelay',delay, ...
'ExecutionMode','FixedRate', 'TimerFcn',#timerCallback);
%# when figure is closed
set(hFig, 'CloseRequestFcn',#onClose);
%# process images
start(hTimer); %# start timer
for i=1:100
if ~ishandle(hFig), break; end
msg = sprintf('Processing image %d / %d', i, 100);
set(hTxt, 'String',msg)
%# some lengthy operation
pause(.1)
end
if isvalid(hTimer)
stop(hTimer) %# stop timer
delete(hTimer) %# delete timer
end
%# timer callback function
function timerCallback(src,evt)
if ~ishandle(hFig), return; end
%# incremenet counter circularly
c = rem(c,size(clr,1)) + 1;
%# update color of patch
set(hPatch, 'FaceColor',clr(c,:));
drawnow
end
%# on figure close
function onClose(src,evt)
%# stop and delete timer
if isvalid(hTimer)
stop(hTimer);
delete(hTimer);
end
%# call default close callback
feval(#closereq)
end
end
The code simulates running a lengthy processing step on a number of images, while at the same time showing an animation to keep the user entertained.
To keep the code simple, I am showing a patch that updates its color continuously (using a timer). This stands for the animated GIF image of "loading...".
Is this what you want? Just combine the loop bodies.
for i=1:200
if mod(i,2) == 0
set(hAxes,'Color','b');
else
set(hAxes,'Color','g');
end
image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
set(loading1,'string',image2);
drawnow;
end
EDIT: OK, in that case, try a timer instead of the first loop
function output = main_function
% Your other setup calls
hAxes = axes('Parent',hFigure,'Units','pixels','Position',[0 112 424 359]);
c = 0;
t = timer('TimerFcn', #color_change_fcn, 'Period', 1.0);
start(t);
for i=1:200
image2 = horzcat('now processing ', 'image', num2str(i), '.jpg of 200 images');
set(loading1,'string',image2);
drawnow;
end
function color_change_fcn
if mod(c,2) == 0
set(hAxes,'Color','b');
else
set(hAxes,'Color','g');
end
drawnow;
c = c + 1;
end
end
Just remember that the MATLAB control flow is inherently single-threaded, so these callbacks won't run if MATLAB is busy working somewhere else.
The structure that I want to draw should be exactly like the one shown. Thanks!
Here's a little function I whipped up that will take as input a square, upper-triangular matrix and plot the lattice structure as above:
function hFigure = plot_lattice(A)
%# Compute all the coordinates needed for the lines and points:
N = size(A,1);
[xPoints,yPoints] = meshgrid(0:N-1);
yPoints = bsxfun(#plus,-yPoints,0:0.5:(N-0.5)/2);
xLines = [xPoints([1:N+1:N^2-N-1 1:N:N^2-2*N+1]); ...
xPoints([1:N-1 N:-1:2],N).']; %'
yLines = [yPoints([1:N+1:N^2-N-1 1:N:N^2-2*N+1]); ...
yPoints([1:N-1 N:-1:2],N).']; %'
index = find(triu(reshape(1:N^2,N,N)));
xPoints = xPoints(index);
yPoints = yPoints(index);
values = strtrim(cellstr(num2str(A(index))));
%# Create the figure:
hFigure = figure('Color','w');
hAxes = axes('Parent',hFigure,'XLim',[-0.5 N-0.5],...
'YLim',[min(yPoints)-0.5 max(yPoints)+0.5],...
'YColor','w','XTick',0:N-1,'LineWidth',2);
hold on;
plot(hAxes,xLines,yLines,'k','LineWidth',2);
plot(hAxes,xPoints,yPoints,'o','MarkerFaceColor',[0.96 0.96 0.86],...
'MarkerSize',30,'MarkerEdgeColor','k','LineWidth',2);
text(xPoints,yPoints,values,'Parent',hAxes,...
'HorizontalAlignment','center');
hold off;
end
And here's a test with a sample matrix:
>> A = triu(reshape(1:25,5,5))
A =
1 6 11 16 21
0 7 12 17 22
0 0 13 18 23
0 0 0 19 24
0 0 0 0 25
>> plot_lattice(A);
I have modified the code a little so it can print the nodes as well as multiple values in each node.
A is now a three dimension matrix and cant take also empty values (NaN) that are not printed in the tree
Ofc the code is not optimal... maybe one of you can improve it
%# Compute all the coordinates needed for the lines and points:
close all
[N,L] = size(A);
L=L/N;
[xPoints,yPoints] = meshgrid(0:N-1);
yPoints = bsxfun(#plus,-yPoints,0:0.5:(N-0.5)/2);
xLines = [xPoints([1:N+1:N^2-N-1 1:N:N^2-2*N+1]); xPoints([1:N-1 N:-1:2],N).'];
yLines = [yPoints([1:N+1:N^2-N-1 1:N:N^2-2*N+1]); yPoints([1:N-1 N:-1:2],N).'];
index = find(triu(reshape(1:N^2,N,N)));
xPoints = xPoints(index);
yPoints = yPoints(index);
% values = strtrim(cellstr(num2str(A(index))));
for i=1:L
values(:,i) = strtrim(cellstr(num2str(A((i-1)*N*N+index))));
end
values = strrep(values, 'NaN', ' ');
for i=1:N
for j=i:N
if i==1 && j==1
nodes(i,j)=cellstr(strcat('N_','0'));
else
nodes(i,j)=cellstr(strcat('N_','{',repmat('u',1,(j-1)-(i-1)),repmat('d',1,(i-1)),'}'));
end
end
end
nodes = nodes(index);
%# Create the figure:
hFigure = figure('Color','w');
hAxes = axes('Parent',hFigure,'XLim',[-0.5 N-0.5],'YLim',[min(yPoints)-0.5 max(yPoints)+0.5],'YColor','w','XTick',0:N-1,'LineWidth',2);
hold on;
plot(hAxes,xLines,yLines,'k','LineWidth',2);
plot(hAxes,xPoints,yPoints,'o','MarkerFaceColor',[0.96 0.96 0.86],'MarkerSize',60,'MarkerEdgeColor','k','LineWidth',2);
for i=1:L
text(xPoints,yPoints+L*0.05-(i-1)*0.1,values(:,i),'Parent',hAxes,'HorizontalAlignment','center');
end
text(xPoints-0.4,yPoints,nodes,'Parent',hAxes,'HorizontalAlignment','center');
hold off;
I would use matlab to generate a text file for use in Graphviz.