# FlyTracker

## PURPOSE

FLYTRACKER

## SYNOPSIS

function [x, y, orientation] = FlyTracker(filename, FrameRange,NBackFrames, opt1, sqrsize,alpha, ellipse)

## DESCRIPTION

    FLYTRACKER
     Usage:
      [x, y, orientation] = FlyTracker(filename, FrameRange, ...
                            NBackFrames, opt1, sqrsize,...
                            alpha, ellipse)

     This function takes an input filename for a movie and tracks the position
     of a fly from StartFrame to EndFrame.  The movie can be in any format
     (.avi, .mpg, .mp2, etc.).  The following are a list of input parameters
     and output variables.

     Input:
          filename:    must be the complete string of the movie filename
          FrameRange:  range of frames to examine
          NBackFrames: number of frames in static background, used only to
                       find fly in first frame
          opt1:        'neg' or 'pos'.  This multiplies the frame data by a
                       negative sign ('neg') or not ('pos').  FindFly needs the
                       fly to be a bright spot, so the choice of this depends on
                       the origional image.  If the original image is RGB, chances
                       are that 'neg' needs to be selected.
          sqrsize:     This is half the length of the sides of the square
                       around the brightest spot to be used in the CM calculation
                       and the orientation  calculation.
          alpha:       This is the weighting parameter for the running
                       background.  It must be close to 1 for best results.
                       0.9 seems like a good value for this, anything less
                       seems to degrade SNR.  But for generalities sake, it
                       is still a user input parameter.
          ellipse:     parameters of the elliptical area that will be tracked

     Output:
          x,y:         The x and y locations of the fly in each frame
          orientation: A matrix containing the UHP and LHP body axis orientation
                       angles for each frame.  UHP are in the first row, LHP are in
                       the second row.  See FlyOrient and FindFly for more
                       details.

## CROSS-REFERENCE INFORMATION

This function calls:

- FindFly FINDFLY
- getframe FRAME=GETFRAME(VR)
- getinfo INFO=GETINFO(VR)
- next WORKED=NEXT(VR)
- seek WORKED=SEEK(VR,FNUM)
- videoReader videoReader class constructor
- getinfo INFO=GETINFO(VW)
- getframe FRAME=GETFRAME(VR)
- getinfo INFO=GETINFO(VR)
- next WORKED=NEXT(VR)
- seek WORKED=SEEK(VR,FNUM)
- videoReader videoReader class constructor
- getinfo INFO=GETINFO(VW)
- getframe FRAME=GETFRAME(VR)
- getinfo INFO=GETINFO(VR)
- next WORKED=NEXT(VR)
- seek WORKED=SEEK(VR,FNUM)
- videoReader videoReader class constructor
- getinfo INFO=GETINFO(VW)

This function is called by:

- FTrack FTRACK

## SOURCE CODE

    0001 function [x, y, orientation] = FlyTracker(filename, FrameRange,...
    0002                         NBackFrames, opt1, sqrsize,...
    0003                         alpha, ellipse)
    0004
    0005 %FLYTRACKER
    0006 % Usage:
    0007 %  [x, y, orientation] = FlyTracker(filename, FrameRange, ...
    0008 %                        NBackFrames, opt1, sqrsize,...
    0009 %                        alpha, ellipse)
    0010 %
    0011 % This function takes an input filename for a movie and tracks the position
    0012 % of a fly from StartFrame to EndFrame.  The movie can be in any format
    0013 % (.avi, .mpg, .mp2, etc.).  The following are a list of input parameters
    0014 % and output variables.
    0015 %
    0016 % Input:
    0017 %      filename:    must be the complete string of the movie filename
    0018 %      FrameRange:  range of frames to examine
    0019 %      NBackFrames: number of frames in static background, used only to
    0020 %                   find fly in first frame
    0021 %      opt1:        'neg' or 'pos'.  This multiplies the frame data by a
    0022 %                   negative sign ('neg') or not ('pos').  FindFly needs the
    0023 %                   fly to be a bright spot, so the choice of this depends on
    0024 %                   the origional image.  If the original image is RGB, chances
    0025 %                   are that 'neg' needs to be selected.
    0026 %      sqrsize:     This is half the length of the sides of the square
    0027 %                   around the brightest spot to be used in the CM calculation
    0028 %                   and the orientation  calculation.
    0029 %      alpha:       This is the weighting parameter for the running
    0030 %                   background.  It must be close to 1 for best results.
    0031 %                   0.9 seems like a good value for this, anything less
    0032 %                   seems to degrade SNR.  But for generalities sake, it
    0033 %                   is still a user input parameter.
    0034 %      ellipse:     parameters of the elliptical area that will be tracked
    0035 %
    0036 % Output:
    0037 %      x,y:         The x and y locations of the fly in each frame
    0038 %      orientation: A matrix containing the UHP and LHP body axis orientation
    0039 %                   angles for each frame.  UHP are in the first row, LHP are in
    0040 %                   the second row.  See FlyOrient and FindFly for more
    0041 %                   details.
    0042
    0043 % This function uses the videoReader function to input the video file into a Matlab object.
    0044 % Usage on videoReader and other functions in the videoIO toolbox can be
    0045 % found in the videoIO documentation.
    0046
    0047 %Written by Dan Valente 8/8/07
    0048
    0049 %Please note: Video indexes start at frame 0
    0050 StartFrame = FrameRange(1);
    0051 EndFrame = FrameRange(end);
    0052 NFrames = EndFrame-StartFrame+1;
    0053
    0054 %If NBackFrames is smaller than the number of frames we want to look at,
    0055 % we'll just take a smaller background average using all the frames of
    0056 % interest.
    0057 if (NBackFrames >= NFrames)
    0058     NBackFrames = NFrames;
    0059 end
    0060
    0061 %initialize some variables
    0062 x = [];
    0063 y = [];
    0064 orientUHP=[];
    0065 orientLHP=[];
    0066
    0067 %load in video object using videoReader
    0068 video = videoReader(filename);
    0069 info = getinfo(video);
    0070 width = info.width;
    0071 height = info.height;
    0072
    0073 %just prevents error if user wants to track to end, but enters the
    0074 % incorrect EndFrame (recall frame index starts at 0).
    0075 if (info.numFrames == EndFrame)
    0076     EndFrame = EndFrame-1;
    0077 elseif (info.numFrames < EndFrame)
    0078     EndFrame = info.numFrames-1;
    0079 end
    0080
    0081 %seek to StartFrame for initial background calculation
    0082 seek(video, StartFrame);
    0083
    0084 mask = ellipse.mask;
    0085
    0086 disp('Calculating background...')
    0087 background = zeros(height, width);
    0088 for bframe = 1:NBackFrames;
    0089     img = getframe(video);
    0090     current = mask.*double(img(:,:,1));  %just take first color matrix and mask out unwanted portions
    0091     background = background + current/NBackFrames ;
    0092     next(video);
    0093 end
    0094 flipper = 256*ones(height, width).*mask;
    0095 if (strcmp(opt1,'neg') == 1)        %make sure our fly will be a bright spot
    0096     background = -background+flipper;
    0097 end
    0098
    0099
    0100 %seek to StartFrame for tracking
    0101 seek(video,StartFrame);
    0102 disp('Beginning tracking...')
    0103 tic
    0104
    0105 for frame = StartFrame:EndFrame
    0106         disp(num2str(frame))
    0107         img = getframe(video);
    0108         img = mask.*double(img(:,:,1));   %just take first color matrix
    0109
    0110         %make sure our fly will be a bright spot
    0111         if (strcmp(opt1,'neg') == 1)
    0112             img = -img+flipper;
    0113         elseif (strcmp(opt1,'pos') == 1)
    0114             img = img;
    0115         end
    0116
    0117         % Calculate square of difference image (to reduce noise) and track
    0118         temp = (img-background).^2;
    0119
    0120         [x_raw y_raw bodyline sqr]=FindFly(temp,sqrsize);
    0121
    0122
    0123         %Just in case of a false track due to objects in the video that are
    0124         %brighter than fly and vary over time.  We assume that these are
    0125         %very far away from the fly.  One may want to change the threshold
    0126         %from 100 pixels to something smaller, if need be.  Any reasonably
    0127         %large number should do, and if you choose an incorrect threshold,
    0128         %you can use the CleanData function to fix this.
    0129         if (frame~=StartFrame)
    0130             if (sqrt((x_raw-x(end))^2+(y_raw-y(end))^2) >= 100)
    0131                 x_raw = x(end);
    0132                 y_raw = y(end);
    0133             end
    0134         end
    0135
    0136         x = [x x_raw];
    0137         y = [y y_raw];
    0138         orientUHP = [orientUHP bodyline(1)];
    0139         orientLHP = [orientLHP bodyline(2)];
    0140 % %
    0141 %         figure(2)
    0142 %         imagesc(img)
    0143 %         colormap gray
    0144 %         hold on
    0145 %         plot(x_raw,y_raw, '.r')
    0146 % %
    0147 %
    0148         %grab whatever the background was before the fly got there.
    0149         temp = background(sqr(1):sqr(2),sqr(3):sqr(4));
    0150         %update
    0151         background = alpha*background+(1-alpha)*img;
    0152         %make sure we only update image outside of fly
    0153         background(sqr(1):sqr(2),sqr(3):sqr(4)) = temp;
    0154
    0155         worked = next(video);
    0156         if (worked == 0)
    0157             break
    0158         end
    0159 end
    0160 disp('Finished tracking.')
    0161 disp('Have a lovely day.')
    0162 toc
    0163
    0164 %Now we have to make sure that the y vector is based on a coordinate
    0165 %system with the origin in the lower left hand corner of the square,
    0166 %for plotting purposes.
    0167 y = height-y;
    0168
    0169 orientation = [orientUHP;orientLHP];
    0170
    0171 return;
    0172