多张面孔检测与跟踪
内容
环境配置
运行代码
1.1 访问:Webcam Support Package。击右下角位置的download,下载Webcam安装包
1.2 需要将安装包放在matlab 的当前路径,双击 usbwebcams.mlpkginstall
1.3 点击该文件根据提示,进行安装
在安装完成结束后,在命令行输入:webcam后出现下图属性情况,则说明安装成功
运行代码
%% detectAndTrackFaces % Automatically detects and tracks multiple faces in a webcam-acquired % video stream. % % Copyright 2013-2014 The MathWorks, Inc clear classes; %% Instantiate video device, face detector, and KLT object tracker vidObj = webcam; faceDetector = vision.CascadeObjectDetector(); % Finds faces by default tracker = MultiObjectTrackerKLT; %% Get a frame for frame-size information frame = snapshot(vidObj); frameSize = size(frame); %% Create a video player instance videoPlayer = vision.VideoPlayer('Position',[200 100 fliplr(frameSize(1:2)+30)]); %% Iterate until we have successfully detected a face bboxes = []; while isempty(bboxes) framergb = snapshot(vidObj); frame = rgb2gray(framergb); bboxes = faceDetector.step(frame); end tracker.addDetections(frame, bboxes); %% And loop until the player is closed frameNumber = 0; keepRunning = true; disp('Press Ctrl-C to exit...'); while keepRunning framergb = snapshot(vidObj); frame = rgb2gray(framergb); if mod(frameNumber, 10) == 0 % (Re)detect faces. % % NOTE: face detection is more expensive than imresize; we can % speed up the implementation by reacquiring faces using a % downsampled frame: % bboxes = faceDetector.step(frame); bboxes = 2 * faceDetector.step(imresize(frame, 0.5)); if ~isempty(bboxes) tracker.addDetections(frame, bboxes); end else % Track faces tracker.track(frame); end % Display bounding boxes and tracked points. displayFrame = insertObjectAnnotation(framergb, 'rectangle',... tracker.Bboxes, tracker.BoxIds); displayFrame = insertMarker(displayFrame, tracker.Points); videoPlayer.step(displayFrame); frameNumber = frameNumber + 1; end %% Clean up release(videoPlayer);
以下函数命名为:MultiObjectTrackerKLT.m
classdef MultiObjectTrackerKLT < handle properties % PointTracker A vision.PointTracker object PointTracker; % Bboxes M-by-4 matrix of [x y w h] object bounding boxes Bboxes = []; % BoxIds M-by-1 array containing ids associated with each bounding box BoxIds = []; % Points M-by-2 matrix containing tracked points from all objects Points = []; % PointIds M-by-1 array containing object id associated with each % point. This array keeps track of which point belongs to which object. PointIds = []; % NextId The next new object will have this id. NextId = 1; % BoxScores M-by-1 array. Low box score means that we probably lost the object. BoxScores = []; end methods %------------------------------------------------------------------ function this = MultiObjectTrackerKLT() % Constructor this.PointTracker = ... vision.PointTracker('MaxBidirectionalError', 2); end %------------------------------------------------------------------ function addDetections(this, I, bboxes) % addDetections Add detected bounding boxes. % addDetections(tracker, I, bboxes) adds detected bounding boxes. % tracker is the MultiObjectTrackerKLT object, I is the current % frame, and bboxes is an M-by-4 array of [x y w h] bounding boxes. % This method determines whether a detection belongs to an existing % object, or whether it is a brand new object. for i = 1:size(bboxes, 1) % Determine if the detection belongs to one of the existing % objects. boxIdx = this.findMatchingBox(bboxes(i, :)); if isempty(boxIdx) % This is a brand new object. this.Bboxes = [this.Bboxes; bboxes(i, :)]; points = detectMinEigenFeatures(I, 'ROI', bboxes(i, :)); points = points.Location; this.BoxIds(end+1) = this.NextId; idx = ones(size(points, 1), 1) * this.NextId; this.PointIds = [this.PointIds; idx]; this.NextId = this.NextId + 1; this.Points = [this.Points; points]; this.BoxScores(end+1) = 1; else % The object already exists. % Delete the matched box currentBoxScore = this.deleteBox(boxIdx); % Replace with new box this.Bboxes = [this.Bboxes; bboxes(i, :)]; % Re-detect the points. This is how we replace the % points, which invariably get lost as we track. points = detectMinEigenFeatures(I, 'ROI', bboxes(i, :)); points = points.Location; this.BoxIds(end+1) = boxIdx; idx = ones(size(points, 1), 1) * boxIdx; this.PointIds = [this.PointIds; idx]; this.Points = [this.Points; points]; this.BoxScores(end+1) = currentBoxScore + 1; end end % Determine which objects are no longer tracked. minBoxScore = -2; this.BoxScores(this.BoxScores < 3) = ... this.BoxScores(this.BoxScores < 3) - 0.5; boxesToRemoveIds = this.BoxIds(this.BoxScores < minBoxScore); while ~isempty(boxesToRemoveIds) this.deleteBox(boxesToRemoveIds(1)); boxesToRemoveIds = this.BoxIds(this.BoxScores < minBoxScore); end % Update the point tracker. if this.PointTracker.isLocked() this.PointTracker.setPoints(this.Points); else this.PointTracker.initialize(this.Points, I); end end %------------------------------------------------------------------ function track(this, I) % TRACK Track the objects. % TRACK(tracker, I) tracks the objects into frame I. tracker is the % MultiObjectTrackerKLT object, I is the current video frame. This % method updates the points and the object bounding boxes. [newPoints, isFound] = this.PointTracker.step(I); this.Points = newPoints(isFound, :); this.PointIds = this.PointIds(isFound); generateNewBoxes(this); if ~isempty(this.Points) this.PointTracker.setPoints(this.Points); end end end methods(Access=private) %------------------------------------------------------------------ function boxIdx = findMatchingBox(this, box) % Determine which tracked object (if any) the new detection belongs to. boxIdx = []; for i = 1:size(this.Bboxes, 1) area = rectint(this.Bboxes(i,:), box); if area > 0.2 * this.Bboxes(i, 3) * this.Bboxes(i, 4) boxIdx = this.BoxIds(i); return; end end end %------------------------------------------------------------------ function currentScore = deleteBox(this, boxIdx) % Delete object. this.Bboxes(this.BoxIds == boxIdx, :) = []; this.Points(this.PointIds == boxIdx, :) = []; this.PointIds(this.PointIds == boxIdx) = []; currentScore = this.BoxScores(this.BoxIds == boxIdx); this.BoxScores(this.BoxIds == boxIdx) = []; this.BoxIds(this.BoxIds == boxIdx) = []; end %------------------------------------------------------------------ function generateNewBoxes(this) % Get bounding boxes for each object from tracked points. oldBoxIds = this.BoxIds; oldScores = this.BoxScores; this.BoxIds = unique(this.PointIds); numBoxes = numel(this.BoxIds); this.Bboxes = zeros(numBoxes, 4); this.BoxScores = zeros(numBoxes, 1); for i = 1:numBoxes points = this.Points(this.PointIds == this.BoxIds(i), :); newBox = getBoundingBox(points); this.Bboxes(i, :) = newBox; this.BoxScores(i) = oldScores(oldBoxIds == this.BoxIds(i)); end end end end %-------------------------------------------------------------------------- function bbox = getBoundingBox(points) x1 = min(points(:, 1)); y1 = min(points(:, 2)); x2 = max(points(:, 1)); y2 = max(points(:, 2)); bbox = [x1 y1 x2 - x1 y2 - y1]; end
运行效果图(因为是夜晚,只有我一人检测,所有没有多目标检测)
欢迎加群
群资料