Kalman filter missing data from eye track Samuel Rivera and Fabian Benitez for Kalman Filtering June 24, 2011 Notes: This function filters eye tracks to smooth and eliminate missing data Syntax: eyeTrack = filterEyeTrackInfant( eyeTrack ) Inputs: eyeTrack: (Nx1) vector of complex (x+i*y) coordinates. -1-i1 to identify missing data. The paramters used here work well for data scaled between [0 1] Outputs: eyeTrack: the kalman filtered version
0001 % Kalman filter missing data from eye track 0002 % Samuel Rivera and Fabian Benitez for Kalman Filtering 0003 % June 24, 2011 0004 % Notes: This function filters eye tracks to smooth and eliminate missing 0005 % data 0006 % 0007 % Syntax: eyeTrack = filterEyeTrackInfant( eyeTrack ) 0008 % 0009 % Inputs: 0010 % eyeTrack: (Nx1) vector of complex (x+i*y) coordinates. -1-i1 to identify 0011 % missing data. The paramters used here work well for data 0012 % scaled between [0 1] 0013 % 0014 % Outputs: 0015 % eyeTrack: the kalman filtered version 0016 0017 function eyeTrack = filterEyeTrackInfant( eyeTrack, smoothParam ) 0018 0019 % oriEyes = eyeTrack; 0020 0021 %--------------------------------------- 0022 %filter using Kalman 0023 0024 eyeTrack = [real(eyeTrack) imag(eyeTrack) ]; 0025 eyeTrack( eyeTrack == -1) = nan; 0026 0027 t = ones( 1, length( eyeTrack ) ); 0028 t( isnan( eyeTrack(:,1) )) = -1; %mising is -1, filled is 1 0029 0030 if nargin < 2 || isempty( smoothParam) 0031 smoothParam = .0003; % to increase smoothness, lower the number 0032 % 1000 empirically works on the up-scaled eye track data 0033 % in [.0001 , .0005] empirically works on the data in [ 0 1 ] 0034 end 0035 0036 known = find( t == 1); 0037 while(known(2)-known(1) >1) %make sure not a single thing, so we can calculate things 0038 known(1) = []; 0039 end 0040 0041 % I need to identify the large gaps of missing eye tracks 0042 % don't interpolate the large missing gaps 0043 missingWindow = 4; 0044 interpThese = ones( 1, length( eyeTrack ) ); 0045 for i1 =missingWindow:length(interpThese) 0046 i1_check = i1 - [missingWindow-1:-1:0]; 0047 if sum( t(i1_check) == -1) == missingWindow 0048 interpThese( i1_check ) = 0; 0049 end 0050 end 0051 % find start/end of the gaps to interpolate 0052 k1 = 1; 0053 inABlock = 0; 0054 for i1 = 1:length(interpThese) 0055 if (inABlock==0) && (interpThese(i1) ==1) 0056 startInterp(k1) = i1; 0057 inABlock = 1; 0058 end 0059 if (inABlock==1) && (interpThese(i1) ==0) 0060 endInterp(k1) = i1-1; 0061 inABlock = 0; 0062 k1 = k1+1; 0063 end 0064 % make sure to end at last sample if started already 0065 if (i1 ==length(interpThese)) && (inABlock==1) 0066 endInterp(k1) = i1; 0067 end 0068 end 0069 0070 % now interpolate just within those blocks of uninterrupted track 0071 for i1 = 1:length( startInterp ) 0072 [eyeTrack1]=kalmanMissingData( eyeTrack(startInterp(i1):endInterp(i1),:)', t(startInterp(i1):endInterp(i1)), smoothParam)'; 0073 eyeTrack(startInterp(i1):endInterp(i1),:) = eyeTrack1; 0074 end 0075 0076 %old way, without chopping eye track into uninterrupted blocks 0077 % if ~isempty(known) && known(1) > 1 0078 % [eyeTrack1]=kalmanMissingData( eyeTrack(known(1):end,:)', t(known(1):end), smoothParam)'; 0079 % eyeTrack = [ eyeTrack(1:known(1)-1,:); eyeTrack1 ]; 0080 % else 0081 % [eyeTrack]=kalmanMissingData( eyeTrack', t, smoothParam)'; 0082 % end 0083 0084 0085 eyeTrack(isnan(eyeTrack)) = -1; 0086 eyeTrack = eyeTrack(:,1)+1i*eyeTrack(:,2); 0087 0088 0089 % visualizeTrackSingle( eyeTrack, oriEyes, 'test' ) 0090 0091 0092 0093 0094