%main_simulation.m  - Author: Stefan Gachter
%                     updated by: Branislav Micusik
%
% Simulation of the motion detection algorithm.
%
%       batch file
%
%       See also: acc_still_bgd_region, bmp_to_gif, difference_image,
%                 display_frame, display_frame_in_figure,
%                 display_histogram, fix_format_int_str,
%                 insert_frame, insert_number, label_mov_objects,
%                 merge_frame, n2s, reset_mean_bgd_image, scalar_lms,
%                 split_frame, weighted_accumulation

%       Author       : Stefan Gachter, stefan.gachter@ieee.org
%                      Center for Machine Perception, 
%                      Czech Technical University, Prague
%       Update       : Branislav Micusik     
%       Documentation: Gaechter-TR-2001-07.pdf
%       Language     : Matlab  5.3.1.29215a (R11.1), (c) MathWorks
%       Last change  : 17/09/2001
%       Status       : Ready
%

clear all;
close all;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%read out setup from file
motion_setup_02;              %from file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% morphological filter parameters

struct_element=  ...
        [0 1 0;
         1 1 1;
         0 1 0];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% path specifications

%load_path=['/home.stud/micusb1/omni/movie/' ...
%           'simulation/pan/movie_' n2s(nb_movie) '/'];
%load_init_path=['/home.stud/micusb1/omni/movie/' ...
%                'simulation/pan/init/movie_' n2s(nb_movie) '/'];
%save_path=['/home.stud/micusb1/omni/movie/' ...
%           'animation/movie_' n2s(nb_movie) '/'];

%load_path=['g:\giotto\motion\'];
%load_init_path=['g:\giotto\motion\'];

save_path=['tmp/'];
dname_bmp=['data/'];
fname_bmp=['sv_video_' fix_format_int_str(nb_movie,2) '_'];

% file name specifications

%stream_name=['stream_pan_' n2s(nb_movie) ;];
animation_name=['mov_objects_movie' ;];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% misc

map_bw=[0 0 0;1 1 1];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
global stop;
global type_views;
global first;
global num_framed_objects;

change = 0;
stop = 0;
num_fields = 1;
num_framed_objects = 2;

figure(num_fig);
set(num_fig,'BackingStore','off');
set(num_fig,'DoubleBuffer','on')

f = uimenu('Label','Change fields');
    uimenu(f,'Label','1 field','Callback','num_fields=1; change=1;');
    uimenu(f,'Label','2 fields','Callback','num_fields=2; change=1;');
    uimenu(f,'Label','8 fields','Callback','num_fields=8; change=1;');
f = uimenu('Label','Number of objects');
    uimenu(f,'Label','1 object','Callback','num_framed_objects=1');
    uimenu(f,'Label','2 object','Callback','num_framed_objects=2');
    uimenu(f,'Label','3 object','Callback','num_framed_objects=3');
    uimenu(f,'Label','4 object','Callback','num_framed_objects=4');
    uimenu(f,'Label','5 object','Callback','num_framed_objects=5');
    uimenu(f,'Label','6 object','Callback','num_framed_objects=6');

s = uimenu('Label','STOP','Callback','stop=1;');

drawnow;

% motion detection simulation

%% image sequence
%file_name=[load_path stream_name '.mat'];
%eval(['load ' file_name ' stream map']);
%eval(['load ' file_name ' map']);

map=gray(256);

%infodev=giottoopen('LPT1');                       % open camera
str_init=[platform '(''init'',1);'];
str_acq=['tmp=' platform '(''acq'',1);'];
str_end=[platform '(''end'',1);'];

if(stream_from_files == 0) 
   eval(str_init);                                 %init camera
end;


%frame_size=[size(stream,1),size(stream,2)/nb_frames];
idx = nb_frame_start_display;
if(stream_from_files == 0) 
   eval(str_acq);              %acquire image from camera
   frame_j(:,:)=tmp(fovea:end,:);
else
   fname1 = [dname_bmp fname_bmp fix_format_int_str(idx,4) '.bmp'];
   frame_j=imread(fname1);
   idx = idx+1;
end

frame_j=double(frame_j);
frame_j=frame_j./255;

frame_size=size(frame_j);

nb_subframes=length(height);

%% initialization
acc_frame_j=zeros(frame_size);
tmp_chg_region_hist=zeros([frame_size,adapt_depth]);
tmp_change_region=zeros(frame_size);

%file_name=[load_init_path init_mean_bgd_img_name '.mat'];
%eval(['load ' file_name ' init_mean_bgd_img']);
%mean_bgd_img_j=init_mean_bgd_img;
mean_bgd_img_j=frame_j;

bgd_change_region=zeros(frame_size);

reset=0;
%frame_j=stream(:,1:frame_size(2));
%for i=2:nb_frames
i=1;
while(~stop & (idx~=nb_frame_stop_display+1 | ~stream_from_files))
   i=i+1;
   if(i>=1000) i=2;
   end;
	display=0;
%  if ((i-1)>=nb_frame_start_display)&((i-1)<nb_frame_stop_display)&~animation
    display=1;
%  end
  
%  if animation|~display
%    disp(['Frame no.' fix_format_int_str(i-1,3) '.']);
%  end
     
  %% temporal change detection
  %  frame_i=stream(:,(i-1)*frame_size(2)+1:i*frame_size(2));
  
  if(stream_from_files == 0) 
     eval(str_acq);              %acquire image from camera
     frame_i(:,:)=tmp(fovea:end,:);
   else
     fname1 = [dname_bmp fname_bmp fix_format_int_str(idx,4) '.bmp'];
     frame_i=imread(fname1);
     idx = idx+1;
  end
  
  frame_i=double(frame_i);
  frame_i=frame_i./255;

  abs_diff_image_d=abs(difference_image(frame_i,frame_j));
  acc_frame_i=weighted_accumulation(acc_frame_j,abs_diff_image_d,acc_length_d);
  
  acc_subframe_i=split_frame(acc_frame_i,height);
  abs_diff_subimage_d=split_frame(abs_diff_image_d,height);
  
  for k=1:nb_subframes;
%    eval(['lms_abs_diff_subimage_d=' ...
%        'scalar_lms(abs_diff_subimage_d.no' n2s(k) '(:));']);
%    eval(['sensitivity_threshold_d.no' n2s(k) '=' ... 
%        '2.576*lms_abs_diff_subimage_d/0.3372+min_sensitivity_threshold_d;']);
     sensitivity_threshold_d.no1 = min_sensitivity_threshold_d;
     tmp_change_subregion.no1 = acc_subframe_i.no1 > sensitivity_threshold_d.no1;

%     eval(['tmp_change_subregion.no' n2s(k) '=' ...
%         'acc_subframe_i.no' n2s(k) '>sensitivity_threshold_d.no' n2s(k) ';']);

  end
  
  [tmp_change_region,border_coordinates_tmp]= ...
    merge_frame(tmp_change_subregion,nb_subframes,'border');

  tmp_change_region=erode(tmp_change_region,struct_element);
  tmp_change_region=dilate(tmp_change_region,struct_element);
   
%  bgd_activity=scalar_lms(abs_diff_image_d);
%  if bgd_activity<activity_threshold
%    reset=0;
%  end
%  if (bgd_activity>=activity_threshold)&(~reset)
%    reset=1;
%    disp(['Reset at frame no.' fix_format_int_str(i-1,3) ...
%         ' when level ' n2s(bgd_activity) '.']);
%    mean_bgd_img_j= ...
%      reset_mean_bgd_image(mean_bgd_img_j,frame_j,frame_i,9,bgd_change_region);
%    tmp_change_region=zeros(frame_size);
%  end
  
  [still_bgd_region_mask,tmp_chg_region_hist]= ...
      acc_still_bgd_region(tmp_change_region,tmp_chg_region_hist);
  
  %% background change detection
  mean_bgd_img_i= ...
    weighted_accumulation(mean_bgd_img_j,frame_i,acc_length_b,still_bgd_region_mask);
  abs_diff_image_b=abs(difference_image(mean_bgd_img_i,frame_i)); 
  
  abs_diff_subimage_b=split_frame(abs_diff_image_b,height);
  for k=1:nb_subframes;
%    eval(['lms_abs_diff_subimage_b=' ...
%      'scalar_lms(abs_diff_subimage_b.no' n2s(k) '(:));']);
%    eval(['sensitivity_threshold_b.no' n2s(k) '=' ... 
%      '2.576*lms_abs_diff_subimage_b/0.3372+min_sensitivity_threshold_b;']);
     sensitivity_threshold_b.no1 = min_sensitivity_threshold_b;
     bgd_change_subregion.no1 = abs_diff_subimage_b.no1 > sensitivity_threshold_b.no1;

  end
  
  [bgd_change_region,border_coordinates_bgd]= ...
    merge_frame(bgd_change_subregion,nb_subframes,'border');

  bgd_change_region=erode(bgd_change_region,struct_element);
  bgd_change_region=dilate(bgd_change_region,struct_element);
  
  %% labeling
  frame_coordinates=label_mov_objects2(bgd_change_region,'frame',num_framed_objects);
  
  %%% display
  fig_frame_i=insert_number(frame_i,i-1,3,[2,2],'inverse');
  fig_abs_diff_image_d=insert_number(abs_diff_image_d,i-1,3,[2,2],'inverse');
  fig_acc_frame_i=insert_number(acc_frame_i,i-1,3,[2,2],'inverse');
  [fig_tmp_change_region,map_tmp_change]= ...
    insert_frame(uint8(tmp_change_region),border_coordinates_tmp,'red',map_bw);
  fig_tmp_change_region= ...
    insert_number(fig_tmp_change_region,i-1,3,[2,2],'transparent');
  fig_still_bgd_region_mask= ...
    insert_number(still_bgd_region_mask,i-1,3,[2,2],'transparent');
  fig_mean_bgd_img_i=insert_number(mean_bgd_img_i,i-1,3,[2,2],'inverse');
  fig_abs_diff_image_b=insert_number(abs_diff_image_b,i-1,3,[2,2],'inverse');
  [fig_bgd_change_region,map_bgd_change]= ...
    insert_frame(uint8(bgd_change_region),border_coordinates_bgd,'red',map_bw);
  fig_bgd_change_region= ...
    insert_number(fig_bgd_change_region,i-1,3,[2,2],'transparent');
  [fig_labeled_change_region,map_change_region]= ...
    insert_frame(bgd_change_region,frame_coordinates,'red',map_bw);
  fig_labeled_change_region= ...
    insert_number(fig_labeled_change_region,i-1,3,[2,2],'transparent');
  [fig_labelled_frame_i,map_frame]= ...
    insert_frame(frame_i,frame_coordinates,'green',map);
  fig_labelled_frame_i= ...
    insert_number(fig_labelled_frame_i,i-1,3,[2,2],'inverse');
  
  if display
     
  fig_bgd_change_region = uint8(255*double(fig_bgd_change_region));
  fig_tmp_change_region = uint8(255*double(fig_tmp_change_region));
  fig_still_bgd_region_mask = uint8(255*double(fig_still_bgd_region_mask));
  
  map_fig=0; 
  switch num_fields
  case 8   
     frames=sequence_to_struct(uint8(255*fig_frame_i), ...
                   uint8(255*fig_abs_diff_image_d), ...
                   uint8(fig_tmp_change_region), ...  
                   uint8(fig_still_bgd_region_mask), ...  
                   uint8(255*fig_mean_bgd_img_i), ...
                   uint8(255*fig_abs_diff_image_b), ...
                   uint8(fig_bgd_change_region), ...
                   uint16(255*fig_labelled_frame_i));
  case 2
      fig_mean_bgd_img_i(:,size(fig_mean_bgd_img_i,2))=1;			%white line for visual image separating               
  		frames=sequence_to_struct(uint8(255*fig_mean_bgd_img_i), ...
   		  uint16(255*fig_labelled_frame_i));
  case 1
		frames=sequence_to_struct(uint16(255*fig_labelled_frame_i));
  end       
%  map_fig= ...
%    sequence_to_struct(map,map,map_tmp_change,map_bw, ...
%                       map,map,map_bgd_change,map_frame);
if(change == 1)
   set(get(gca,'children'),'cdata',[]);
   change=0;
end

  display_frame_in_figure_2(frames,map_fig,num_fields,[4 2],num_fig);
  
%  display_histogram(abs_diff_subimage_d,nb_subframes, ...
%    sensitivity_threshold_d,[0 0.05],12);
%  xlabel('absolute difference for two consecutive images');
%  display_histogram(abs_diff_subimage_b,nb_subframes, ...
%    sensitivity_threshold_b,[0 0.05],13);
%  xlabel('absolute difference for background subtraction');

%  pause(0.001);
	drawnow;
end
  
  %%% animation
  if ((i-1)>=nb_frame_start_animation)&((i-1)<nb_frame_stop_animation)&animation
     
  switch num_fields
  case 8   
     frames=sequence_to_struct(uint8(255*fig_frame_i), ...
                   uint8(255*fig_abs_diff_image_d), ...
                   uint8(fig_tmp_change_region), ...  
                   uint8(fig_still_bgd_region_mask), ...  
                   uint8(255*fig_mean_bgd_img_i), ...
                   uint8(255*fig_abs_diff_image_b), ...
                   uint8(fig_bgd_change_region), ...
                   uint16(255*fig_labelled_frame_i));
  case 2
      fig_mean_bgd_img_i(:,size(fig_mean_bgd_img_i,2))=1;			%white line for visual image separating               
  		frames=sequence_to_struct(uint8(255*fig_mean_bgd_img_i), ...
   		  uint16(255*fig_labelled_frame_i));
  case 1
		frames=sequence_to_struct(uint16(255*fig_labelled_frame_i));
  end       
      
  fig_rgb = display_frame_in_figure_2(frames,map_fig,num_fields,[4 2],num_fig);
             
%  map_fig=sequence_to_struct(map,map,map_tmp_change,map_bw, ...
%                             map,map,map_bgd_change,map_frame);
%
%  fig_rgb=display_frame_in_figure(frames,map_fig,8,[4 2],'not_display');
%  red_map_frame=[gray(254);name_to_rgb('red');name_to_rgb('green')];

   red_map_frame=[gray(255);name_to_rgb('green')];
%   frame=rgb2ind(fig_rgb,red_map_frame);
  
   file_name=[save_path animation_name '_' fix_format_int_str(i-1,3) '.bmp'];

   imwrite(fig_rgb,red_map_frame,file_name,'bmp');
  end
  
  %% update   
  frame_j=frame_i;
  acc_frame_j=acc_frame_i;
  mean_bgd_img_j=mean_bgd_img_i;
  
end

%%% animation
if animation
  start_stop=[nb_frame_start_animation nb_frame_stop_animation-1];
 % bmp_to_gif(save_path,animation_name,start_stop, ...
 %   'animate_whirlgif','erase_bmp','erase_gif');
 bmp_to_gif(save_path,animation_name,start_stop, ...
    'animate_imagemagick','erase_bmp'); 
end

if(stream_from_files == 0) 
   eval(str_end);            %terminate device
end

