Create Instance Segmentation Training Data From Ground Truth
This example shows how to create instance segmentation training data from a groundTruth object. To train a Mask R-CNN and SOLO v2 network using the trainMaskRCNN and trainSOLOv2 functions, respectively, format your input data as a 1-by-4 cell array containing the RGB training image, bounding boxes, instance labels, and instance masks. Convert your polygon ground data into a set of binary instance masks and axis-aligned rectangles for training.
First, load the ground truth, the images visionteam.jpg and visionteam1.jpg, and create a groundTruth object.
gt = load("gTruth.mat"); src = groundTruthDataSource(["visionteam.jpg","visionteam1.jpg"]); gTruth = groundTruth(src,gt.labelDef,gt.labelData)
gTruth =
groundTruth with properties:
DataSource: [1×1 groundTruthDataSource]
LabelDefinitions: [1×5 table]
LabelData: [2×1 table]
Load the training images using the ImageDatastore object.
imds = imageDatastore(gTruth.DataSource.Source);
Gather the polygon data from the groundTruth object and group it by label type so that all the polygon data for all classes is combined.
labelData = gatherLabelData(gTruth,labelType.Polygon,GroupLabelData="LabelType");Identify which images have label data and only keep those rows of data.
hasData = rowfun(@(x)~isempty(x{1}),labelData{1});
imds = subset(imds,hasData{:,1});
labels = labelData{1}(hasData{:,1},:);Create an arrayDatastore to read the label data.
labelDS = arrayDatastore(labels{:,1},IterationDimension=1,OutputType="same");Combine the image and label data. Apply a data transform using the helperPolygonToMaskTransform helper function to convert each polygon into a bounding box and a stack of binary masks. Then, preview the results.
ds = combine(imds,labelDS); tds = transform(ds,@(data,info)helperPolygonToMaskTransform(data,info),IncludeInfo=true); data = preview(tds)
data=1×4 cell array
413×800×3 uint8 3×4 double 3×1 cell 413×800×3 logical
To speed up training, write the binary instance masks, bounding boxes, and labels to disk into a .mat file, instead of computing them during training, using the helperWriteMaskBoxesAndLabels helper function. The name of the MAT file matches the name of the corresponding image.
labelDataFolder = fullfile(pwd,"masksBoxesAndLabels"); if ~isfolder(labelDataFolder) mkdir(labelDataFolder); classes = string(gTruth.LabelDefinitions.Name); mkdir(labelDataFolder); writeall(tds,labelDataFolder,... WriteFcn=@(data,info,fmt)helperWriteMaskBoxesAndLabels(data,info,fmt,classes)); end
Create a fileDatastore object to read MAT files during training using the helperReadMaskBoxesAndLabels helper function. Ensure that you read only valid MAT files using the helperValidMATFiles helper function.
fs = helperValidMATFiles(labelDataFolder); labelDS = fileDatastore(fs,... IncludeSubfolders=true,... ReadFcn=@helperReadMaskBoxesAndLabels,... FileExtensions=".mat",... UniformRead=true);
Order the image and MAT files so that they are in the same order.
[~,ordImgs] = sortrows(imds.Files); [~,ordLabels] = sortrows(labelDS.Files); imds = subset(imds,ordImgs); labelDS = subset(labelDS,ordLabels);
Combine the image and label datastores into a datastore you can use for training the Mask R-CNN and SOLOv2 instance segmentation networks. Preview the training datastore.
ds = combine(imds,labelDS); preview(ds)
ans=1×4 cell array
413×800×3 uint8 3×4 double 3×1 categorical 413×800×3 logical
Supporting Functions
helperPolygonToMaskTransform
function [out,info] = helperPolygonToMaskTransform(data,info) % Transform polygons into binary instance masks and bounding boxes. out = cell(size(data,1),4); for i = 1:size(data,1) I = data{i,1}; annotationStruct = data{i,2}; if isempty(annotationStruct) maskset = false(0,0,0); boxes = zeros(0,4); labels = createArray(0,1,Like=""); else s = data{i,2}; % Convert polygon into a set of binary masks and a set of bounding % boxes. [maskset,boxes,labels] = helperPolygonsToMasksAndBoxes(s,size(I)); end % Package output in the required for training. out{i,1} = I; out{i,2} = boxes; out{i,3} = labels; out{i,4} = maskset; end end
helperPolygonsToMasksAndBoxes
function [maskset,boxes,labels] = helperPolygonsToMasksAndBoxes(s,sizeI) % Transform polygons into binary instance masks and bounding boxes. % The input s is an M-by-N cell. Each row contains ROI data for a particular class. numInstances = size(s,1); maskset = false([sizeI(1:2) numInstances]); % Generate labels for each object instance. labels = s(:,2); % Convert polygons into binary instance masks and bounding boxes. boxes = zeros(numInstances,4); for i = 1:numInstances poly = s{i,1}; minxy = min(poly); maxxy = max(poly); boxes(i,:) = reshape([minxy maxxy-minxy],[],4); maskset(:,:,i) = poly2mask(poly(:,1),poly(:,2),sizeI(1),sizeI(2)); end end
helperWriteMaskBoxesAndLabels
function helperWriteMaskBoxesAndLabels(data,writeInfo,~,classes) % Write binary instance masks, boxes, and labels into a MAT file. [fPath,fName,~] = fileparts(writeInfo.SuggestedOutputName); labelData.Boxes = data{2}; labelData.Labels = categorical(string(data{3}),classes); labelData.Masks = data{4}; save(fullfile(fPath,fName+".mat"),"labelData"); end
helperReadMaskBoxesAndLabels
function data = helperReadMaskBoxesAndLabels(filename) % Read instance masks, boxes, and labels from a MAT file. loaded = load(filename); data = cell(1,3); data{1} = loaded.labelData.Boxes; data{2} = loaded.labelData.Labels; data{3} = loaded.labelData.Masks; end
helperValidMATFiles
function fs = helperValidMATFiles(labelDataFolder) fs = matlab.io.datastore.FileSet(labelDataFolder,"FileExtensions","*.mat",IncludeSubfolders=true); if ismac % Remove files beginning with "._" that mac OS adds when writing to % certain file systems. files = fs.FileInfo.Filename; fs = fs.subset(~files.contains("._")); end end
See Also
Topics
- Perform Instance Segmentation Using SOLOv2
- Perform Instance Segmentation Using Mask R-CNN
- Get Started with Instance Segmentation Using Deep Learning
- Get Started with SOLOv2 for Instance Segmentation
- Getting Started with Mask R-CNN for Instance Segmentation
- Deep Learning in MATLAB (Deep Learning Toolbox)
- Datastores for Deep Learning (Deep Learning Toolbox)