gusucode.com > vision工具箱matlab源码程序 > vision/+vision/PeopleDetector.m
classdef PeopleDetector < matlab.System %PeopleDetector Detect upright people using HOG features % DETECTOR = vision.PeopleDetector creates a System object that % detects upright, unoccluded, people. The detector uses Histogram of % Oriented Gradient (HOG) features and a trained Support Vector % Machine (SVM) classifier. % % DETECTOR = vision.PeopleDetector(MODEL) creates a System object and % sets the ClassificationModel to MODEL. The input MODEL can be % either 'UprightPeople_128x64' or 'UprightPeople_96x48'. % % DETECTOR = vision.PeopleDetector(...,Name,Value) configures the % System object properties, specified as one or more name-value pair % arguments. Unspecified properties have default values. % % Step method syntax: % % BBOXES = step(DETECTOR,I) performs multi-scale object detection on % the input image, I, and returns, BBOXES, an M-by-4 matrix defining % M bounding boxes containing the detected people. Each row in BBOXES % is a four-element vector, [x y width height], that specifies the % upper left corner and size of a bounding box in pixels. When no % people are detected, BBOXES is empty. I must be a grayscale or % truecolor (RGB) image. % % [BBOXES, SCORES] = step(DETECTOR,I) returns the detection SCORES % for each bounding box in an M-by-1 vector. The SCORES are positive % values. Larger score values indicate a higher confidence in the % detection. % % [...] = step(DETECTOR, I, ROI) detects people within the % rectangular search region specified by ROI. ROI must be a 4-element % vector, [x y width height], that defines a rectangular region of % interest within image I. The 'UseROI' property must be true to use % this syntax. % % System objects may be called directly like a function instead of using % the step method. For example, y = step(obj, x) and y = obj(x) are % equivalent. % % PeopleDetector methods: % % step - See above description for use of this method % release - Allow property value and input characteristics changes % clone - Create people object detector object with same property % values % isLocked - Locked status (logical) % % PeopleDetector properties: % % ClassificationModel - Name of the classification model % ClassificationThreshold - People classification threshold % MinSize - Size of the smallest region containing a % person % MaxSize - Size of the biggest region containing a % person % ScaleFactor - Scaling for multi-scale object detection % WindowStride - Detection window stride % MergeDetections - Control whether similar detections are % merged % UseROI - Detect people within a region of interest % % % Example: Detect people % % ---------------------------- % % % Create people detector % peopleDetector = vision.PeopleDetector; % % I = imread('visionteam1.jpg'); % [bboxes, scores] = step(peopleDetector, I); % Detect people % % % Annotate detected people % I = insertObjectAnnotation(I, 'rectangle', bboxes, scores); % figure, imshow(I) % title('Detected people and detection scores'); % % See also detectPeopleACF, vision.CascadeObjectDetector, % insertObjectAnnotation, extractHOGFeatures % Copyright 2012-2016 The MathWorks, Inc. % References: % ----------- % [1] Dalal, N. and Triggs, B., Histograms of Oriented Gradients for % Human Detection. CVPR 2005. %#codegen %#ok<*EMCA> properties(Nontunable) %ClassificationModel Name of the classification model % Specify the name of the model as a string. Valid values for % this property are 'UprightPeople_128x64' and % 'UprightPeople_96x48', where the image size used for training % is 128-by-64 and 96-by-48 pixels, respectively. Note that the % images used to train the models include background pixels % around the actual person. Therefore, the actual size of a % detected person is smaller than the training image size. % % Default: 'UprightPeople_128x64' ClassificationModel = 'UprightPeople_128x64'; end properties %ClassificationThreshold People classification threshold % Specify a threshold value as a non-negative scalar. Use this % threshold to control the classification of individual image % sub-regions as person or non-person during multi-scale object % detection. Increase this threshold in situations where many % false detections occur. This property is tunable. Typical % values range from 0 to 4. % % Default: 1 ClassificationThreshold = 1; %MinSize Size of the smallest region containing a person % Specify the size of the smallest region containing a person, in % pixels, as a two-element vector, [height width]. When you know % the minimum person size to detect, you can reduce computation % time by setting this property to a value larger than the image % size used to train the classification model. When you do not % specify this property, the object sets it to the image size % used to train the classification model. This property is % tunable. % % Default: [] MinSize = []; %MaxSize Size of the biggest region containing a person % Specify the size of the biggest region containing a person, in % pixels, as a two-element vector, [height width]. When you know % the maximum person size to detect, you can reduce computation % time by setting this property to a value smaller than the size % of the input image. When you do not specify this property, the % object sets it to the input image size. This property is % tunable. % % Default: [] MaxSize = []; %ScaleFactor Scaling for multi-scale object detection % Specify the factor used to incrementally scale the detection % resolution between MinSize and MaxSize. The ScaleFactor must be % greater than or equal to 1.0001. At each increment, N, the % detection resolution is % % round(TrainingSize*(ScaleFactor^N)). % % The TrainingSize is [128 64] for the 'UprightPeople_128x64' % model and [96 48] for the 'UprightPeople_96x48' model. % Decreasing the scale factor can increase the detection % accuracy. However, doing so increases the computation time. % This property is tunable. % % Default: 1.05 ScaleFactor = 1.05; %WindowStride Detection window stride % Specify a scalar or a two-element vector [x y] in pixels for % the detection window stride. The object uses the window stride % to slide the detection window across the image. When you % specify this value as a vector, the first and second elements % are the stride size in the x and y directions. When you specify % this value as a scalar, the stride is the same for both x and % y. Decreasing the window stride can increase the detection % accuracy. However, doing so increases computation time. % Increasing the window stride beyond [8 8] can lead to a greater % number of missed detections. This property is tunable. % % Default: [8 8] WindowStride = [8 8]; end properties(Logical, Nontunable) %MergeDetections Control whether similar detections are merged % Specify a logical scalar to control whether similar detections % are merged using a mean shift based algorithm. Set this % property to false to output unprocessed bounding boxes and % detection scores. This is useful if you want to perform a % custom merge operation. % % Default: true MergeDetections = true; % UseROI Detect objects within a ROI % Set to true to detect objects within a rectangular region of % interest within I. % % Default: false UseROI = false; end properties (Transient,Access = private) pHOGDescriptor; pTrainingSize; end methods %------------------------------------------------------------------ % Constructor %------------------------------------------------------------------ function obj = PeopleDetector(varargin) if (isSimMode()) obj.pHOGDescriptor = vision.internal.HOGDescriptor; else obj.pHOGDescriptor = ... vision.internal.buildable.HOGDescriptorBuildable.HOGDescriptor_construct(); end setProperties(obj,nargin,varargin{:},'ClassificationModel'); setupModel(obj); validatePropertiesImpl(obj); end %------------------------------------------------------------------ % ClassificationModel set method %------------------------------------------------------------------ function set.ClassificationModel(obj,value) validateattributes(value,{'char'},{'nonempty','row'}, ... mfilename, 'ClassificationModel'); obj.ClassificationModel = value; setupModel(obj); end %------------------------------------------------------------------ % ClassificationThreshold set method %------------------------------------------------------------------ function set.ClassificationThreshold(obj,value) validateattributes( value,{'numeric'},... {'scalar', '>=',0,'real', 'nonempty','nonsparse','finite'},... mfilename,'ClassificationThreshold'); obj.ClassificationThreshold = value; end %------------------------------------------------------------------ % ScaleFactor set method %------------------------------------------------------------------ function set.ScaleFactor(obj,value) validateattributes( value,{'numeric'},... {'scalar', '>=',1.0001,'real', 'nonempty','nonsparse','finite'},... mfilename,'ScaleFactor'); obj.ScaleFactor = value; end %------------------------------------------------------------------ % MinSize set method %------------------------------------------------------------------ function set.MinSize(obj,value) validateSize('MinSize',value); obj.MinSize = value; end %------------------------------------------------------------------ % MaxSize set method %------------------------------------------------------------------ function set.MaxSize(obj,value) validateSize('MaxSize',value); obj.MaxSize = value; end %------------------------------------------------------------------ % WindowStride set method %------------------------------------------------------------------ function set.WindowStride(obj,value) validateattributes(value,... {'numeric'}, ... {'real','positive','integer', ... 'nonempty','row','vector', 'nonsparse'},... mfilename,'WindowStride'); if isscalar(value) obj.WindowStride = [value value]; else validateattributes(value,{'numeric'},{'numel',2},... mfilename,'WindowStride'); obj.WindowStride = value; end end %------------------------------------------------------------------ % MergeDetections set method %------------------------------------------------------------------ function set.MergeDetections(obj,value) obj.MergeDetections = value; end %------------------------------------------------------------------ % UseROI set method %------------------------------------------------------------------ function set.UseROI(obj, value) obj.UseROI = logical(value); end end properties (Constant, Hidden, Nontunable) ClassificationModelSet = matlab.system.StringSet({'UprightPeople_128x64','UprightPeople_96x48'}); end methods(Access = protected) %------------------------------------------------------------------ % Cross validate properties %------------------------------------------------------------------ function validatePropertiesImpl(obj) % validate that MinSize is greater than or equal to the minimum % object size used to train the classification model if ~isempty(obj.MinSize) coder.internal.errorIf(any(obj.MinSize < obj.pTrainingSize) , ... 'vision:ObjectDetector:minSizeLTTrainingSize', ... obj.pTrainingSize(1),obj.pTrainingSize(2)); end % validate the MaxSize is greater than the TrainingSize when % MinSize is not specified if isempty(obj.MinSize) && ~isempty(obj.MaxSize) coder.internal.errorIf(any(obj.pTrainingSize >= obj.MaxSize) , ... 'vision:ObjectDetector:modelMinSizeGTMaxSize', ... obj.pTrainingSize(1),obj.pTrainingSize(2)); end % validate that MinSize < MaxSize if ~isempty(obj.MaxSize) && ~isempty(obj.MinSize) coder.internal.errorIf(any(obj.MinSize >= obj.MaxSize) , ... 'vision:ObjectDetector:minSizeGTMaxSize'); end end %------------------------------------------------------------------ % Setup implementation %------------------------------------------------------------------ function setupModel(obj,~) % setup the HOG people detector switch obj.ClassificationModel case 'UprightPeople_128x64' model = 1; obj.pTrainingSize = [128 64]; case 'UprightPeople_96x48' model = 2; obj.pTrainingSize = [96 48]; end if (isSimMode()) obj.pHOGDescriptor.setup(model); else vision.internal.buildable.HOGDescriptorBuildable.HOGDescriptor_setup(obj.pHOGDescriptor, model); end end %------------------------------------------------------------------ % Release method implementation %------------------------------------------------------------------ function releaseImpl(obj) if (~isSimMode()) % delete HOGDescriptor object vision.internal.buildable.HOGDescriptorBuildable.HOGDescriptor_deleteObj(obj.pHOGDescriptor); end end %------------------------------------------------------------------ % Validate inputs to STEP method %------------------------------------------------------------------ function validateInputsImpl(obj, I, varargin) validateattributes(I,... {'uint8','uint16','double','single','int16'},... {'real','nonsparse'},... 'PeopleDetector','I',2); numDims = ndims(I); % verify I is 2D or 3D coder.internal.errorIf(~any(numDims == [2 3]), ... 'vision:dims:imageNot2DorRGB'); % verify that a 3D I has 3 color planes coder.internal.errorIf(numDims == 3 && size(I,3) ~= 3, ... 'vision:dims:imageNot2DorRGB'); if obj.UseROI vision.internal.detector.checkROI(varargin{1},size(I)); end end %------------------------------------------------------------------ % STEP method implementation %------------------------------------------------------------------ function [bbox, score] = stepImpl(obj,I,varargin) if obj.UseROI roi = varargin{1}; else roi = zeros(0,4); end Iroi = vision.internal.detector.cropImageIfRequested(I, roi, obj.UseROI); Iu8 = im2uint8(Iroi); if (isSimMode()) postMergeThreshold = 0; [bbox, score] = obj.pHOGDescriptor.detectMultiScale(Iu8, ... double(obj.ScaleFactor), ... double(obj.ClassificationThreshold), ... postMergeThreshold, ... int32(obj.MinSize),... int32(obj.MaxSize),... int32(obj.WindowStride),... obj.MergeDetections); else if isempty(obj.MinSize) obj_MinSize = [0 0]; else obj_MinSize = obj.MinSize; end if isempty(obj.MaxSize) obj_MaxSize = [0 0]; else obj_MaxSize = obj.MaxSize; end postMergeThreshold = 0; [bbox, score] = vision.internal.buildable.HOGDescriptorBuildable.HOGDescriptor_detectMultiScale(obj.pHOGDescriptor ,... Iu8, ... obj.ScaleFactor, ... % double obj.ClassificationThreshold, ... % double postMergeThreshold, ... % double obj_MinSize,... % int32 obj_MaxSize,... % int32 obj.WindowStride,... % int32 obj.MergeDetections); % logical end bbox = clipBBox(bbox, size(Iroi)); bbox(:,1:2) = vision.internal.detector.addOffsetForROI(bbox(:,1:2), roi, obj.UseROI); end %------------------------------------------------------------------ % Return the number of inputs %------------------------------------------------------------------ function num_inputs = getNumInputsImpl(obj) if obj.UseROI num_inputs = 2; else num_inputs = 1; end end %------------------------------------------------------------------ % Return the number of outputs %------------------------------------------------------------------ function num_outputs = getNumOutputsImpl(~) num_outputs = 2; end %------------------------------------------------------------------ % Custom save/load method %------------------------------------------------------------------ function s = saveObjectImpl(obj) s = saveObjectImpl@matlab.System(obj); end function loadObjectImpl(obj,s,~) if ~isfield(s, 'UseROI') % UseROI added in R2015a s.UseROI = false; end loadObjectImpl@matlab.System(obj, s); end end end % of classdef %-------------------------------------------------------------------------- % Validation for MinSize and MaxSize %-------------------------------------------------------------------------- function validateSize(prop,value) % By default MaxSize/MinSize is [], and it can be set to empty too. validateattributes( value,... {'numeric'}, {'real','nonsparse','finite','2d','integer', '>=',0},... mfilename,prop); % Using 'vector',2 in validateattributes fails for [] so the % following check makes sure that MaxSize has 2-elements coder.internal.errorIf(~isempty(value) && (numel(value) ~= 2), ... 'vision:ObjectDetector:invalidSize',prop); end %========================================================================== function flag = isSimMode() flag = isempty(coder.target); end %========================================================================== % Clip the bounding box when it is positioned outside the image. This can % happen when detections occur near the image boundaries. %========================================================================== function clippedBBox = clipBBox(bbox, imgSize) % bounding boxes are returned as doubles clippedBBox = double(bbox); % The original bounding boxes all overlap the image. Therefore, a check to % remove non-overlapping boxes is not required. % Get coordinates of upper-left (x1,y1) and bottom-right (x2,y2) corners. x1 = clippedBBox(:,1); y1 = clippedBBox(:,2); x2 = clippedBBox(:,1) + clippedBBox(:,3) - 1; y2 = clippedBBox(:,2) + clippedBBox(:,4) - 1; % Clip boxes so that they are within the upper-left corner of the image xIndex = x1 < 1; yIndex = y1 < 1; clippedBBox(xIndex, 1) = 1; clippedBBox(yIndex, 2) = 1; % Update the width and height after clipping clippedBBox(xIndex, 3) = x2(xIndex); clippedBBox(yIndex, 4) = y2(yIndex); % Clip boxes so that they are within the lower-right corner of the image. clippedBBox(:,3) = min(imgSize(2), x2) - clippedBBox(:,1) + 1; clippedBBox(:,4) = min(imgSize(1), y2) - clippedBBox(:,2) + 1; end