Added support of 1x1x1xN input for parseYolo

This commit is contained in:
Ruslan Garnov 2020-11-05 02:27:32 +03:00
parent e12adcdf08
commit 0e4b5b88dc
5 changed files with 52 additions and 12 deletions

View File

@ -246,6 +246,28 @@ void parseSSD(const cv::Mat& in_ssd_result,
}
}
static void checkYoloDims(const MatSize& dims) {
const auto d = dims.dims();
// Accept 1x13x13xN and 13x13xN
GAPI_Assert(d >= 2);
if (d >= 3) {
if (dims[d-2] == 13) {
GAPI_Assert(dims[d-1]%5 == 0);
GAPI_Assert(dims[d-2] == 13);
GAPI_Assert(dims[d-3] == 13);
for (int i = 0; i < d-3; i++) {
GAPI_Assert(dims[i] == 1);
}
return;
}
}
// Accept 1x1x1xN, 1x1xN, 1xN
GAPI_Assert(dims[d-1]%(5*13*13) == 0);
for (int i = 0; i < d-1; i++) {
GAPI_Assert(dims[i] == 1);
}
}
void parseYolo(const cv::Mat& in_yolo_result,
const cv::Size& in_size,
const float confidence_threshold,
@ -255,12 +277,12 @@ void parseYolo(const cv::Mat& in_yolo_result,
std::vector<int>& out_labels)
{
const auto& dims = in_yolo_result.size;
GAPI_Assert(dims.dims() == 4);
GAPI_Assert(dims[0] == 1);
GAPI_Assert(dims[1] == 13);
GAPI_Assert(dims[2] == 13);
GAPI_Assert(dims[3] % 5 == 0); // 5 boxes
const auto num_classes = dims[3] / 5 - 5;
checkYoloDims(dims);
int acc = 1;
for (int i = 0; i < dims.dims(); i++) {
acc *= dims[i];
}
const auto num_classes = acc/(5*13*13)-5;
GAPI_Assert(num_classes > 0);
GAPI_Assert(0 < nms_threshold && nms_threshold <= 1);
out_boxes.clear();

View File

@ -157,7 +157,7 @@ GAPI_TEST_EXT_BASE_FIXTURE(ParseSSDBLTest, ParserSSDTest, initNothing,
GAPI_TEST_EXT_BASE_FIXTURE(ParseSSDTest, ParserSSDTest, initNothing,
FIXTURE_API(float, bool, bool), 3, confidence_threshold, alignment_to_square, filter_out_of_bounds)
GAPI_TEST_EXT_BASE_FIXTURE(ParseYoloTest, ParserYoloTest, initNothing,
FIXTURE_API(float, float, int), 3, confidence_threshold, nms_threshold, num_classes)
FIXTURE_API(float, float, int, std::pair<bool,int>), 4, confidence_threshold, nms_threshold, num_classes, dims_config)
GAPI_TEST_FIXTURE(SizeTest, initMatrixRandU, <>, 0)
GAPI_TEST_FIXTURE(SizeRTest, initNothing, <>, 0)
} // opencv_test

View File

@ -1666,7 +1666,7 @@ TEST_P(ParseSSDTest, ParseTest)
TEST_P(ParseYoloTest, ParseTest)
{
cv::Mat in_mat = generateYoloOutput(num_classes);
cv::Mat in_mat = generateYoloOutput(num_classes, dims_config);
auto anchors = cv::gapi::nn::parsers::GParseYolo::defaultAnchors();
std::vector<cv::Rect> boxes_gapi, boxes_ref;
std::vector<int> labels_gapi, labels_ref;

View File

@ -225,13 +225,26 @@ private:
class ParserYoloTest
{
public:
cv::Mat generateYoloOutput(const int num_classes)
cv::Mat generateYoloOutput(const int num_classes, std::pair<bool,int> dims_config = {false, 4})
{
std::vector<int> dims = { 1, 13, 13, (num_classes + 5) * 5 };
bool one_dim = false;
int num_dims = 0;
std::tie(one_dim, num_dims) = dims_config;
GAPI_Assert(num_dims <= 4);
GAPI_Assert((!one_dim && num_dims >= 3) ||
( one_dim && num_dims >= 1));
std::vector<int> dims(num_dims, 1);
if (one_dim) {
dims.back() = (num_classes+5)*5*13*13;
} else {
dims.back() = (num_classes+5)*5;
dims[num_dims-2] = 13;
dims[num_dims-3] = 13;
}
cv::Mat mat(dims, CV_32FC1);
auto data = mat.ptr<float>();
const size_t range = dims[0] * dims[1] * dims[2] * dims[3];
const size_t range = std::accumulate(dims.begin(), dims.end(), 1, std::multiplies<int>());
for (size_t i = 0; i < range; ++i)
{
data[i] = static_cast<float>(std::rand()) / RAND_MAX;

View File

@ -531,7 +531,12 @@ INSTANTIATE_TEST_CASE_P(ParseTestCPU, ParseYoloTest,
Values(CORE_CPU),
Values(0.3f, 0.5f, 0.7f),
Values(0.5f, 1.0f),
Values(80, 7)));
Values(80, 7),
Values(std::make_pair(false, 3),
std::make_pair(false, 4),
std::make_pair(true, 2),
std::make_pair(true, 3),
std::make_pair(true, 4))));
INSTANTIATE_TEST_CASE_P(SizeTestCPU, SizeTest,
Combine(Values(CV_8UC1, CV_8UC3, CV_32FC1),