Files
mediapipe/mediapipe/framework/formats/location_opencv_test.cc
T
MediaPipe TeamandSebastian Schmidt 4dc4b19ddb Project import generated by Copybara.
GitOrigin-RevId: 1e13be30e2c6838d4a2ff768a39c414bc80534bb
2022-09-06 21:46:17 +00:00

168 lines
6.2 KiB
C++

// Copyright 2022 The MediaPipe Authors.
//
// 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 "mediapipe/framework/formats/location_opencv.h"
#include "mediapipe/framework/formats/annotation/rasterization.pb.h"
#include "mediapipe/framework/port/gtest.h"
#include "mediapipe/framework/port/rectangle.h"
namespace mediapipe {
// 7x3x1 test mask pattern containing the following region types: bordering left
// and right edges, multiple and single pixel lengths, multiple and single
// segments per row.
static const int kWidth = 7;
static const int kHeight = 3;
const std::vector<uint8> kTestPatternVector = {0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0,
0, 0, 0, 1, 0, 1, 0, 1, 0, 0};
// Interval {y, x_start, x_end} representation of kTestPatternVector.
const std::vector<std::vector<int>> kTestPatternIntervals = {
{0, 5, 6}, {1, 1, 2}, {2, 0, 0}, {2, 2, 2}, {2, 4, 4}};
static const float kEps = 0.0001f;
Location TestPatternIntervalsToMaskLocation() {
LocationData data;
data.set_format(LocationData::MASK);
data.mutable_mask()->set_width(kWidth);
data.mutable_mask()->set_height(kHeight);
for (const auto& test_interval : kTestPatternIntervals) {
auto interval =
data.mutable_mask()->mutable_rasterization()->add_interval();
interval->set_y(test_interval[0]);
interval->set_left_x(test_interval[1]);
interval->set_right_x(test_interval[2]);
}
return Location(data);
}
TEST(LocationOpencvTest, CreateBBoxLocation) {
const int x_start = 1;
const int y_start = 2;
const int width = 3;
const int height = 4;
const cv::Rect cv_rect(x_start, y_start, width, height);
Location location = CreateBBoxLocation(cv_rect);
auto rect = location.GetBBox<Rectangle_i>();
const std::vector<int> cv_rect_dims(
{cv_rect.x, cv_rect.y, cv_rect.width, cv_rect.height});
const std::vector<int> rect_dims(
{rect.xmin(), rect.ymin(), rect.Width(), rect.Height()});
EXPECT_EQ(cv_rect_dims, rect_dims);
}
TEST(LocationOpencvTest, CreateCvMaskLocation) {
cv::Mat_<uint8> test_mask(kHeight, kWidth,
const_cast<uint8*>(kTestPatternVector.data()));
Location location = CreateCvMaskLocation(test_mask);
auto intervals = location.ConvertToProto().mask().rasterization().interval();
EXPECT_EQ(intervals.size(), kTestPatternIntervals.size());
for (int i = 0; i < intervals.size(); ++i) {
const std::vector<int> vec = {intervals[i].y(), intervals[i].left_x(),
intervals[i].right_x()};
EXPECT_EQ(vec, kTestPatternIntervals[i]);
}
}
TEST(LocationOpenCvTest, EnlargeLocationMaskGrow) {
const float grow_factor = 1.3;
auto test_location = TestPatternIntervalsToMaskLocation();
const float sum = cv::sum(*GetCvMask(test_location))[0];
EnlargeLocation(test_location, grow_factor);
const float grown_sum = cv::sum(*GetCvMask(test_location))[0];
EXPECT_GT(grown_sum, sum);
}
TEST(LocationOpenCvTest, EnlargeMaskShrink) {
const float shrink_factor = 0.7;
auto test_location = TestPatternIntervalsToMaskLocation();
const float sum = cv::sum(*GetCvMask(test_location))[0];
EnlargeLocation(test_location, shrink_factor);
const float shrunk_sum = cv::sum(*GetCvMask(test_location))[0];
EXPECT_GT(sum, shrunk_sum);
}
TEST(LocationOpenCvTest, EnlargeBBox) {
const float test_factor = 1.2f;
auto relative_bbox =
Location::CreateRelativeBBoxLocation(0.5f, 0.3f, 0.2f, 0.6f);
EnlargeLocation(relative_bbox, test_factor);
auto enlarged_relative_bbox_rect = relative_bbox.GetRelativeBBox();
EXPECT_NEAR(enlarged_relative_bbox_rect.xmin(), 0.48f, kEps);
EXPECT_NEAR(enlarged_relative_bbox_rect.ymin(), 0.24f, kEps);
EXPECT_NEAR(enlarged_relative_bbox_rect.Width(), 0.24f, kEps);
EXPECT_NEAR(enlarged_relative_bbox_rect.Height(), 0.72f, kEps);
auto bbox = Location::CreateBBoxLocation(50, 30, 20, 60);
EnlargeLocation(bbox, test_factor);
auto enlarged_bbox_rect = bbox.GetBBox<Rectangle_i>();
EXPECT_EQ(enlarged_bbox_rect.xmin(), 48);
EXPECT_EQ(enlarged_bbox_rect.ymin(), 24);
EXPECT_EQ(enlarged_bbox_rect.Width(), 24);
EXPECT_EQ(enlarged_bbox_rect.Height(), 72);
}
TEST(LocationOpenCvTest, ConvertRelativeBBoxToCvMask) {
const float rel_x_min = 0.1;
const float rel_y_min = 0.2;
const float rel_width = 0.3;
const float rel_height = 0.6;
const int width = 10;
const int height = 20;
cv::Size expected_size(width, height);
LocationData data;
data.set_format(LocationData::RELATIVE_BOUNDING_BOX);
data.mutable_relative_bounding_box()->set_xmin(rel_x_min);
data.mutable_relative_bounding_box()->set_ymin(rel_y_min);
data.mutable_relative_bounding_box()->set_width(rel_width);
data.mutable_relative_bounding_box()->set_height(rel_height);
Location test_location(data);
const int x_start = rel_x_min * width;
const int x_end = x_start + rel_width * width;
const int y_start = rel_y_min * height;
const int y_end = y_start + rel_height * height;
const auto cv_mask = *ConvertToCvMask(test_location, width, height);
EXPECT_EQ(cv_mask.size(), expected_size);
for (int y = 0; y < cv_mask.rows; ++y) {
for (int x = 0; x < cv_mask.cols; ++x) {
bool in_mask = (x >= x_start && x < x_end && y >= y_start && y < y_end);
float expected_value = in_mask ? 1 : 0;
ASSERT_EQ(cv_mask.at<float>(y, x), expected_value);
}
}
}
TEST(LocationOpenCvTest, GetCvMask) {
auto test_location = TestPatternIntervalsToMaskLocation();
auto cv_mask = *GetCvMask(test_location);
EXPECT_EQ(cv_mask.cols * cv_mask.rows, kTestPatternVector.size());
int flat_idx = 0;
for (auto it = cv_mask.begin<uint8>(); it != cv_mask.end<uint8>(); ++it) {
const uint8 expected_value = kTestPatternVector[flat_idx] == 0 ? 0 : 255;
EXPECT_EQ(*it, expected_value);
flat_idx++;
}
}
} // namespace mediapipe