gusucode.com > vision工具箱matlab源码程序 > vision/+vision/+internal/+cascadeTrainer/createOcvVecFile.m

    function createOcvVecFile(positives, totalNumInstances,...
    outputVecFilename, objectTrainingSize)
%function createOcvVecFile(positives, outputVecFilename, sampleWidth, ...
%  sampleHeight) writes an OpenCV style "vec" file to be used for training 
%  a cascade object detector.
%
%    positives           struct array that contains image file names with 
%                        the associated bounding boxes.
% 
%    totalNumInstances   number of bounding boxes in all images, should be
%                        computed in trainCascadeObjectDetector.
%
%    outputVecFilename   name of the output vec file
%
%    objectTrainingSize  [sampleHeight, sampleWidth], the size to which all 
%                        samples will be resized

vecFile = openOutputVecFile(outputVecFilename);

writeHeader(vecFile, totalNumInstances, objectTrainingSize);

% count the number of samples written as a sanity check
samplesWritten = 0;

for imgNum = 1:length(positives)
    
    boundingBoxes = getBoundingBoxes(positives, imgNum, vecFile);
    img = readImage(positives, imgNum, vecFile);
    
    % readImage returns [] if it tries to read a non-image file.
    % Skipping silently.
    if ~isempty(img)
        
        % If img is color, convert it to grayscale
        if ndims(img) == 3
            img = rgb2gray(img);
        end
    
        % For each instance in image
        for boundingBoxNum = 1:size(boundingBoxes, 1)            
            % Extract the sub-image specified by the bounding box
            imgPatch = cropROI(img, boundingBoxes, boundingBoxNum, ...
                imgNum, vecFile);
            
            % Resize the sub-image to [sampleHeight sampleWidth]
            % Note that width and height must be revesed to comply with
            % imresize convention.
            imgPatchResize = imresize(imgPatch, objectTrainingSize);

            % Write to image data to vec file
            writeImageInfoToVecFile(imgPatchResize, vecFile.id);
            samplesWritten = samplesWritten + 1;
        end
    end
end

% If everything succeeds, close the outputVecFile.
fclose(vecFile.id);

% Sanity check. Must always pass.
assert(samplesWritten == totalNumInstances);

%==========================================================================
% Create a new output vec file with validation
% Return a struct with fields 
%   name   the file name
%   id     the file id returned by fopen
% Error if unable to create the file
function vecFile = openOutputVecFile(outputVecFilename)
% trainCascadeObjectDetector.m has already checked to ensure that a file
% with this name does not already exist
vecFile.name = outputVecFilename;
vecFile.id = fopen(vecFile.name, 'w');
if(vecFile.id ==  -1)
    error(message('vision:trainCascadeObjectDetector:cannotWriteVecFile'));
end

%==========================================================================
% Write header information to the outputVecFile
function writeHeader(vecFile, totalNumInstances, objectTrainingSize)

fwrite(vecFile.id, totalNumInstances, 'int');
fwrite(vecFile.id, prod(objectTrainingSize), 'int');

% mysterious min/max values from OpenCV
tmp = int16(0);
fwrite(vecFile.id, tmp, 'short');
fwrite(vecFile.id, tmp, 'short');

%==========================================================================
% Get bounding boxes associated with the current image and check their
% validity.
function currentBoundingBoxes = getBoundingBoxes(instances, imgNum, vecFile)
currentImageInstance = instances(imgNum);
currentBoundingBoxes = round(currentImageInstance.objectBoundingBoxes);
% Check that currentBoundingBoxes is an M-by-4 array
if (~ismatrix(currentBoundingBoxes)) || (size(currentBoundingBoxes, 2)~=4) ...
        || (size(currentBoundingBoxes, 1)==0)
    errMsg = message('vision:trainCascadeObjectDetector:invalidBoundingBoxes',...
        imgNum, currentImageInstance.imageFilename);
    cleanUpAndErrorOut(errMsg, vecFile);
end

%==========================================================================
% Read the image and validate it
function img = readImage(instances, imgNum, vecFile)
currentImageInstance = instances(imgNum);
% Read the image
imgName = currentImageInstance.imageFilename;
if ~exist(imgName, 'file');
    errMsg = message('vision:trainCascadeObjectDetector:cannotFindFile',...
        imgNum, imgName);
    cleanUpAndErrorOut(errMsg, vecFile);
end

img = vision.internal.cascadeTrainer.readImage(imgName);

%==========================================================================
% Crop the ROI specified by the bounding box and validate it
function imgPatch = cropROI(img, boxes, boundingBoxNum, imgNum, vecFile)

x      = boxes(boundingBoxNum, 1);
y      = boxes(boundingBoxNum, 2);
width  = boxes(boundingBoxNum, 3);
height = boxes(boundingBoxNum, 4);

% Check bounding box bounds - within image limits?
if any(boxes(boundingBoxNum, :) < 1) || y + height - 1 > size(img, 1) || ...
        x + width - 1 > size(img, 2)
    errMsg = message('vision:trainCascadeObjectDetector:cannotReadBoundingBox',...
        boundingBoxNum, imgNum);
    cleanUpAndErrorOut(errMsg, vecFile);
end

% Crop the ROI specified by the bounding box
imgPatch = img(y:y+height-1, x:x+width-1);

%==========================================================================
% Write image intensity data in row-major format as short data type to the
% outputVecFile
function writeImageInfoToVecFile(img, outputVecFile)
% 0 separator
chartmp = uint8(0);
fwrite(outputVecFile, chartmp, 'uchar');
% image data
fwrite(outputVecFile, img', 'short');

%==========================================================================
% Error in the function. Close the vec file, delete it, and throw error
% message
function cleanUpAndErrorOut(errorMessage, vecFile)
fclose(vecFile.id);
delete(vecFile.name);
error(errorMessage);