gusucode.com > KLT Tracking源码程序matlab > kltTrack.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % PROJECT: % KLT Tracker % % BY: % Parthipan Siva % Assignment for SD 770-7: Topics in Particle Filtering % Systems Design Engineering % University of Waterloo % % DATE/Version: % Jan. 2007 - V 1.0 % % Description: kltTrack.m % Given the output of the KLT tracker code (feature list of % tracked and new points) this function will track an object % with the use of replaced features. % Note it is assumed that the KLT features were started at % startFrame that is that all features in the KLT feature % list file for startFrame has a value > 0. % Note ellipse as defined by h, y and angle are assumed to be % choosen such that all KLT features withing the ellipse on % the start frame belongs to the object of interest. % % References: % http://www.ces.clemson.edu/~stb/klt/ % % Project file list: % drawEllipse.m % InsidePolygon.m % kltTrack.m % kltTrackSIMPLE.m % readKLTFeatureList.m % Example1.m % Example2.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % INPUTS: % dir - the directory location where the KLT features are located % dir2 - the directory where the pgm image for each frame is % located % fileStart1 - the start of a file name (not including the frame % number) it is assumed that KLT features and image % files have the same file nume but with extensions % .txt and .pgm % h - the spread in row and col directions of the ellipse % sarounding the object (on the first frame) % y - the center location of the object on the first frame % startFrame - the start frame number % endFrame - the frame number at which to end tracking % TOL - the tollerance on the KLT featurs to use % angle - the orientation of the ellipse sarrounding the object % TIME_WINDOW - the duration in frames during which the KLT % feature points must have moved % SHOW_FIG - (optional) 1 to display figures (if movieFileName % specified regardless of this state figure is shown) % movieFileName - (optional) if a movie is needed specify file % name with .avi extension % framesPerSec - (optional) the fps for the avi, if not specified % set to 5 % % OUTPUTS: % frameInfo - struct containing the info for each frame % INDEX_OF_KEY_PTS - the key points used for % tracking % INDEX_OF_KEY_PTS_POT - the key points that were % used as replacement/addition for orignal % feature points % y - the center location of object ellipse % h - the row col spread of object ellipse % ellipse - cordinates along the ellipse boundar % used for ploting %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function [frameInfo] = kltTrack(dir, dir2, fileStart1, h, y, startFrame, ... endFrame, TOL, angle, TIME_WINDOW, SHOW_FIG, movieFileName, framesPerSec) if nargin < 10 disp('Warning not enough parameters'); pause; elseif nargin == 10 SHOW_FIG = 0; makeMovie = 0; elseif nargin == 11 makeMovie = 0; elseif nargin == 12 framesPerSec = 5; makeMovie = 1; elseif nargin == 13 makeMovie = 1; end fileEnd1 = '.ppm'; fileEnd2 = '.txt'; fileEnd3 = '.pgm'; frameInfoIndex = 1; % initialise arrays used to keep track of key points INDEX_OF_KEY_PTS = []; % these are the set of points on the object for sure INDEX_OF_KEY_PTS_POT = []; % these are the set of points that can potentially be on the object % We will keep adding potential points to INDEX_OF_KEY_PTS based on its % behaviour. Note when a point is added to INDEX_OF_KEY_PTS from % INDEX_OF_KEY_PTS_POT it is not deleted from INDEX_OF_KEY_PTS_POT. It is % kept as part of INDEX_OF_KEY_PTS_POT until the point stops moving for % TIME_WINDOW number of frames, at which point it is deleted from % INDEX_OF_KEY_PTS_POT and INDEX_OF_KEY_PTS. This is done to remove any % KLT points that appears behind the object motion. In this case the KLT % feature will dissapear and then reapear as the object passes over it. % Once the object passes over it, the KLT point will be detected as a new % feature but we don't want this to be added to the object being tracked. % read the KLT feature points on the first frame PointList = readKLTFeatureList([dir fileStart1 num2str(startFrame) fileEnd2]); % get coordinates of an ellipse sarrounding the inital location of the % object to track ellipse = drawEllipse(y,h/2,angle); % Find all KLT feature points within the ellipse sarounding the object polygon = [ellipse(2,:)' ellipse(1,:)']; for j = 1:size(PointList,1) if (PointList(j,4)>TOL) pt = [PointList(j,2) PointList(j,3)]; % if the KLT feature is inside the ellipse assume it is a featur to % track. [Inside] = InsidePolygon(polygon, pt); if (Inside == 1) INDEX_OF_KEY_PTS(end+1) = j; end end end if (SHOW_FIG == 1 || makeMovie == 1) fig = figure; end if (makeMovie == 1) set(fig,'DoubleBuffer','on'); mov = avifile(movieFileName,'compression','none'); end if (SHOW_FIG == 1 || makeMovie == 1) % read the first image I = imread([dir2 fileStart1 num2str(startFrame) fileEnd3]); imshow(I); hold on; plot(PointList(INDEX_OF_KEY_PTS,2),PointList(INDEX_OF_KEY_PTS,3),'x'); plot(ellipse(2,:),ellipse(1,:)); if (makeMovie == 0) pause(0.1); else F = getframe(gca); mov = addframe(mov,F); end end frameInfo(frameInfoIndex).INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS; frameInfo(frameInfoIndex).INDEX_OF_KEY_PTS_POT = INDEX_OF_KEY_PTS_POT; frameInfo(frameInfoIndex).y = y; frameInfo(frameInfoIndex).h = h; frameInfo(frameInfoIndex).ellipse = ellipse; frameInfoIndex = frameInfoIndex + 1; % loop through remaining figures and track the object defined in the % ellipse. distTimeIndex = 1; for i = startFrame+1:endFrame % save the previous list PointListPrev = PointList; % Read the KLT features for current frame PointList = readKLTFeatureList([dir fileStart1 num2str(i) fileEnd2]); % find the distance travelled between last frame and current frame. % Keep the history for TIME_WINDOW number of frames. if (distTimeIndex > TIME_WINDOW) PastDist = PastDist(:,2:end); PastDist(:,end+1) = sqrt((PointList(:,2)-PointListPrev(:,2)).^2 + (PointList(:,3)-PointListPrev(:,3)).^2); else PastDist(:,distTimeIndex) = sqrt((PointList(:,2)-PointListPrev(:,2)).^2 + (PointList(:,3)-PointListPrev(:,3)).^2); end distTimeIndex = distTimeIndex + 1; % if the KLT feature is new in the current frame, set dist travelled in % the previous frames to a large number. locs = find(PointList(:,4)>0); PastDist(locs,:) = 99; % get rid of points that were not successfully traced to current frame. % These features are lost. j = 1; while j<=numel(INDEX_OF_KEY_PTS) if (PointList(INDEX_OF_KEY_PTS(j),4)~=0) if j == 1 INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS(2:end); elseif j == numel(INDEX_OF_KEY_PTS) INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS(1:end-1); else INDEX_OF_KEY_PTS = [INDEX_OF_KEY_PTS(1:j-1) INDEX_OF_KEY_PTS(j+1:end)]; end else j = j + 1; end end % The object size and orientation is not changed. Only it's location is % changed. That is we are assuming only translational motion. % % get the previous center of the ellipse as the centroid of all the KLT % % features associated with the object in the previous frame. % prevCenter = [sum(PointListPrev(INDEX_OF_KEY_PTS,2))/numel(INDEX_OF_KEY_PTS) ... % sum(PointListPrev(INDEX_OF_KEY_PTS,3))/numel(INDEX_OF_KEY_PTS)]; % get the current center of the ellipse as the centroid of all the KLT % features associated with the object in the current frame. currCenter = [sum(PointList(INDEX_OF_KEY_PTS,2))/numel(INDEX_OF_KEY_PTS) ... sum(PointList(INDEX_OF_KEY_PTS,3))/numel(INDEX_OF_KEY_PTS)]; % get the new ellipse boundary coordinates ellipse = drawEllipse([currCenter(2) currCenter(1)],h/2,angle); % Elliminate all key points not inside the ellipse in the current % location. This needs to be removed if we assume the scale of the % object is changing. polygon = [ellipse(2,:)' ellipse(1,:)']; j = 1; while j<=numel(INDEX_OF_KEY_PTS) pt = [PointList(INDEX_OF_KEY_PTS(j),2) PointList(INDEX_OF_KEY_PTS(j),3)]; [Inside] = InsidePolygon(polygon, pt); if (Inside==0) if j == 1 INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS(2:end); elseif j == numel(INDEX_OF_KEY_PTS) INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS(1:end-1); else INDEX_OF_KEY_PTS = [INDEX_OF_KEY_PTS(1:j-1) INDEX_OF_KEY_PTS(j+1:end)]; end else j = j + 1; end end % Loop through the potential key points and remove those potential % keypoint that were not tracked to current frame j = 1; while j<=numel(INDEX_OF_KEY_PTS_POT) if (PointList(INDEX_OF_KEY_PTS_POT(j),4)~=0) % when removing the points ensure it is also removed from % INDEX_OF_KEY_PTS. ***** NOT SURE IF THIS IS NEEDED, THIS % SHOULD BE REDUNDENT CODE ***** k = 1; while (k <= numel(INDEX_OF_KEY_PTS)) if (INDEX_OF_KEY_PTS(k) == INDEX_OF_KEY_PTS_POT(j)) if k == 1 INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS(2:end); elseif k == numel(INDEX_OF_KEY_PTS) INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS(1:end-1); else INDEX_OF_KEY_PTS = [INDEX_OF_KEY_PTS(1:k-1) INDEX_OF_KEY_PTS(k+1:end)]; end k = numel(INDEX_OF_KEY_PTS) + 1; end k = k + 1; end if j == 1 INDEX_OF_KEY_PTS_POT = INDEX_OF_KEY_PTS_POT(2:end); elseif j == numel(INDEX_OF_KEY_PTS_POT) INDEX_OF_KEY_PTS_POT = INDEX_OF_KEY_PTS_POT(1:end-1); else INDEX_OF_KEY_PTS_POT = [INDEX_OF_KEY_PTS_POT(1:j-1) INDEX_OF_KEY_PTS_POT(j+1:end)]; end else j = j + 1; end end % check for new KLT feature points that lie inside the ellipse. If such % a point exist inside the ellipse add it to both INDEX_OF_KEY_PTS_POT % and INDEX_OF_KEY_PTS for j = 1:size(PointList,1) if (PointList(j,4) > TOL) pt = [PointList(j,2) PointList(j,3)]; [Inside] = InsidePolygon(polygon, pt); if (Inside == 1) INDEX_OF_KEY_PTS_POT(end+1) = j; % add to INDEX_OF_KEY_PTS INDEX_OF_KEY_PTS(end+1) = j; end end end if (SHOW_FIG == 1 || makeMovie == 1) % get current frame I = imread([dir2 fileStart1 num2str(i) fileEnd3]); imshow(I); hold on; % Plot all new feature points tempLocs = find(PointList(:,4)>TOL); plot(PointList(tempLocs,2),PointList(tempLocs,3),'.'); % tempLocs = find(PointList(1:130,4)==0); % plot(PointList(tempLocs,2),PointList(tempLocs,3),'r.'); % Plot all KLT features associated to object plot(PointList(INDEX_OF_KEY_PTS,2),PointList(INDEX_OF_KEY_PTS,3),'r.','MarkerSize',5); % Plot the ellipse plot(ellipse(2,:),ellipse(1,:)); % Plot the center of the ellipse plot(currCenter(1),currCenter(2),'g.'); % Plot any existing Potential feature points if (numel(INDEX_OF_KEY_PTS_POT)>0) plot(PointList(INDEX_OF_KEY_PTS_POT,2),PointList(INDEX_OF_KEY_PTS_POT,3),'bo','MarkerSize',5); end if (makeMovie == 0) pause(0.1); else F = getframe(gca); mov = addframe(mov,F); end end % check for motion of all potential KLT feature points. If there are no % motion for the past TIME_WINDOW frames removie it, because it is most % likely an occulded KLT feature reapearing after the object moves over % it. if (distTimeIndex > TIME_WINDOW) j = 1; while j<=numel(INDEX_OF_KEY_PTS_POT) % find the distance traved in the TIME_WINDOW as the sum of all % displacement between two frames totalDisplacement = PastDist(INDEX_OF_KEY_PTS_POT(j),:); totalDisplacement = sum(totalDisplacement); % if there are no displacement remove point from both % INDEX_OF_KEY_PTS. ****** IDEALY WE SHOULD REMOVE IT FROM % INDEX_OF_KEY_PTS_POT AS WELL ****** if (totalDisplacement<=0) % plot the point in red to show it is no longer part of % INDEX_OF_KEY_PTS plot(PointList(INDEX_OF_KEY_PTS_POT(j),2),PointList(INDEX_OF_KEY_PTS_POT(j),3),'ro'); % remove from INDEX_OF_KEY_PTS k = 1; while (k <= numel(INDEX_OF_KEY_PTS)) if (INDEX_OF_KEY_PTS(k) == INDEX_OF_KEY_PTS_POT(j)) if k == 1 INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS(2:end); elseif k == numel(INDEX_OF_KEY_PTS) INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS(1:end-1); else INDEX_OF_KEY_PTS = [INDEX_OF_KEY_PTS(1:k-1) INDEX_OF_KEY_PTS(k+1:end)]; end k = numel(INDEX_OF_KEY_PTS) + 1; end k = k + 1; end end j = j + 1; end end frameInfo(frameInfoIndex).INDEX_OF_KEY_PTS = INDEX_OF_KEY_PTS; frameInfo(frameInfoIndex).INDEX_OF_KEY_PTS_POT = INDEX_OF_KEY_PTS_POT; frameInfo(frameInfoIndex).y = [currCenter(2) currCenter(1)]; frameInfo(frameInfoIndex).h = h; frameInfo(frameInfoIndex).ellipse = ellipse; frameInfoIndex = frameInfoIndex + 1; if (numel(INDEX_OF_KEY_PTS) == 0) break; end end if (makeMovie == 1) mov = close(mov); end