Skip to content

Commit

Permalink
# Conflicts:
Browse files Browse the repository at this point in the history
#	docs/template_plugin/tests/functional/op_reference/convert_color_nv12.cpp
#	inference-engine/tests/functional/plugin/cpu/shared_tests_instances/single_layer_tests/convert_color_nv12.cpp
#	inference-engine/tests/functional/shared_test_classes/include/shared_test_classes/single_layer/convert_color_nv12.hpp
#	inference-engine/tests/functional/shared_test_classes/src/single_layer/convert_color_nv12.cpp
#	ngraph/core/include/openvino/core/preprocess/input_tensor_info.hpp
#	ngraph/core/include/openvino/core/preprocess/preprocess_steps.hpp
#	ngraph/core/include/openvino/op/nv12_to_bgr.hpp
#	ngraph/core/include/openvino/op/nv12_to_rgb.hpp
#	ngraph/core/src/op/nv12_to_bgr.cpp
#	ngraph/core/src/op/nv12_to_rgb.cpp
#	ngraph/core/src/preprocess/pre_post_process.cpp
#	ngraph/core/src/preprocess/preprocess_steps_impl.hpp
#	ngraph/test/CMakeLists.txt
  • Loading branch information
nosovmik committed Oct 4, 2021
1 parent 96519b1 commit a9db7a4
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 13 deletions.
20 changes: 20 additions & 0 deletions ngraph/core/include/openvino/core/preprocess/color_format.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

namespace ov {
namespace preprocess {

/// \brief Color format enumeration for conversion
enum class ColorFormat {
UNDEFINED,
NV12_SINGLE_PLANE, // Image in NV12 format as single tensor
NV12_TWO_PLANES, // Image in NV12 format represented as separate tensors for Y and UV planes
RGB,
BGR
};

} // namespace preprocess
} // namespace ov
37 changes: 37 additions & 0 deletions ngraph/core/include/openvino/core/preprocess/input_tensor_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "openvino/core/core_visibility.hpp"
#include "openvino/core/layout.hpp"
#include "openvino/core/preprocess/color_format.hpp"
#include "openvino/core/type/element_type.hpp"

namespace ov {
Expand Down Expand Up @@ -117,6 +118,42 @@ class OPENVINO_API InputTensorInfo final {
///
/// \return Rvalue reference to 'this' to allow chaining with other calls in a builder-like manner.
InputTensorInfo&& set_spatial_static_shape(size_t height, size_t width) &&;

/// \brief Set color format for user's input tensor
///
/// In general way, some formats support multi-plane input, e.g. NV12 image can be represented as 2 separate tensors
/// (planes): Y plane and UV plane. set_color_format API also allows to set sub_names for such parameters for
/// convenient usage TBD: example
///
/// This version allows chaining for Lvalue objects
///
/// \param format Color format of input image
///
/// \param sub_names Optional list of sub-names assigned for each plane (e.g. {"Y", "UV"}). If not specified,
/// sub-names for plane parameters are auto-generated, exact names auto-generation rules depend on specific color
/// format, and client's code shall not rely on these rules.
///
/// \return Reference to 'this' to allow chaining with other calls in a builder-like manner
InputTensorInfo& set_color_format(const ov::preprocess::ColorFormat& format,
const std::vector<std::string>& sub_names = {}) &;

/// \brief Set color format for user's input tensor
///
/// In general way, some formats support multi-plane input, e.g. NV12 image can be represented as 2 separate tensors
/// (planes): Y plane and UV plane. set_color_format API also allows to set sub_names for such parameters for
/// convenient usage TBD: example
///
/// This version allows chaining for Rvalue objects
///
/// \param format Color format of input image
///
/// \param sub_names Optional list of sub-names assigned for each plane (e.g. {"Y", "UV"}). If not specified,
/// sub-names for plane parameters are auto-generated, exact names auto-generation rules depend on specific color
/// format, and client's code shall not rely on these rules.
///
/// \return Rvalue reference to 'this' to allow chaining with other calls in a builder-like manner
InputTensorInfo&& set_color_format(const ov::preprocess::ColorFormat& format,
const std::vector<std::string>& sub_names = {}) &&;
};

} // namespace preprocess
Expand Down
21 changes: 21 additions & 0 deletions ngraph/core/include/openvino/core/preprocess/preprocess_steps.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include "openvino/core/core_visibility.hpp"
#include "openvino/core/preprocess/color_format.hpp"
#include "openvino/core/preprocess/resize_algorithm.hpp"
#include "openvino/core/type/element_type.hpp"

Expand Down Expand Up @@ -56,6 +57,26 @@ class OPENVINO_API PreProcessSteps final {
/// \return Rvalue reference to 'this' to allow chaining with other calls in a builder-like manner
PreProcessSteps&& convert_element_type(const ov::element::Type& type) &&;

/// \brief Converts color format for user's input tensor. Requires source color format to be specified by
/// InputTensorInfo::set_color_format.
///
/// This version allows chaining for Lvalue objects
///
/// \param dst_format Destination color format of input image
///
/// \return Reference to 'this' to allow chaining with other calls in a builder-like manner
PreProcessSteps& convert_color(const ov::preprocess::ColorFormat& dst_format) &;

/// \brief Converts color format for user's input tensor. Requires source color format to be specified by
/// InputTensorInfo::set_color_format.
///
/// This version allows chaining for Rvalue objects.
///
/// \param dst_format Color format of input image.
///
/// \return Rvalue reference to 'this' to allow chaining with other calls in a builder-like manner
PreProcessSteps&& convert_color(const ov::preprocess::ColorFormat& dst_format) &&;

/// \brief Add scale preprocess operation - Lvalue version
/// Divide each element of input by specified value
///
Expand Down
23 changes: 23 additions & 0 deletions ngraph/core/src/preprocess/color_utils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "color_utils.hpp"

using namespace ov::preprocess;

std::unique_ptr<ColorFormatInfo> ColorFormatInfo::get(ColorFormat format) {
std::unique_ptr<ColorFormatInfo> res;
switch (format) {
case ColorFormat::NV12_SINGLE_PLANE:
res.reset(new ColorFormatInfoNV12_Single(format));
break;
case ColorFormat::NV12_TWO_PLANES:
res.reset(new ColorFormatInfoNV12_TwoPlanes(format));
break;
default:
res.reset(new ColorFormatInfo(format));
break;
}
return res;
}
107 changes: 107 additions & 0 deletions ngraph/core/src/preprocess/color_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include "openvino/core/partial_shape.hpp"
#include "openvino/core/preprocess/color_format.hpp"

namespace ov {
namespace preprocess {

/// \brief Helper function to check if color format represents RGB family
inline bool is_rgb_family(const ColorFormat& format) {
return format == ColorFormat::RGB || format == ColorFormat::BGR;
}

/// \brief Internal helper class to get information depending on color format
class ColorFormatInfo {
public:
static std::unique_ptr<ColorFormatInfo> get(ColorFormat format);

virtual ~ColorFormatInfo() = default;

virtual size_t planes_count() const {
return 1;
}
// Calculate shape of plane based image shape in NHWC format
PartialShape shape(size_t plane_num, const PartialShape& image_src_shape) const {
OPENVINO_ASSERT(plane_num < planes_count(),
"Internal error: incorrect plane number specified for color format");
return calculate_shape(plane_num, image_src_shape);
}

std::string friendly_name(size_t plane_num, const std::string& original_name) const {
OPENVINO_ASSERT(plane_num < planes_count(),
"Internal error: incorrect plane number specified for color format");
return calc_friendly_name(plane_num, original_name);
}

protected:
virtual PartialShape calculate_shape(size_t plane_num, const PartialShape& image_shape) const {
return image_shape;
}
virtual std::string calc_friendly_name(size_t plane_num, const std::string& original_name) const {
return original_name;
}
explicit ColorFormatInfo(ColorFormat format) : m_format(format) {}
ColorFormat m_format;
};

// --- Derived classes ---
class ColorFormatInfoNV12_Single : public ColorFormatInfo {
public:
explicit ColorFormatInfoNV12_Single(ColorFormat format) : ColorFormatInfo(format) {}

protected:
PartialShape calculate_shape(size_t plane_num, const PartialShape& image_shape) const override {
PartialShape result = image_shape;
if (image_shape.rank().is_static() && image_shape.rank().get_length() == 4) {
result[3] = 1;
if (result[1].is_static()) {
result[1] = result[1].get_length() * 3 / 2;
}
}
return result;
}
};

class ColorFormatInfoNV12_TwoPlanes : public ColorFormatInfo {
public:
explicit ColorFormatInfoNV12_TwoPlanes(ColorFormat format) : ColorFormatInfo(format) {}

size_t planes_count() const override {
return 2;
}

protected:
PartialShape calculate_shape(size_t plane_num, const PartialShape& image_shape) const override {
PartialShape result = image_shape;
if (image_shape.rank().is_static() && image_shape.rank().get_length() == 4) {
if (plane_num == 0) {
result[3] = 1;
return result;
} else {
// UV plane has half or width and half of height. Number of channels is 2
if (result[1].is_static()) {
result[1] = result[1].get_length() / 2;
}
if (result[2].is_static()) {
result[2] = result[2].get_length() / 2;
}
result[3] = 2;
}
}
return result;
}
std::string calc_friendly_name(size_t plane_num, const std::string& original_name) const override {
if (plane_num == 0) {
return original_name + "/Y";
}
return original_name + "/UV";
}
};

} // namespace preprocess
} // namespace ov
Loading

0 comments on commit a9db7a4

Please sign in to comment.