Main Content

深層学習を使用したビン ピッキングの 6-DoF 姿勢推定の実行

この例では、RGB-D イメージと深層学習ネットワークを使用して、ビン内の機械部品の 3 次元位置と向きを推定することにより、6 自由度 (6-DoF) の姿勢推定を実行する方法を示します。

6-DoF 姿勢は、基準フレームに対する 3 次元空間内のオブジェクトの回転と平行移動です。イメージと深度センサーを使用した 6-DoF 姿勢推定は、ロボティクスや拡張現実のためのインテリジェントなビン ピッキングなど、多くのコンピューター ビジョン システムの鍵となります。インテリジェントなビン ピッキングにおける 6-DoF 姿勢は、ある標準的な姿勢から、シーンをキャプチャするカメラによって観測された姿勢へのオブジェクトの回転と平行移動です。RGB イメージと深度測定値の両方をキャプチャする RGB-D センサーとペアになったロボット アームは、6-DoF 姿勢推定モデルを使用し、RGB-D センサーに対するオブジェクトの位置と向きを同時に検出して推定できます。推定された姿勢は、下流のタスクでオブジェクトへのパスを計画したり、特定のロボット グリッパーでオブジェクトを最も適切に掴む方法を決定したりするために使用できます。

この例では、事前学習済みの Pose Mask R-CNN ネットワークを使用して 6-DoF 姿勢推定を実行します。これは、6-DoF 姿勢推定用に設計された畳み込みニューラル ネットワーク (CNN) の一種です [1][2]。6-DoF 姿勢は、3 次元の回転と平行移動で構成され、rigidtform3d オブジェクトとして保存されます。次に、ネットワーク予測を可視化し、ジオメトリベースの後処理を適用して初期姿勢予測を調整し、結果をグラウンド トゥルース姿勢と比較して評価します。最後に、オプションで転移学習を使用して、ビンピッキング データ セットでネットワークに学習させることができます。

この例では、Computer Vision Toolbox™ Model for Pose Mask R-CNN 6-DoF Pose Estimation が必要です。アドオン エクスプローラーから、Computer Vision Toolbox Model for Pose Mask R-CNN 6-DoF Object Pose Estimation をインストールできます。アドオンのインストールの詳細については、アドオンの取得と管理を参照してください。Computer Vision Toolbox Model for Pose Mask R-CNN 6-DoF Object Pose Estimation には、Deep Learning Toolbox™ と Image Processing Toolbox™ が必要です。

サンプル データの読み込み

サンプル RGB イメージとそれに関連する深度イメージおよびカメラの内部パラメーターをワークスペースに読み込みます。

imRGB = imread("image_00050.jpg");
load("depth_00050.mat","imDepth")
load("intrinsics_00050.mat","intrinsics")

機械部品を表すオブジェクト形状の 3 次元点群モデルをワークスペースに読み込みます。これらの 3 次元モデルを使用して、6-DoF 姿勢予測を可視化します。

load("pointCloudModels.mat","modelClassNames","modelPointClouds")

このサンプルに関連付けられたグラウンド トゥルースの注釈 (境界ボックス、クラス、セグメンテーション マスク、および 6-DoF 姿勢) は、深層ニューラル ネットワークの学習に使用します。注釈をワークスペースに読み込みます。

load("groundTruth_00050.mat")

グラウンド トゥルースの注釈と姿勢の可視化

サンプルの RGB イメージを表示します。

figure
imshow(imRGB);
title("RGB Image")

深度イメージを表示します。深度イメージは、カメラからシーン内の各ピクセルまでの距離、つまり深度を示します。

figure
imshow(imDepth);
title("Depth Image")

グラウンド トゥルース データの可視化

関数 insertObjectMask を使用して、元のイメージにグラウンド トゥルース マスクを重ね合わせます。

imRGBAnnot = insertObjectMask(imRGB,gtMasks,Opacity=0.5);

関数 insertObjectAnnotation を使用して、元のイメージにオブジェクトの境界ボックスを重ね合わせます。

imRGBAnnot = insertObjectAnnotation(imRGBAnnot,"rectangle",gtBoxes,gtClasses);

元のイメージにグラウンド トゥルース マスクと境界ボックスを重ね合わせて表示します。

figure
imshow(imRGBAnnot); 
title("Ground Truth Annotations")

グラウンド トゥルース姿勢の可視化

オブジェクトの 3 次元回転と平行移動を可視化するには、各オブジェクト クラスの点群に姿勢変換を適用し、点群を元のイメージに表示します。姿勢変換された点群をイメージに投影すると、シーン内の機械部品の向きと完全に一致します。

各オブジェクト クラスに対応する姿勢の色、姿勢の色の数、オブジェクトの数を定義し、姿勢変換された点群を格納する RGB イメージ imGTPose のコピーを作成します。

poseColors = ["blue","green","magenta","cyan"];
numPoseColors = length(poseColors);
numObj = size(gtBoxes,1);  
imGTPose = imRGB;

グラウンド トゥルース オブジェクトの姿勢を可視化するには、関数 rigidtform3d を使用して点群をイメージに投影し、投影された点群をサンプル イメージに重ねて表示します。

for gIndex = 1:numObj
    gClass = string(gtClasses(gIndex));
    
    % Retrieve the 3D object point cloud data.
    ptCloud = modelPointClouds(modelClassNames == gClass);

    % Apply the pose transformation to the point cloud.
    ptCloudGT = pctransform(ptCloud,gtPoses(gIndex));

    % Subsample the point clouds to 5% of the original number of points 
    % for a cleaner visualization.
    ptCloudGT = pcdownsample(ptCloudGT,"random",0.05);

    % Project the transformed point clouds onto the image using the camera
    % intrinsic parameters and identity transform for camera pose and position.
    projectedPoints = world2img(ptCloudGT.Location,rigidtform3d,intrinsics);
    
    % Overlay the 2-D projected points over the image.
    imGTPose = insertMarker(imGTPose,[projectedPoints(:,1) projectedPoints(:,2)], ...
        "circle",Size=1,Color=poseColors(modelClassNames==gClass));
end

figure
imshow(imGTPose);
title("Ground Truth Poses")

事前学習済みの Pose Mask R-CNN モデルを使用した 6-DoF 姿勢の予測

posemaskrcnnオブジェクトを使用して、事前学習済みの Pose Mask R-CNN モデルを作成します。

net = posemaskrcnn("resnet50-pvc-parts");

オブジェクト関数predictPoseを使用して、イメージ内の機械部品の 6-DoF 姿勢を予測します。予測信頼度のしきい値 Threshold を 0.5 に指定します。

[poses,labels,scores,boxes,masks] = predictPose(net, ...
                imRGB,imDepth,intrinsics,Threshold=0.5, ...
                ExecutionEnvironment="gpu");

予測結果の可視化

この例のグラウンド トゥルース姿勢の可視化セクションでグラウンド トゥルース姿勢を可視化するために使用したのと同じように、投影された点群を使用して、6-DoF 姿勢予測を表示します。予測されたオブジェクトの姿勢を可視化するには、関数 rigidtform3d を使用して点群をイメージに投影し、投影された点群をサンプル イメージに重ねて表示します。

numPreds = size(boxes,1);  
imPose = imRGB;
detPosedPtClouds = cell(1,numPreds);
for detIndex = 1:numPreds
    detClass = string(labels(detIndex));

    % Define predicted rotation and translation.
    detTform = poses(detIndex);
    detScore = scores(detIndex);
    
    % Retrieve the 3-D object point cloud of the predicted object class.
    ptCloud = modelPointClouds(modelClassNames == detClass);
    
    % Transform the 3-D object point cloud using the predicted pose.
    ptCloudDet = pctransform(ptCloud, detTform);
    detPosedPtClouds{detIndex} = ptCloudDet;

    % Subsample the point cloud for cleaner visualization.
    ptCloudDet = pcdownsample(ptCloudDet,"random",0.05);

    % Project the transformed point cloud onto the image using the camera
    % intrinsic parameters and identity transform for camera pose and position.
    projectedPoints = world2img(ptCloudDet.Location,rigidtform3d,intrinsics);
    
    % Overlay the 2-D projected points over the image.
    imPose = insertMarker(imPose,[projectedPoints(:,1), projectedPoints(:,2)],...
        "circle",Size=1,Color=poseColors(modelClassNames==detClass));
end

関数 insertObjectAnnotation を使用して、予測された境界ボックス、クラス、および信頼度スコアの注釈をイメージに挿入します。

LabelScoreStr = compose("%s-%.2f",labels,scores); 
imPose = insertObjectAnnotation(imPose,"rectangle",boxes,LabelScoreStr); 

予測された境界ボックス、クラス、および信頼度スコアを重ね合わせたイメージを表示します。

figure
imshow(imPose)
title("Pose Mask R-CNN Prediction Results")

Pose Mask R-CNN ネットワークの予測をこのように可視化することで、ネットワークが 2 次元境界ボックスとクラス、およびビン内のパーツの 3 次元平行移動を正しく予測していることがわかります。3 次元回転はより困難なタスクであるため、予測には多少のノイズが伴います。結果を絞り込むため、推定済み姿勢の調整セクションで、深層学習の結果と従来の点群処理手法を組み合わせます。

推定済み姿勢の調整

深度イメージからの部分的な点群の取得

Pose Mask R-CNN ネットワークからの予測の精度を向上させるには、予測された姿勢と点群データの従来の幾何学的処理を組み合わせます。このセクションでは、深度イメージとカメラの内部パラメーターを使用して、シーンの点群表現を取得します。

後処理を使用して、遠くの壁や床の点など、ビンピッキング シーンの一部としては現実的に遠く離れ過ぎている点を削除します。カメラからの適切な最大距離、つまり最大深度を 0.5 に指定します。

maxDepth = 0.5;

PVC パーツが置かれているビンの表面を点群データから削除するには、シーン点群内のビンの表面に 3 次元平面を当てはめます。平面を当てはめる手順で使用する最大ビン距離とビンの向きを指定します。最大ビン距離は、カメラからビンまでの最大距離の推定値です。簡単にするために、ビンは水平方向にあると仮定します。

maxBinDistance = 0.0015;
binOrientation = [0 0 -1];

サポート関数 helperPostProcessScene を使用して、深度イメージの生のシーン点群を後処理し、検出された各オブジェクトの点群を返します。

[scenePointCloud,roiScenePtCloud] = helperPostProcessScene(imDepth,intrinsics,boxes,maxDepth, ...
    maxBinDistance,binOrientation);

シーンの点群をプロットします。

figure
pcshow(scenePointCloud,VerticalAxisDir="Down")
title("Scene Point Cloud from Depth Image")

深度イメージから抽出されたオブジェクト点群の 1 つをプロットします。

figure
pcshow(roiScenePtCloud{end}, VerticalAxisDir="Down")
title("Object Point Cloud from Depth Image")

点群のレジストレーションおよび姿勢推定の調整

姿勢推定の結果を改善するには、関数pcregistericpを使用して、反復最近接点 (ICP) アルゴリズムに基づいて点群のレジストレーションを実行します。レジストレーション中に、Pose Mask R-CNN モデルによって予測されたオブジェクトの姿勢を、深度イメージからのオブジェクトの部分的な点群に揃えます。使用される点群の点の数を減らして計算時間を短縮するには、関数pcdownsampleを使用し、ダウンサンプリング係数を 0.25 に設定します。

downsampleFactor = 0.25;
registeredPoses = cell(numPreds,1);
for detIndex = 1:numPreds
    
    % Downsample the object point cloud transformed by the predicted pose.
    ptCloudDet = pcdownsample(detPosedPtClouds{detIndex},"random",downsampleFactor);

    % Downsample point cloud obtained from the postprocessed scene depth image.
    ptCloudDepth =  pcdownsample(roiScenePtCloud{detIndex},"random",downsampleFactor);
    
    % Run the ICP point cloud registration algorithm with default
    % parameters.
    [tform,movingReg] = pcregistericp(ptCloudDet,ptCloudDepth);
    registeredPoses{detIndex} = tform;
end

簡単にするために、単一の検出オブジェクトのレジストレーションを可視化します。左のサブプロットで、Pose Mask R-CNN 予測から取得された点群をマゼンタでプロットし、シーン深度イメージの後処理から取得された点群を緑でプロットします。右のサブプロットで、レジストレーションされた点群をマゼンタでプロットし、深度イメージ点群を緑でプロットします。

figure
subplot(1,2,1)
pcshowpair(ptCloudDet,ptCloudDepth)
title("Predicted Pose and Depth Image Point Clouds")

subplot(1,2,2)
pcshowpair(movingReg,ptCloudDepth)
title("ICP Registration Result")

Pose Mask R-CNN 予測姿勢と点群レジストレーションの組み合わせ

この大幅に改善された後処理と調整の手順の後、Pose Mask R-CNN ネットワークによって予測された姿勢を可視化します。投影された点は、イメージ内に存在する機械部品とより一致するようになり、回転結果もより正確になりました。

refinedPoses = cell(1,numPreds);
imPoseRefined = imRGB;

for detIndex = 1:numPreds 

    detClass = string(labels(detIndex));

    % Define predicted rotation and translation.
    detTform = poses(detIndex);
    detScore = scores(detIndex);

    % Rotation and translation from registration of depth point clouds.
    icpTform = registeredPoses{detIndex};

    % Combine the two transforms to return the final pose.
    combinedTform = rigidtform3d(icpTform.A*detTform.A);
    refinedPoses{detIndex} = combinedTform;

    % Retrieve the 3-D object point cloud of the predicted object class.
    ptCloud = modelPointClouds(modelClassNames == detClass);

    % Transform the point cloud by the predicted pose.
    ptCloudDet = pctransform(ptCloud,combinedTform);

    % Subsample the point cloud for cleaner visualization.
    ptCloudDet = pcdownsample(ptCloudDet,"random",0.05);

    % Project the transformed point cloud onto the image using the camera
    % intrinsic parameters.
    projectedPoints = world2img(ptCloudDet.Location,rigidtform3d,intrinsics);
    
    % Display the projected point cloud points onto the image.
    imPoseRefined = insertMarker(imPoseRefined,[projectedPoints(:,1), projectedPoints(:,2)],...
        "circle",Size=1,Color=poseColors(modelClassNames == detClass));

end
refinedPoses = cat(1,refinedPoses{:});

関数insertObjectAnnotationを使用して、各オブジェクトの予測された境界ボックス、クラス、および信頼度スコアのラベルをイメージに挿入します。

imPoseRefined = insertObjectAnnotation(imPoseRefined,"rectangle",boxes,LabelScoreStr); 

予測された境界ボックス、クラス、および信頼度スコアを重ね合わせたイメージを表示します。

figure
imshow(imPoseRefined)
title("Pose Mask R-CNN + ICP")

6-DoF 姿勢予測の評価

予測された 6-DoF オブジェクトの姿勢の品質を定量化したり評価したりするには、面取り距離 [3] を使用して、予測された姿勢によって変換された点群と、グラウンド トゥルース姿勢によって変換された同じ点群の最近接点の間の距離を測定します。面取り距離が小さいということは、予測された姿勢とグラウンド トゥルース姿勢が密接に一致していることを示します。より短い面取り距離で正確に姿勢が揃うようにするには、すべてのオブジェクト点群をグラウンド トゥルース姿勢 (緑) と予測姿勢 (マゼンタ) として表示します。

まず、サポート関数 helperEvaluatePosePrediction を使用して、グラウンド トゥルース姿勢と予測姿勢のオブジェクト点群間の面取り距離を計算します。

[distPtCloud,predIndices,gtIndices] = helperEvaluatePosePrediction( ...
    modelPointClouds,modelClassNames,boxes,labels,refinedPoses,gtBoxes,gtClasses,gtPoses);

次に、グラウンド トゥルース姿勢と予測姿勢の点群ペアを可視化し、各オブジェクトの姿勢に対応する面取り距離値を表示します。

figure
for detIndex = 1:length(predIndices)
    detClass = string(labels(detIndex));
    gtIndex = gtIndices(detIndex);

    % Obtain the point cloud of the predicted object.
    ptCloudDet = modelPointClouds(modelClassNames == detClass);

    % Predicted 6-DoF pose with ICP refinement.
    detTform = refinedPoses(detIndex);

    % Apply the predicted pose transformation to the predicted object point
    % cloud.
    ptCloudTformDet = pctransform(ptCloudDet, detTform);

    if gtIndex == 0
        % The predicted bounding box does not match any
        % ground truth bounding box (false positive).
        ptCloudTformGT = pointCloud(single.empty(0,3));
    else
        % Obtain the point cloud of the ground truth object.
        ptCloudGT = modelPointClouds(modelClassNames == string(gtClasses(gtIndex)));

        % Apply the ground truth pose transformation.
        ptCloudTformGT = pctransform(ptCloudGT,gtPoses(gtIndex));
    end

    subplot(2,4,detIndex);
    pcshowpair(ptCloudTformDet,ptCloudTformGT);
    title(sprintf("d = %.4f",distPtCloud(detIndex)))
end

学習用データの準備

Pose Mask R-CNN 深層学習ネットワークを使用して、カスタム ビンピッキング データ セットで転移学習を実行します。データ セットには、Simulink® を使用して生成された 3 次元パイプ コネクタの RGB イメージと深度イメージが 100 個格納されています。データは、さまざまな視角やさまざまなライティング条件での、ビン内にランダムな向きで置かれた機械部品のイメージで構成されており、I、X、L、または T の形状をもつオブジェクトに対応する 4 つのオブジェクト クラスを含みます。データ セットには、各イメージ内のすべてのオブジェクトの境界ボックス、オブジェクト クラス、バイナリ マスク、6-DoF 姿勢情報、および 4 つのオブジェクト クラスごとの点群データも含まれます。

データ セットのダウンロード

サポート関数 helperDownloadPVCPartsDataset を使用してデータ セットをダウンロードします。この手順にはインターネット接続が必要です。

datasetUnzipFolder = helperDownloadPVCPartsDataset;

データの読み込みと分割

データを分割する前に、グローバルな乱数の状態を設定して、結果のより高い再現性を確保します。

rng("default");

データ セットとグラウンド トゥルース データの場所を指定します。

datasetDir = fullfile(datasetUnzipFolder,"pvcparts100");
gtLocation = fullfile(datasetDir,"GT");

ビンピッキング データ セットから読み取るサポート関数 helperSimAnnotMATReader を使用して、fileDatastore オブジェクトを作成します。

dsRandom = fileDatastore(gtLocation, ...
    ReadFcn=@(x)helperSimAnnotMATReader(x,datasetDir));

データ セットを学習セットと検証セットにランダムに分割します。イメージの総数が比較的少ないため、データの比較的大部分 (70%) を学習に割り当て、30% を検証に割り当てます。

randIndices = randperm(length(dsRandom.Files));
numTrainRandom = round(0.7*length(dsRandom.Files)); 
dsTrain = subset(dsRandom,randIndices(1:numTrainRandom));
dsVal = subset(dsRandom,randIndices(numTrainRandom+1:end));

データ ローダーを使用して、最初の検証サンプルの RGB イメージ、深度イメージ、オブジェクト マスク、オブジェクト クラス、境界ボックス、姿勢、およびカメラの内部パラメーターをクエリします。

data = preview(dsVal);
imRGB = data{1};
imDepth = data{2};
gtMasks = data{5};
gtClasses = data{4};
gtBoxes = data{3};
gtPoses = data{6};
intrinsics = data{7};

クエリされたオブジェクト クラスが正しい順序を維持していることを確認します。

trainClassNames = categories(gtClasses)
trainClassNames = 4×1 cell
    {'I_shape'}
    {'X_shape'}
    {'L_shape'}
    {'T_shape'}

Pose Mask R-CNN ネットワークの学習

Pose Mask R-CNN モデルには 2 段階で学習させます。

  1. 境界ボックス、クラス ラベル、およびセグメンテーション マスクの予測で構成されるインスタンス セグメンテーション タスクで、事前学習済みの Pose Mask R-CNN ネットワークに学習させます。この最初の学習手順では、学習の第 2 段階で使用する深層ニューラル ネットワークの重みを初期化します。

  2. 検出された各オブジェクトの 3 次元回転と平行移動の予測で構成される姿勢推定タスクを、前の手順で学習させた Pose Mask R-CNN ネットワークに学習させます。

可能であれば、1 つ以上の GPU で学習を行います。GPU を使用するには、Parallel Computing Toolbox™ ライセンスと CUDA® 対応の NVIDIA® GPU が必要です。詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。学習の 2 つの段階では、NVIDIA GeForce RTX 3090 GPU でそれぞれ約 20 分と約 45 分がかかります。

アンカー ボックスの推定

Pose Mask R-CNN ネットワークに学習させるには、以下の変数 doTraintrue に設定します。カスタム データ セットでネットワークに学習させるには、データに対して固有のアンカー ボックスの位置を推定します。100 個の学習イメージのサブセットから境界ボックスを推定します。関数estimateAnchorBoxesを使用してアンカー ボックスを推定します。

doTrain = false;

if doTrain
    numAnchors = 8;
    numImgSample = 100;
    numImgSample = min(numImgSample, length(dsTrain.Files));
    sampledBboxes = {};
    dsTmp = copy(dsTrain);
    for ii=1:numImgSample
        tmpData = read(dsTmp);
        randSelect = randi(size(tmpData{3},1));
        sampledBboxes{end+1} = tmpData{3}(randSelect,:);
    end
    blds = boxLabelDatastore(table(sampledBboxes'));
    [anchorBoxes,meanAnchorIoU] = estimateAnchorBoxes(blds,numAnchors);
end

Pose Mask R-CNN ネットワーク アーキテクチャの定義

posemaskrcnn オブジェクトを使用して、Pose Mask R-CNN 姿勢推定ネットワークを作成します。ResNet-50 を使用して作成された事前学習済みネットワークをベース ネットワークとして指定します。クラス名と推定アンカー ボックスを指定します。

if doTrain
    untrainedNetwork = posemaskrcnn("resnet50-pvc-parts",trainClassNames,anchorBoxes);
end

インスタンス セグメンテーション用の学習オプションの指定

関数trainingOptions (Deep Learning Toolbox)を使用して、インスタンス セグメンテーション学習ステージ用のネットワーク学習オプションを指定します。SGDM ソルバーを使用して、オブジェクト検出器に最大 5 エポック学習させます。名前と値の引数 ValidationData を検証データ dsVal として指定します。中間のネットワーク チェックポイントを保存する場所を指定します。

if doTrain
    outFolder = fullfile(tempdir,"output","train_posemaskrcnn_mask");
    mkdir(outFolder);
    ckptFolder = fullfile(outFolder, "checkpoints");
    mkdir(ckptFolder);
    disp(outFolder);
    
    optionsMask = trainingOptions("sgdm", ...
        InitialLearnRate=0.0001, ...  
        LearnRateSchedule="piecewise", ...
        LearnRateDropPeriod=1, ...
        LearnRateDropFactor=0.5, ...
        MaxEpochs=5, ...
        Plot="none", ...
        Momentum=0.9, ...
        MiniBatchSize=1, ... 
        ResetInputNormalization=false, ...
        ExecutionEnvironment="gpu", ...
        VerboseFrequency=5, ...
        ValidationData=dsVal, ...
        ValidationFrequency=20, ...
        Plots="training-progress",...
        CheckpointPath=ckptFolder,...
        CheckpointFrequency=2,...
        CheckpointFrequencyUnit="epoch");
end
/tmp/output/train_posemaskrcnn_mask

インスタンス セグメンテーションのための Pose Mask R-CNN の学習

関数trainPoseMaskRCNNを使用して、Pose Mask R-CNN ネットワークに学習させ、境界ボックス、オブジェクト クラス、およびインスタンス セグメンテーション マスクを予測します。この学習手順では、姿勢またはマスク ヘッドの損失は使用されません。学習済みのネットワークをローカル フォルダーに保存し、複数の反復にわたる学習損失の進行状況をプロットします。

if doTrain
    net = trainPoseMaskRCNN(...
        dsTrain,untrainedNetwork,"mask",optionsMask); 
    
    modelDateTime = string(datetime("now",Format="yyyy-MM-dd-HH-mm-ss"));
    save(fullfile(outFolder,"trainedPoseMaskRCNN-"+modelDateTime+".mat"),"net");
    disp(fullfile(outFolder,"trainedPoseMaskRCNN-"+modelDateTime+".mat"))

end
 
    Epoch    Iteration    TimeElapsed    LearnRate    TrainingLoss    TrainingRPNLoss    TrainingRMSE    TrainingClassLoss    TrainingMaskLoss    TrainingRLoss    TrainingTLoss    ValidationLoss    ValidationRPNLoss    ValidationRMSE    ValidationClassLoss    ValidationMaskLoss    ValidationRLoss    ValidationTLoss
    _____    _________    ___________    _________    ____________    _______________    ____________    _________________    ________________    _____________    _____________    ______________    _________________    ______________    ___________________    __________________    _______________    _______________
      1          1         00:00:40       0.0001         3.6575           2.0999           0.064771           0.80412             0.68873               0                0              3.656              2.1041             0.064585             0.8018                0.68549                 0                  0       
      1         20         00:05:26       0.0001         2.8532            2.101           0.033871           0.1678              0.55049               0                0              2.8663             2.0856             0.028553             0.20525               0.54689                 0                  0             1         40         00:08:11       0.0001         2.6816           2.0566           0.022791           0.18648             0.41571               0                0              2.6817             2.0625             0.023789             0.17854               0.41691                 0                  0       
      1         60         00:10:52       0.0001         2.5642           2.0606           0.022521           0.1352              0.34588               0                0              2.5318             2.0249             0.022349             0.14351               0.34107                 0                  0       
      2         80         00:13:33        5e-05         2.424            2.0027           0.017956           0.11243             0.29084               0                0              2.4487             2.0111             0.02126              0.12291               0.29346                 0                  0       
      2         100        00:16:04        5e-05         2.3739           1.9871           0.018299           0.10889             0.25964               0                0              2.3918              1.989             0.020345             0.11354               0.26897                 0                  0             2         120        00:18:27        5e-05         2.3243           1.9641           0.022171           0.10137             0.23665               0                0              2.3622              1.987             0.019728             0.10639               0.24901                 0                  0       
      2         140        00:20:30        5e-05         2.3016           1.9652           0.017714          0.089053             0.22962               0                0              2.3231             1.9708             0.019083             0.10094               0.23229                 0                  0             3         160        00:22:34       2.5e-05        2.3177           1.9933           0.019636          0.090793             0.21396               0                0              2.297               1.962             0.01866             0.095371               0.22095                 0                  0       
      3         180        00:24:32       2.5e-05        2.2961           1.9604           0.017988           0.10632             0.21138               0                0              2.2766             1.9511             0.018349            0.093786               0.21333                 0                  0       
      3         200        00:26:49       2.5e-05        2.2735           1.9666           0.019381          0.079479             0.20799               0                0              2.266              1.9501             0.017941            0.091677               0.20628                 0                  0       
      4         220        00:29:09      1.25e-05        2.1984           1.9292           0.014187          0.066644             0.18836               0                0              2.2479             1.9421             0.017586            0.088471               0.19976                 0                  0       
      4         240        00:31:12      1.25e-05        2.1725           1.9005           0.013352           0.07207             0.18658               0                0              2.233              1.9326             0.017474            0.086695               0.19629                 0                  0       
      4         260        00:33:40      1.25e-05        2.2302           1.9573           0.017712          0.075043             0.18019               0                0              2.2362             1.9395             0.01735             0.086148                0.1932                 0                  0             4         280        00:35:41      1.25e-05        2.1736           1.9141           0.013931          0.064661              0.1809               0                0              2.2202              1.928             0.017174            0.084905               0.19013                 0                  0       
      5         300        00:37:44      6.25e-06        2.2396           1.9665           0.018019          0.072635             0.18246               0                0              2.227               1.938             0.016975            0.083989               0.18807                 0                  0             5         320        00:39:41      6.25e-06        2.1851           1.9053           0.016149          0.081836             0.18185               0                0              2.2075             1.9205             0.016835            0.083628               0.18653                 0                  0       
      5         340        00:41:56      6.25e-06        2.2176           1.9552           0.017416           0.06266             0.18237               0                0              2.2122             1.9274             0.01673             0.083202               0.18486                 0                  0       

      5         350        00:42:49      6.25e-06        2.2211           1.9671           0.013468          0.064305             0.17621               0                0              2.2171             1.9334             0.016688            0.082739               0.18426                 0                  0       
/tmp/output/train_posemaskrcnn_pose-and-mask/trainedPoseMaskRCNN-2024-01-13-17-12-55.mat

姿勢予測用の学習オプションの指定

関数trainingOptions (Deep Learning Toolbox)を使用して、姿勢予測の学習ステージ用のネットワーク学習オプションを指定します。SGDM ソルバーを使用して、オブジェクト検出器に最大 5 エポック学習させます。名前と値の引数 ValidationData を検証データ dsVal として指定します。中間のネットワーク チェックポイントを保存する場所を指定します。

if doTrain
    outFolder = fullfile(tempdir,"output","train_posemaskrcnn_pose-and-mask");
    mkdir(outFolder);
    ckptFolder = fullfile(outFolder,"checkpoints");
    mkdir(ckptFolder);
    disp(outFolder);

    optionsPose = trainingOptions("sgdm", ...
        InitialLearnRate=0.0001, ...  
        LearnRateSchedule="piecewise", ...
        LearnRateDropPeriod=1, ...
        LearnRateDropFactor=0.5, ...
        MaxEpochs=5, ...
        Plot="none", ...
        Momentum=0.9, ...
        MiniBatchSize=1, ... 
        ResetInputNormalization=false, ...
        ExecutionEnvironment="gpu", ...
        VerboseFrequency=5, ...
        CheckpointPath=ckptFolder,...
        CheckpointFrequency=5,...
        CheckpointFrequencyUnit="epoch",...
        ValidationData=dsVal, ...
        ValidationFrequency=20, ...
        Plots="training-progress");
end
/tmp/output/train_posemaskrcnn_pose-and-mask

姿勢推定のための Pose Mask R-CNN の学習

検出されたオブジェクトごとに 6-DoF 姿勢を予測するには、関数trainPoseMaskRCNNを使用して、インスタンス セグメンテーションを学習させた Pose Mask R-CNN ネットワーク net に、姿勢損失とマスク損失の両方を学習させます。学習済みのネットワークをローカル フォルダーに保存し、複数の反復にわたる回転と平行移動の学習損失の進行状況をプロットします。

if doTrain
    trainedNet = trainPoseMaskRCNN(...
        dsTrain,net,"pose-and-mask",optionsPose);  
    
    modelDateTime = string(datetime("now",Format="yyyy-MM-dd-HH-mm-ss"));
    save(fullfile(outFolder,"trainedPoseMaskRCNN-"+modelDateTime+".mat"),"trainedNet");
    disp(fullfile(outFolder,"trainedPoseMaskRCNN-"+modelDateTime+".mat"))
    
end
 
    Epoch    Iteration    TimeElapsed    LearnRate    TrainingLoss    TrainingRPNLoss    TrainingRMSE    TrainingClassLoss    TrainingMaskLoss    TrainingRLoss    TrainingTLoss    ValidationLoss    ValidationRPNLoss    ValidationRMSE    ValidationClassLoss    ValidationMaskLoss    ValidationRLoss    ValidationTLoss
    _____    _________    ___________    _________    ____________    _______________    ____________    _________________    ________________    _____________    _____________    ______________    _________________    ______________    ___________________    __________________    _______________    _______________
      1          1         00:00:06       0.0001         4.425            1.9067           0.012332           0.07459             0.18954            0.21684         0.0073509          4.5597             1.9297             0.016825             0.08355               0.18645              0.22715           0.007171    
      1          5         00:01:30       0.0001         3.3443           1.8693           0.013716          0.080874             0.18584            0.11243         0.0070213                                                                                                                                                    1         10         00:01:53       0.0001         4.9746            1.974           0.016091           0.07546             0.18325            0.2653          0.0072887                                                                                                                                              
      1         15         00:02:17       0.0001         3.9358           1.8795           0.016757          0.063235              0.1757            0.17371         0.0063496                                                                                                                                              
      1         20         00:02:40       0.0001         3.4181           2.0059           0.013514          0.092078             0.18308            0.10455         0.0077985          4.1825             1.9166             0.016276            0.077023               0.17267              0.19286           0.0071258   
      1         25         00:04:09       0.0001           4              1.8551           0.01647            0.10322             0.16983            0.17885         0.0066904                                                                                                                                                    1         30         00:04:52       0.0001         2.7365           1.8988           0.016118           0.07185             0.15666           0.052364         0.006943                                                                                                                                               
      1         35         00:05:33       0.0001         4.211            1.9617           0.016341          0.063856             0.16036            0.19293         0.0079464                                                                                                                                                    1         40         00:06:03       0.0001         3.876            1.9508           0.015947          0.071591             0.15336            0.16067         0.0077663          4.0866             1.8918             0.015256             0.07096               0.15351              0.18839           0.0071143   
      1         45         00:07:10       0.0001         4.0012           1.8485           0.018498          0.061303             0.14996            0.18584         0.0064536                                                                                                                                                    1         50         00:07:31       0.0001         4.2271           1.8272           0.013666          0.087144             0.15059            0.20833         0.0065178                                                                                                                                              
      1         55         00:07:54       0.0001         4.9432           1.8978           0.013188          0.075847             0.13748            0.27551         0.0063785                                                                                                                                              
      1         60         00:08:18       0.0001         4.264            1.8711           0.012996          0.051528             0.14363            0.21028         0.0081964          3.979              1.8831             0.014396            0.063456               0.13634              0.18119           0.0069832   
      1         65         00:09:19       0.0001         3.5047           1.8438           0.015684           0.05031             0.13383            0.13927         0.0068367                                                                                                                                              
      1         70         00:09:43       0.0001         4.3177           1.8502           0.016837          0.084931             0.13774            0.21456         0.0082395                                                                                                                                              
      2         75         00:10:10        5e-05         3.6337           1.8203           0.011019          0.063082             0.12334             0.155          0.0066063                                                                                                                                              
      2         80         00:10:35        5e-05         4.0287           1.9151           0.013735          0.062149             0.12865            0.18343         0.0074681          3.9288             1.8685             0.013519            0.060119               0.12383              0.17935           0.0069387   
      2         85         00:11:33        5e-05         4.3161            1.812           0.012129          0.061233             0.12055            0.22469         0.0063328                                                                                                                                              
      2         90         00:11:56        5e-05         3.1033            1.917           0.011359          0.050071             0.12942           0.092577         0.0069659                                                                                                                                              
      2         95         00:12:21        5e-05         3.7234           1.8451           0.013112          0.057168             0.12521            0.16207         0.0062087                                                                                                                                              
      2         100        00:12:45        5e-05         3.1449           1.9157           0.013601          0.065032             0.11772           0.096688         0.006601           3.9312             1.8625             0.01309             0.058631               0.11685              0.18111           0.006914    
      2         105        00:13:48        5e-05         4.0344           1.8717           0.012813           0.05403             0.11965            0.19016         0.0074705                                                                                                                                              
      2         110        00:14:14        5e-05         3.8351           1.8718           0.013196          0.055865              0.1164            0.16986         0.0079226                                                                                                                                              
      2         115        00:14:38        5e-05         3.9524            1.788           0.014964          0.065013             0.11283            0.19099         0.0061608                                                                                                                                              
      2         120        00:15:04        5e-05         4.1302            1.835          0.0096374          0.058363             0.11195            0.2052          0.0063144          3.9014             1.8535             0.012624            0.055436               0.11169              0.17996           0.0068592   
      2         125        00:16:07        5e-05         4.8263           1.7608           0.010414          0.045687             0.10477            0.28372         0.0067439                                                                                                                                              
      2         130        00:16:32        5e-05         4.0135           1.8345           0.011485          0.043757             0.11138            0.19359         0.0076483                                                                                                                                              
      2         135        00:17:02        5e-05         3.2582           1.8583           0.014081          0.043283             0.10866            0.11662         0.0067626                                                                                                                                              
      2         140        00:17:32        5e-05         4.2529           1.8885           0.016219          0.084695             0.11235            0.20741         0.0077019          3.9015             1.8483             0.012281            0.056084               0.10686              0.18095           0.0068519   
      3         145        00:18:56       2.5e-05        3.7113           1.8038           0.010348          0.054806             0.10584            0.16745         0.0061971                                                                                                                                              
      3         150        00:19:31       2.5e-05        3.819            1.8661           0.012479          0.051198             0.10875            0.17103         0.0070119                                                                                                                                              
      3         155        00:20:24       2.5e-05        4.2989           1.8207           0.011249          0.052029             0.10203            0.22564         0.0056505                                                                                                                                              
      3         160        00:20:52       2.5e-05        3.0749           1.9308           0.010262          0.033757             0.11216           0.091426         0.0073638          3.9042             1.8464             0.012248            0.054448               0.10394              0.1819            0.0068128   
      3         165        00:22:09       2.5e-05        3.6398           1.7523           0.011382          0.049113             0.10725            0.16621         0.0057626                                                                                                                                              
      3         170        00:22:36       2.5e-05        3.1996            1.87            0.010457          0.045865             0.10051            0.11107         0.0062097                                                                                                                                              
      3         175        00:23:05       2.5e-05        3.9704           1.8259           0.011135          0.047548             0.10321            0.19149         0.0067736                                                                                                                                                    3         180        00:23:32       2.5e-05        3.802            1.9253           0.012872          0.053294             0.10632            0.16245         0.0079684           3.89              1.8396             0.012118            0.054609               0.10171              0.18143           0.0067744   
      3         185        00:24:47       2.5e-05        3.8619            1.856           0.013456          0.058048             0.099451           0.17727         0.0062281                                                                                                                                              
      3         190        00:25:13       2.5e-05        4.1406           1.7998          0.0088859          0.064439             0.10199            0.21026         0.0062842                                                                                                                                              
      3         195        00:25:42       2.5e-05        4.7698           1.8287          0.0097723          0.042307             0.092342           0.27329         0.0063759                                                                                                                                                    3         200        00:26:08       2.5e-05        4.0045           1.7964           0.010865          0.041261             0.10155            0.19907         0.0063662          3.8773              1.827             0.011879            0.053423               0.099519             0.18179           0.0067648   
      3         205        00:27:23       2.5e-05        3.189             1.842           0.012717          0.035845             0.10007            0.11339         0.0064482                                                                                                                                              
      3         210        00:27:54       2.5e-05        4.1905           1.8187           0.015489          0.080467             0.10085            0.21014         0.007362                                                                                                                                               
      4         215        00:28:22      1.25e-05        3.7177           1.7929           0.011466          0.058451             0.095559           0.16988         0.0060606                                                                                                                                                    4         220        00:28:52      1.25e-05        3.9055           1.9303           0.012267          0.052593             0.10119            0.1732          0.0077092          3.8889             1.8304             0.011744            0.052941               0.097746             0.18292           0.0066802   
      4         225        00:30:00      1.25e-05        4.2065           1.7322           0.011028          0.049974             0.095855           0.22607         0.0056673                                                                                                                                                    4         230        00:30:26      1.25e-05        2.9952           1.8656          0.0097368          0.043235             0.10368           0.089534         0.0077586                                                                                                                                              
      4         235        00:30:51      1.25e-05        3.5719           1.7539           0.010217          0.050412             0.10007            0.15977         0.0059596                                                                                                                                              
      4         240        00:31:16      1.25e-05        3.2121           1.8378          0.0099281          0.051963             0.094783           0.11535         0.0064121          3.9073             1.8477             0.011723            0.052852               0.096757             0.18315           0.0066667   
      4         245        00:32:24      1.25e-05        3.9596           1.8314           0.010207          0.043314             0.098772           0.19086         0.0067334                                                                                                                                              
      4         250        00:32:50      1.25e-05        3.8413           1.8361           0.012347          0.050678             0.098378           0.17672         0.0076649                                                                                                                                              
      4         255        00:33:14      1.25e-05        3.796            1.8042           0.014324          0.061713             0.096777           0.17557         0.0063271                                                                                                                                              
      4         260        00:33:33      1.25e-05        4.0321           1.8212          0.0076936          0.060508             0.095771           0.19901         0.0056828          3.8827              1.83              0.011685            0.052384               0.096111             0.18256           0.0066912   
      4         265        00:34:21      1.25e-05        4.6725           1.8429           0.010168          0.040001             0.089355           0.26294         0.0060712                                                                                                                                                    4         270        00:34:41      1.25e-05        3.9771           1.8056          0.0099264           0.03906             0.097494           0.1963          0.0062003                                                                                                                                              
      4         275        00:35:01      1.25e-05        3.1871           1.8461           0.011912          0.036101             0.096022           0.11311         0.006594                                                                                                                                               
      4         280        00:35:21      1.25e-05        4.1018           1.8518           0.014761          0.076527             0.096452           0.19914         0.007096           3.888               1.828             0.011568            0.052635               0.095317             0.18335           0.0067016   
      5         285        00:36:27      6.25e-06        3.7842            1.781           0.011226          0.067673             0.094224           0.17673         0.0062813                                                                                                                                                    5         290        00:36:46      6.25e-06        3.8726           1.9327           0.011989          0.049069             0.097751           0.1703          0.0078037                                                                                                                                              
      5         295        00:37:06      6.25e-06        4.2542           1.7398           0.01168           0.045045             0.094381           0.23059         0.0057382                                                                                                                                                    5         300        00:37:24      6.25e-06        2.904            1.8251           0.009817          0.037831             0.10111           0.085492         0.0075196          3.8797             1.8325             0.011495            0.052319               0.094561             0.18224           0.006641    
      5         305        00:38:12      6.25e-06        3.5168           1.7686          0.0099903          0.044795             0.097054           0.1539          0.0057348                                                                                                                                              
      5         310        00:38:31      6.25e-06        3.1919           1.8286           0.010338          0.051687             0.093272           0.11444         0.006366                                                                                                                                               
      5         315        00:38:50      6.25e-06        3.9709            1.821           0.009547          0.045288             0.09482            0.19314         0.0068896                                                                                                                                              
      5         320        00:39:14      6.25e-06        3.7801           1.7907           0.012333          0.052526             0.096638           0.17514         0.0076521          3.8794             1.8182             0.011481            0.052753               0.094354             0.18359           0.0066794   
      5         325        00:40:12      6.25e-06        3.8643           1.8934           0.015141          0.064857             0.094833           0.1734          0.0062066                                                                                                                                                    5         330        00:40:37      6.25e-06        3.9124           1.7465          0.0081929          0.064391             0.094037           0.19389         0.0060411                                                                                                                                              
      5         335        00:41:02      6.25e-06        4.597            1.7798          0.0099351          0.050266             0.086528           0.26107         0.0059784                                                                                                                                                    5         340        00:41:29      6.25e-06        3.8049           1.7888           0.010299          0.034911             0.095508           0.1814          0.0061398          3.8842             1.8352             0.011452            0.052434               0.093791             0.18248           0.0066486   
      5         345        00:42:36      6.25e-06        3.0303           1.7334           0.012292          0.038415             0.094794           0.10832         0.0068153                                                                                                                                              

      5         350        00:43:04      6.25e-06        4.0497           1.8327           0.014771           0.09441             0.094598           0.19413         0.0071972          3.8757             1.8281             0.011435            0.052273               0.093563             0.18237           0.0066686   
/tmp/output/train_posemaskrcnn_pose-and-mask/trainedPoseMaskRCNN-2024-01-13-18-17-09.mat

サポート関数

helperSimAnnotMATReader

function out = helperSimAnnotMATReader(filename,datasetRoot)
% Read annotations for simulated bin picking dataset
% Expected folder structure under `datasetRoot`:
%       depth/      (depth images folder)
%       GT/         (ground truth MAT files)
%       image/      (color images)

    data = load(filename);
    groundTruthMaT = data.groundTruthMaT;
    clear data;
    
    % Read RGB image.
    tmpPath = strsplit(groundTruthMaT.RGBImagePath, '\');
    basePath = {tmpPath{4:end}};
    imRGBPath = fullfile(datasetRoot, basePath{:});
    im = imread(imRGBPath);
    im = rgb2gray(im);
    if(size(im,3)==1)
        im = repmat(im, [1 1 3]);
    end
    
    % Read depth image.
    aa = strsplit(groundTruthMaT.DepthImagePath, '\');
    bb = {aa{4:end}};
    imDepthPath = fullfile(datasetRoot,bb{:}); % handle windows paths
    imD = load(imDepthPath); imD = imD.depth;
    
    % For "undefined" value in instance labels, assign to the first class.
    undefinedSelect = isundefined(groundTruthMaT.instLabels);
    classNames = categories(groundTruthMaT.instLabels);
    groundTruthMaT.instLabels(undefinedSelect) = classNames{1};
    if isrow(groundTruthMaT.instLabels)
        groundTruthMaT.instLabels = groundTruthMaT.instLabels';
    end
    
    % Wrap the camera parameter matrix into the cameraIntrinsics object.
    K = groundTruthMaT.IntrinsicsMatrix;
    intrinsics = cameraIntrinsics([K(1,1) K(2,2)], [K(1,3)  K(2,3)], [size(im,1) size(im, 2)]);
    
    % Process rotation matrix annotations.
    rotationCell = num2cell(groundTruthMaT.rotationMatrix,[1 2]);
    rotationCell = squeeze(rotationCell);
    
    % Process translation annotations.
    translation = squeeze(groundTruthMaT.translation)';
    translationCell = num2cell(translation, 2);
    
    % Process poses into rigidtform3d vector - transpose R to obtain the
    % correct pose.
    poseCell = cellfun( @(R,t)(rigidtform3d(R',t)), rotationCell, translationCell, ...
        UniformOutput=false);
    pose = vertcat(poseCell{:});
    
    % Remove heavily occluded objects.
    if length(groundTruthMaT.occPercentage) == length(groundTruthMaT.instLabels)
        visibility = groundTruthMaT.occPercentage;
        visibleInstSelector = visibility > 0.5;
    else
        visibleInstSelector = true([length(groundTruthMaT.instLabels),1]);
    end
    
    out{1} = im;
    out{2} = imD;                                                    % HxWx1 double array depth-map
    out{3} = groundTruthMaT.instBBoxes(visibleInstSelector,:);       % Nx4 double bounding boxes
    out{4} = groundTruthMaT.instLabels(visibleInstSelector);         % Nx1 categorical object labels
    out{5} = logical(groundTruthMaT.instMasks(:,:,visibleInstSelector));      % HxWxN logical mask arrays
    out{6} = pose(visibleInstSelector);                              % Nx1 rigidtform3d vector of object poses
    out{7} = intrinsics;                                             % cameraIntrinsics object

end

helperPostProcessScene

function [scenePtCloud,roiScenePtCloud] = helperPostProcessScene(imDepth,intrinsics,boxes,maxDepth,maxBinDistance,binOrientation)

    % Convert the depth image into an organized point cloud using camera
    % intrinsics.
    scenePtCloud = pcfromdepth(imDepth,1.0,intrinsics);
    
    % Remove outliers, or points that are too far away to be in the bin.
    selectionROI = [...
            scenePtCloud.XLimits(1) scenePtCloud.XLimits(2) ...
            scenePtCloud.YLimits(1) scenePtCloud.YLimits(2) ...
            scenePtCloud.ZLimits(1) maxDepth];
    selectedIndices = findPointsInROI(scenePtCloud, selectionROI);
    cleanScenePtCloud = select(scenePtCloud,selectedIndices);
    
    % Fit a plane to the bin surface.
    [~,~,outlierIndices] = pcfitplane(...
        cleanScenePtCloud,maxBinDistance,binOrientation);
    
    % Re-map indices back to the original scene point cloud. Use this
    % when cropping out object detections from the scene point cloud.
    origPtCloudSelection = selectedIndices(outlierIndices);
    
    % Crop predicted ROIs from the scene point cloud.
    numPreds = size(boxes,1);
    roiScenePtCloud = cell(1,numPreds);
    for detIndex=1:numPreds
        box2D = boxes(detIndex,:);
        
        % Get linear indices into the organized point cloud corresponding to the 
        % predicted 2-D bounding box of an object.
        boxIndices = (box2D(2):box2D(2)+box2D(4))' + (size(scenePtCloud.Location,1)*(box2D(1)-1:box2D(1)+box2D(3)-1));
        boxIndices = uint32(boxIndices(:));
        
        % Remove points that are outliers from earlier pre-processing steps
        % (either belonging to the bin surface or too far away).
        keptIndices = intersect(origPtCloudSelection,boxIndices);
        roiScenePtCloud{detIndex} = select(scenePtCloud,keptIndices);
    end

end

helperEvaluatePosePrediction

function [distADDS,predIndices,gtIndices] = helperEvaluatePosePrediction(...
    modelPointClouds, modelClassNames,boxes,labels,pose, gBox,gLabel,gPose)
% Compare predicted and ground truth pose for a single image containing multiple 
% object instances using the one-sided Chamfer distance.

    function pointCloudADDS = pointCloudChamferDistance(ptCloudGT,ptCloudDet,numSubsampledPoints)
    % Return the one-sided Chamfer distance between two point clouds, which
    % computes the closest point in point cloud B for each point in point cloud A,
    % and averages over these minimum distances.

        % Sub-sample the point clouds                                                                                                                               
        if nargin == 2
            numSubsampledPoints = 1000;
        end
        
        rng("default"); % Ensure reproducibility in the point-cloud sub-sampling step.
        
        if numSubsampledPoints < ptCloudDet.Count
            subSampleFactor = numSubsampledPoints / ptCloudDet.Count;
            ptCloudDet = pcdownsample(ptCloudDet,"random",subSampleFactor);
            subSampleFactor = numSubsampledPoints / ptCloudGT.Count;   
            ptCloudGT = pcdownsample(ptCloudGT,"random",subSampleFactor);
        end
        
        % For each point in GT ptCloud, find the distance to closest point in predicted ptCloud.
        distPtCloud = pdist2(ptCloudGT.Location, ptCloudDet.Location,...
                "euclidean", "smallest",1);

        % Average over all points in GT ptCloud.
        pointCloudADDS = mean(distPtCloud); 
        
    end

    maxADDSThreshold = 0.1;

    % Associate predicted bboxes with ground truth annotations based on
    % bounding box overlaps as an initial step.
    minOverlap = 0.1;
    overlapRatio = bboxOverlapRatio(boxes,gBox);
    [predMatchScores, predGTIndices]  = max(overlapRatio, [], 2); % (numPreds x 1)
    [gtMatchScores, ~]  = max(overlapRatio, [], 1); % (1 x numGT)
    matchedPreds = predMatchScores > minOverlap;
    matchedGTs = gtMatchScores > minOverlap;

    numPreds = size(boxes,1);

    distADDS = cell(numPreds,1);
    predIndices = cell(numPreds,1);
    gtIndices = cell(numPreds,1);
    
    for detIndex=1:numPreds
        detClass = string(labels(detIndex));

        % Account for predictions unmatched with GT (false positives).
        if ~matchedPreds(detIndex)
            % If the predicted bounding box does not overlap any
            % ground truth bounding box, then maximum penalty is applied 
            % and the point cloud matching steps are skipped.
            distADDS{detIndex} = maxADDSThreshold;
            predIndices{detIndex} = detIndex;
            gtIndices{detIndex} = 0;
        else
            % Match GT labels to Predicted objects by their bounding 
            % box overlap ratio (box Intersection-over-Union).
            gtIndex = predGTIndices(detIndex);
            detClassname = string(detClass);
            gClassname = string(gLabel(gtIndex));

            if detClassname ~= gClassname
                % If predicted object category is incorrec, set
                % to maximum allowed distance (highly penalized).
                distADDS{detIndex} = maxADDSThreshold;
            else
                % Predicted rotation and translation.                     
                detTform = pose(detIndex);
                
                % Ground truth pose.
                gTform = gPose(gtIndex);
        
                % Get the point cloud of the object.
                ptCloud = modelPointClouds(modelClassNames == string(gClassname));

                % Apply the ground truth pose transformation.
                ptCloudTformGT = pctransform(ptCloud, gTform);
        
                % Apply the predicted pose transformation
                ptCloudDet = pctransform(ptCloud, detTform);
        
                pointCloudADDSObj = pointCloudChamferDistance(...
                    ptCloudTformGT,ptCloudDet);
        
                distADDS{detIndex} = pointCloudADDSObj;
            end
            predIndices{detIndex} = detIndex;
            gtIndices{detIndex} = gtIndex;
        end                                      
    end
    
    distADDS = cat(1, distADDS{:});

    % Account for unmatched GT objects (false negatives).
    numUnmatchedGT = numel(matchedGTs) - nnz(matchedGTs);
    if numUnmatchedGT > 0
        % Set to max distance for unmatched GTs.
        falseNegativesADDS = maxADDSThreshold * ones(numUnmatchedGT,1); 
        fnPred = zeros(numUnmatchedGT,1);
        fnGT = find(~matchedGTs);
        distADDS = cat(1, distADDS, falseNegativesADDS);
        predIndices = cat(1, predIndices, fnPred);
        gtIndices = cat(1, gtIndices, fnGT);
    end

    predIndices = cat(1, predIndices{:});
    gtIndices = cat(1, gtIndices{:});

end

helperDownloadPVCPartsDataset

function datasetUnzipFolder = helperDownloadPVCPartsDataset()
    datasetURL = "https://ssd.mathworks.com/supportfiles/vision/data/pvcparts100Dataset.zip";
    datasetUnzipFolder = fullfile(tempdir,"dataset");
    datasetZip = fullfile(datasetUnzipFolder,"pvcparts100Dataset.zip");
    if ~exist(datasetZip,"file")
        mkdir(datasetUnzipFolder);
        disp("Downloading PVC Parts dataset (200 MB)...");
        websave(datasetZip, datasetURL);
    end
    unzip(datasetZip, datasetUnzipFolder)
end

参考文献

[1] Yu Xiang, Tanner Schmidt, Venkatraman Narayanan, and Dieter Fox. "PoseCNN: A Convolutional Neural Network for 6D Object Pose Estimation in Cluttered Scenes." In Robotics: Science and Systems (RSS), 2018.

[2] Jiang, Xiaoke, Donghai Li, Hao Chen, Ye Zheng, Rui Zhao, and Liwei Wu. "Uni6d: A unified CNN framework without projection breakdown for 6d pose estimation." In Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition, 2022.

[3] Gunilla Borgefors. "Hierarchical Chamfer matching: A parametric edge matching algorithm." In IEEE Transactions on Pattern Analysis and Machine Intelligence 10, no. 6 (1988): 849-865.

参考

| | | | | (Deep Learning Toolbox)

関連するトピック