123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- function [x, y, orientation] = FlyTracker(filename, FrameRange,...
- NBackFrames, opt1, sqrsize,...
- alpha, ellipse)
- %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.
- % This function uses the videoReader function to input the video file into a Matlab object.
- % Usage on videoReader and other functions in the videoIO toolbox can be
- % found in the videoIO documentation.
- %Written by Dan Valente 8/8/07
- %Please note: Video indexes start at frame 0
- StartFrame = FrameRange(1);
- EndFrame = FrameRange(end);
- NFrames = EndFrame-StartFrame+1;
- %If NBackFrames is smaller than the number of frames we want to look at,
- % we'll just take a smaller background average using all the frames of
- % interest.
- if (NBackFrames >= NFrames)
- NBackFrames = NFrames;
- end
- %initialize some variables
- x = [];
- y = [];
- orientUHP=[];
- orientLHP=[];
- %load in video object using videoReader
- video = videoReader(filename);
- info = getinfo(video);
- width = info.width;
- height = info.height;
- %just prevents error if user wants to track to end, but enters the
- % incorrect EndFrame (recall frame index starts at 0).
- if (info.numFrames == EndFrame)
- EndFrame = EndFrame-1;
- elseif (info.numFrames < EndFrame)
- EndFrame = info.numFrames-1;
- end
- %seek to StartFrame for initial background calculation
- seek(video, StartFrame);
- mask = ellipse.mask;
- disp('Calculating background...')
- background = zeros(height, width);
- for bframe = 1:NBackFrames;
- img = getframe(video);
- current = mask.*double(img(:,:,1)); %just take first color matrix and mask out unwanted portions
- background = background + current/NBackFrames ;
- next(video);
- end
- flipper = 256*ones(height, width).*mask;
- if (strcmp(opt1,'neg') == 1) %make sure our fly will be a bright spot
- background = -background+flipper;
- end
- %seek to StartFrame for tracking
- seek(video,StartFrame);
- disp('Beginning tracking...')
- tic
- for frame = StartFrame:EndFrame
- disp(num2str(frame))
- img = getframe(video);
- img = mask.*double(img(:,:,1)); %just take first color matrix
-
- %make sure our fly will be a bright spot
- if (strcmp(opt1,'neg') == 1)
- img = -img+flipper;
- elseif (strcmp(opt1,'pos') == 1)
- img = img;
- end
-
- % Calculate square of difference image (to reduce noise) and track
- temp = (img-background).^2;
-
- [x_raw y_raw bodyline sqr]=FindFly(temp,sqrsize);
-
-
- %Just in case of a false track due to objects in the video that are
- %brighter than fly and vary over time. We assume that these are
- %very far away from the fly. One may want to change the threshold
- %from 100 pixels to something smaller, if need be. Any reasonably
- %large number should do, and if you choose an incorrect threshold,
- %you can use the CleanData function to fix this.
- if (frame~=StartFrame)
- if (sqrt((x_raw-x(end))^2+(y_raw-y(end))^2) >= 100)
- x_raw = x(end);
- y_raw = y(end);
- end
- end
-
- x = [x x_raw];
- y = [y y_raw];
- orientUHP = [orientUHP bodyline(1)];
- orientLHP = [orientLHP bodyline(2)];
- % %
- % figure(2)
- % imagesc(img)
- % colormap gray
- % hold on
- % plot(x_raw,y_raw, '.r')
- % %
- %
- %grab whatever the background was before the fly got there.
- temp = background(sqr(1):sqr(2),sqr(3):sqr(4));
- %update
- background = alpha*background+(1-alpha)*img;
- %make sure we only update image outside of fly
- background(sqr(1):sqr(2),sqr(3):sqr(4)) = temp;
-
- worked = next(video);
- if (worked == 0)
- break
- end
- end
- disp('Finished tracking.')
- disp('Have a lovely day.')
- toc
- %Now we have to make sure that the y vector is based on a coordinate
- %system with the origin in the lower left hand corner of the square,
- %for plotting purposes.
- y = height-y;
- orientation = [orientUHP;orientLHP];
- return;
-
|