162 lines
6.4 KiB
Plaintext
162 lines
6.4 KiB
Plaintext
/*
|
|
* SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include "common/bboxUtils.h"
|
|
#include "common/kernels/kernel.h"
|
|
|
|
using namespace nvinfer1;
|
|
namespace nvinfer1
|
|
{
|
|
namespace plugin
|
|
{
|
|
// PROPOSALS INFERENCE
|
|
pluginStatus_t proposalsInference(cudaStream_t stream, const int N, const int A, const int H, const int W,
|
|
const int featureStride, const int preNmsTop, const int nmsMaxOut, const float iouThreshold, const float minBoxSize,
|
|
const float* imInfo, const float* anchors, const DataType t_scores, const DLayout_t l_scores, const void* scores,
|
|
const DataType t_deltas, const DLayout_t l_deltas, const void* deltas, void* workspace, const DataType t_rois,
|
|
void* rois)
|
|
{
|
|
/*
|
|
* N: batch size
|
|
* A: number of anchor boxes per grid cell on feature map
|
|
* H: height of feature map
|
|
* W: width of feature map
|
|
*/
|
|
if (imInfo == NULL || anchors == NULL || scores == NULL || deltas == NULL || workspace == NULL || rois == NULL)
|
|
{
|
|
return STATUS_BAD_PARAM;
|
|
}
|
|
|
|
DEBUG_PRINTF("&&&& IM INFO %u\n", hash(imInfo, N * 3 * sizeof(float)));
|
|
// anchors: anchor boxes
|
|
/*
|
|
* The following line of code looks somewhat incorrect because it sounds like we always have 9 fixed anchor boxes.
|
|
* The "corrected" implementation should be
|
|
* DEBUG_PRINTF("&&&& ANCHORS %u\n", A * 4 * sizeof(float)));
|
|
*/
|
|
DEBUG_PRINTF("&&&& ANCHORS %u\n", hash(anchors, 9 * 4 * sizeof(float)));
|
|
// scores: objectness of each predicted bounding boxes
|
|
// 2: softmax, instead of sigmoid, was used for binary objectness classifcation in Faster R-CNN
|
|
DEBUG_PRINTF("&&&& SCORES %u\n", hash(scores, N * A * 2 * H * W * sizeof(float)));
|
|
// deltas: predicted bounding box offsets
|
|
DEBUG_PRINTF("&&&& DELTAS %u\n", hash(deltas, N * A * 4 * H * W * sizeof(float)));
|
|
|
|
size_t nmsWorkspaceSize = proposalsForwardNMSWorkspaceSize(N, A, H, W, nmsMaxOut);
|
|
|
|
void* nmsWorkspace = workspace;
|
|
|
|
size_t proposalsSize = proposalsForwardBboxWorkspaceSize(N, A, H, W);
|
|
const DataType t_proposals = nvinfer1::DataType::kFLOAT;
|
|
const DLayout_t l_proposals = NC4HW;
|
|
void* proposals = nextWorkspacePtr((int8_t*) nmsWorkspace, nmsWorkspaceSize);
|
|
|
|
const DataType t_fgScores = t_scores;
|
|
const DLayout_t l_fgScores = NCHW;
|
|
void* fgScores = nextWorkspacePtr((int8_t*) proposals, proposalsSize);
|
|
|
|
pluginStatus_t status;
|
|
|
|
/*
|
|
* Only the second probability value of the objectness (probability of being a object) from the scores will be extracted.
|
|
* Because the first probability (probability of not being a object) value is redundant.
|
|
*/
|
|
status = extractFgScores(stream,
|
|
N, A, H, W,
|
|
t_scores, l_scores, scores,
|
|
t_fgScores, l_fgScores, fgScores);
|
|
ASSERT_FAILURE(status == STATUS_SUCCESS);
|
|
|
|
DEBUG_PRINTF("&&&& FG SCORES %u\n", hash((void*) fgScores, N * A * H * W * sizeof(float)));
|
|
DEBUG_PRINTF("&&&& DELTAS %u\n", hash((void*) proposals, N * A * H * W * 4 * sizeof(float)));
|
|
|
|
/*
|
|
* Decode predicted bounding boxes.
|
|
* Decoded predicted bounding boxes were at the raw input image scale.
|
|
*/
|
|
status = bboxDeltas2Proposals(stream,
|
|
N, A, H, W,
|
|
featureStride,
|
|
minBoxSize,
|
|
imInfo,
|
|
anchors,
|
|
t_deltas, l_deltas, deltas,
|
|
t_proposals, l_proposals, proposals,
|
|
t_fgScores, l_fgScores, fgScores);
|
|
ASSERT_FAILURE(status == STATUS_SUCCESS);
|
|
|
|
DEBUG_PRINTF("&&&& PROPOSALS %u\n", hash((void*) proposals, N * A * H * W * 4 * sizeof(float)));
|
|
DEBUG_PRINTF("&&&& FG SCORES %u\n", hash((void*) fgScores, N * A * H * W * sizeof(float)));
|
|
|
|
/*
|
|
* Non maximum suppression using objectness scores to get the most representative bounding boxes (ROIs).
|
|
* The rois were at the feature map scale.
|
|
*/
|
|
status = nms(stream,
|
|
N,
|
|
A * H * W,
|
|
preNmsTop,
|
|
nmsMaxOut,
|
|
iouThreshold,
|
|
t_fgScores, l_fgScores, fgScores,
|
|
t_proposals, l_proposals, proposals,
|
|
nmsWorkspace,
|
|
t_rois, rois);
|
|
ASSERT_FAILURE(status == STATUS_SUCCESS);
|
|
|
|
DEBUG_PRINTF("&&&& ROIS %u\n", hash((void*) rois, N * nmsMaxOut * 4 * sizeof(float)));
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
// WORKSPACE SIZES
|
|
size_t proposalsForwardNMSWorkspaceSize(int N,
|
|
int A,
|
|
int H,
|
|
int W,
|
|
int nmsMaxOut)
|
|
{
|
|
return N * A * H * W * 5 * 5 * sizeof(float) + (1 << 22);
|
|
}
|
|
|
|
size_t proposalsForwardBboxWorkspaceSize(int N,
|
|
int A,
|
|
int H,
|
|
int W)
|
|
{
|
|
return N * A * H * W * 4 * sizeof(float);
|
|
}
|
|
size_t proposalForwardFgScoresWorkspaceSize(int N,
|
|
int A,
|
|
int H,
|
|
int W)
|
|
{
|
|
return N * A * H * W * sizeof(float);
|
|
}
|
|
|
|
size_t proposalsInferenceWorkspaceSize(int N,
|
|
int A,
|
|
int H,
|
|
int W,
|
|
int nmsMaxOut)
|
|
{
|
|
size_t wss[3];
|
|
wss[0] = proposalsForwardNMSWorkspaceSize(N, A, H, W, nmsMaxOut);
|
|
wss[1] = proposalsForwardBboxWorkspaceSize(N, A, H, W);
|
|
wss[2] = proposalForwardFgScoresWorkspaceSize(N, A, H, W);
|
|
return calculateTotalWorkspaceSize(wss, 3);
|
|
}
|
|
} // namespace plugin
|
|
} // namespace nvinfer1
|