FlyTracker.m 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. function [x, y, orientation] = FlyTracker(filename, FrameRange,...
  2. NBackFrames, opt1, sqrsize,...
  3. alpha, ellipse)
  4. %FLYTRACKER
  5. % Usage:
  6. % [x, y, orientation] = FlyTracker(filename, FrameRange, ...
  7. % NBackFrames, opt1, sqrsize,...
  8. % alpha, ellipse)
  9. %
  10. % This function takes an input filename for a movie and tracks the position
  11. % of a fly from StartFrame to EndFrame. The movie can be in any format
  12. % (.avi, .mpg, .mp2, etc.). The following are a list of input parameters
  13. % and output variables.
  14. %
  15. % Input:
  16. % filename: must be the complete string of the movie filename
  17. % FrameRange: range of frames to examine
  18. % NBackFrames: number of frames in static background, used only to
  19. % find fly in first frame
  20. % opt1: 'neg' or 'pos'. This multiplies the frame data by a
  21. % negative sign ('neg') or not ('pos'). FindFly needs the
  22. % fly to be a bright spot, so the choice of this depends on
  23. % the origional image. If the original image is RGB, chances
  24. % are that 'neg' needs to be selected.
  25. % sqrsize: This is half the length of the sides of the square
  26. % around the brightest spot to be used in the CM calculation
  27. % and the orientation calculation.
  28. % alpha: This is the weighting parameter for the running
  29. % background. It must be close to 1 for best results.
  30. % 0.9 seems like a good value for this, anything less
  31. % seems to degrade SNR. But for generalities sake, it
  32. % is still a user input parameter.
  33. % ellipse: parameters of the elliptical area that will be tracked
  34. %
  35. % Output:
  36. % x,y: The x and y locations of the fly in each frame
  37. % orientation: A matrix containing the UHP and LHP body axis orientation
  38. % angles for each frame. UHP are in the first row, LHP are in
  39. % the second row. See FlyOrient and FindFly for more
  40. % details.
  41. % This function uses the videoReader function to input the video file into a Matlab object.
  42. % Usage on videoReader and other functions in the videoIO toolbox can be
  43. % found in the videoIO documentation.
  44. %Written by Dan Valente 8/8/07
  45. %Please note: Video indexes start at frame 0
  46. StartFrame = FrameRange(1);
  47. EndFrame = FrameRange(end);
  48. NFrames = EndFrame-StartFrame+1;
  49. %If NBackFrames is smaller than the number of frames we want to look at,
  50. % we'll just take a smaller background average using all the frames of
  51. % interest.
  52. if (NBackFrames >= NFrames)
  53. NBackFrames = NFrames;
  54. end
  55. %initialize some variables
  56. x = [];
  57. y = [];
  58. orientUHP=[];
  59. orientLHP=[];
  60. %load in video object using videoReader
  61. video = videoReader(filename);
  62. info = getinfo(video);
  63. width = info.width;
  64. height = info.height;
  65. %just prevents error if user wants to track to end, but enters the
  66. % incorrect EndFrame (recall frame index starts at 0).
  67. if (info.numFrames == EndFrame)
  68. EndFrame = EndFrame-1;
  69. elseif (info.numFrames < EndFrame)
  70. EndFrame = info.numFrames-1;
  71. end
  72. %seek to StartFrame for initial background calculation
  73. seek(video, StartFrame);
  74. mask = ellipse.mask;
  75. disp('Calculating background...')
  76. background = zeros(height, width);
  77. for bframe = 1:NBackFrames;
  78. img = getframe(video);
  79. current = mask.*double(img(:,:,1)); %just take first color matrix and mask out unwanted portions
  80. background = background + current/NBackFrames ;
  81. next(video);
  82. end
  83. flipper = 256*ones(height, width).*mask;
  84. if (strcmp(opt1,'neg') == 1) %make sure our fly will be a bright spot
  85. background = -background+flipper;
  86. end
  87. %seek to StartFrame for tracking
  88. seek(video,StartFrame);
  89. disp('Beginning tracking...')
  90. tic
  91. for frame = StartFrame:EndFrame
  92. disp(num2str(frame))
  93. img = getframe(video);
  94. img = mask.*double(img(:,:,1)); %just take first color matrix
  95. %make sure our fly will be a bright spot
  96. if (strcmp(opt1,'neg') == 1)
  97. img = -img+flipper;
  98. elseif (strcmp(opt1,'pos') == 1)
  99. img = img;
  100. end
  101. % Calculate square of difference image (to reduce noise) and track
  102. temp = (img-background).^2;
  103. [x_raw y_raw bodyline sqr]=FindFly(temp,sqrsize);
  104. %Just in case of a false track due to objects in the video that are
  105. %brighter than fly and vary over time. We assume that these are
  106. %very far away from the fly. One may want to change the threshold
  107. %from 100 pixels to something smaller, if need be. Any reasonably
  108. %large number should do, and if you choose an incorrect threshold,
  109. %you can use the CleanData function to fix this.
  110. if (frame~=StartFrame)
  111. if (sqrt((x_raw-x(end))^2+(y_raw-y(end))^2) >= 100)
  112. x_raw = x(end);
  113. y_raw = y(end);
  114. end
  115. end
  116. x = [x x_raw];
  117. y = [y y_raw];
  118. orientUHP = [orientUHP bodyline(1)];
  119. orientLHP = [orientLHP bodyline(2)];
  120. % %
  121. % figure(2)
  122. % imagesc(img)
  123. % colormap gray
  124. % hold on
  125. % plot(x_raw,y_raw, '.r')
  126. % %
  127. %
  128. %grab whatever the background was before the fly got there.
  129. temp = background(sqr(1):sqr(2),sqr(3):sqr(4));
  130. %update
  131. background = alpha*background+(1-alpha)*img;
  132. %make sure we only update image outside of fly
  133. background(sqr(1):sqr(2),sqr(3):sqr(4)) = temp;
  134. worked = next(video);
  135. if (worked == 0)
  136. break
  137. end
  138. end
  139. disp('Finished tracking.')
  140. disp('Have a lovely day.')
  141. toc
  142. %Now we have to make sure that the y vector is based on a coordinate
  143. %system with the origin in the lower left hand corner of the square,
  144. %for plotting purposes.
  145. y = height-y;
  146. orientation = [orientUHP;orientLHP];
  147. return;