mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6860e8ed77 | |||
| 719059f671 | |||
| 4eb82c2ed0 | |||
| 5516c2eda1 | |||
| 18ea4758e2 | |||
| 1c2792bc60 | |||
| eb68476aaf | |||
| 8d0fc8bfb5 | |||
| e2f5671280 | |||
| ba30403581 | |||
| 0a31fa19f8 | |||
| 8cfe9546f3 | |||
| fd2b5411e4 | |||
| dd66cccbbd |
@@ -78,10 +78,17 @@ function(ocv_create_plugin module default_name dependency_target dependency_targ
|
|||||||
set_target_properties(${OPENCV_PLUGIN_NAME} PROPERTIES PREFIX "${OPENCV_PLUGIN_MODULE_PREFIX}")
|
set_target_properties(${OPENCV_PLUGIN_NAME} PROPERTIES PREFIX "${OPENCV_PLUGIN_MODULE_PREFIX}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(WIN32 OR NOT APPLE)
|
||||||
set_target_properties(${OPENCV_PLUGIN_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
set(OPENCV_PLUGIN_NO_LINK FALSE CACHE BOOL "")
|
||||||
elseif(WIN32)
|
else()
|
||||||
# Hack for Windows only, Linux/MacOS uses global symbol table (without exact .so binding)
|
set(OPENCV_PLUGIN_NO_LINK TRUE CACHE BOOL "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(OPENCV_PLUGIN_NO_LINK)
|
||||||
|
if(APPLE)
|
||||||
|
set_target_properties(${OPENCV_PLUGIN_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
find_package(OpenCV REQUIRED ${module} ${OPENCV_PLUGIN_DEPS})
|
find_package(OpenCV REQUIRED ${module} ${OPENCV_PLUGIN_DEPS})
|
||||||
target_link_libraries(${OPENCV_PLUGIN_NAME} PRIVATE ${OpenCV_LIBRARIES})
|
target_link_libraries(${OPENCV_PLUGIN_NAME} PRIVATE ${OpenCV_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#define CV_VERSION_MAJOR 4
|
#define CV_VERSION_MAJOR 4
|
||||||
#define CV_VERSION_MINOR 5
|
#define CV_VERSION_MINOR 5
|
||||||
#define CV_VERSION_REVISION 3
|
#define CV_VERSION_REVISION 3
|
||||||
#define CV_VERSION_STATUS "-pre"
|
#define CV_VERSION_STATUS "-openvino"
|
||||||
|
|
||||||
#define CVAUX_STR_EXP(__A) #__A
|
#define CVAUX_STR_EXP(__A) #__A
|
||||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||||
|
|||||||
@@ -1194,7 +1194,7 @@ double norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask
|
|||||||
// special case to handle "integer" overflow in accumulator
|
// special case to handle "integer" overflow in accumulator
|
||||||
const size_t esz = src1.elemSize();
|
const size_t esz = src1.elemSize();
|
||||||
const int total = (int)it.size;
|
const int total = (int)it.size;
|
||||||
const int intSumBlockSize = normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15);
|
const int intSumBlockSize = (normType == NORM_L1 && depth <= CV_8S ? (1 << 23) : (1 << 15))/cn;
|
||||||
const int blockSize = std::min(total, intSumBlockSize);
|
const int blockSize = std::min(total, intSumBlockSize);
|
||||||
int isum = 0;
|
int isum = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|||||||
@@ -2166,6 +2166,15 @@ TEST(Core_Norm, IPP_regression_NORM_L1_16UC3_small)
|
|||||||
EXPECT_EQ((double)20*cn, cv::norm(a, b, NORM_L1, mask));
|
EXPECT_EQ((double)20*cn, cv::norm(a, b, NORM_L1, mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Core_Norm, NORM_L2_8UC4)
|
||||||
|
{
|
||||||
|
// Tests there is no integer overflow in norm computation for multiple channels.
|
||||||
|
const int kSide = 100;
|
||||||
|
cv::Mat4b a(kSide, kSide, cv::Scalar(255, 255, 255, 255));
|
||||||
|
cv::Mat4b b = cv::Mat4b::zeros(kSide, kSide);
|
||||||
|
const double kNorm = 2.*kSide*255.;
|
||||||
|
EXPECT_EQ(kNorm, cv::norm(a, b, NORM_L2));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(Core_ConvertTo, regression_12121)
|
TEST(Core_ConvertTo, regression_12121)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ namespace detail
|
|||||||
CV_UNKNOWN, // Unknown, generic, opaque-to-GAPI data type unsupported in graph seriallization
|
CV_UNKNOWN, // Unknown, generic, opaque-to-GAPI data type unsupported in graph seriallization
|
||||||
CV_BOOL, // bool user G-API data
|
CV_BOOL, // bool user G-API data
|
||||||
CV_INT, // int user G-API data
|
CV_INT, // int user G-API data
|
||||||
|
CV_INT64, // int64_t user G-API data
|
||||||
CV_DOUBLE, // double user G-API data
|
CV_DOUBLE, // double user G-API data
|
||||||
CV_FLOAT, // float user G-API data
|
CV_FLOAT, // float user G-API data
|
||||||
CV_UINT64, // uint64_t user G-API data
|
CV_UINT64, // uint64_t user G-API data
|
||||||
@@ -61,6 +62,7 @@ namespace detail
|
|||||||
template<typename T> struct GOpaqueTraits;
|
template<typename T> struct GOpaqueTraits;
|
||||||
template<typename T> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_UNKNOWN; };
|
template<typename T> struct GOpaqueTraits { static constexpr const OpaqueKind kind = OpaqueKind::CV_UNKNOWN; };
|
||||||
template<> struct GOpaqueTraits<int> { static constexpr const OpaqueKind kind = OpaqueKind::CV_INT; };
|
template<> struct GOpaqueTraits<int> { static constexpr const OpaqueKind kind = OpaqueKind::CV_INT; };
|
||||||
|
template<> struct GOpaqueTraits<int64_t> { static constexpr const OpaqueKind kind = OpaqueKind::CV_INT64; };
|
||||||
template<> struct GOpaqueTraits<double> { static constexpr const OpaqueKind kind = OpaqueKind::CV_DOUBLE; };
|
template<> struct GOpaqueTraits<double> { static constexpr const OpaqueKind kind = OpaqueKind::CV_DOUBLE; };
|
||||||
template<> struct GOpaqueTraits<float> { static constexpr const OpaqueKind kind = OpaqueKind::CV_FLOAT; };
|
template<> struct GOpaqueTraits<float> { static constexpr const OpaqueKind kind = OpaqueKind::CV_FLOAT; };
|
||||||
template<> struct GOpaqueTraits<uint64_t> { static constexpr const OpaqueKind kind = OpaqueKind::CV_UINT64; };
|
template<> struct GOpaqueTraits<uint64_t> { static constexpr const OpaqueKind kind = OpaqueKind::CV_UINT64; };
|
||||||
|
|||||||
@@ -437,11 +437,7 @@ public:
|
|||||||
*
|
*
|
||||||
* @sa @ref gapi_compile_args
|
* @sa @ref gapi_compile_args
|
||||||
*/
|
*/
|
||||||
GStreamingCompiled compileStreaming(GMetaArgs &&in_metas, GCompileArgs &&args = {});
|
GAPI_WRAP GStreamingCompiled compileStreaming(GMetaArgs &&in_metas, GCompileArgs &&args = {});
|
||||||
|
|
||||||
/// @private -- Exclude this function from OpenCV documentation
|
|
||||||
GAPI_WRAP GStreamingCompiled compileStreaming(const cv::detail::ExtractMetaCallback &callback,
|
|
||||||
GCompileArgs &&args = {});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compile the computation for streaming mode.
|
* @brief Compile the computation for streaming mode.
|
||||||
@@ -464,6 +460,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
GAPI_WRAP GStreamingCompiled compileStreaming(GCompileArgs &&args = {});
|
GAPI_WRAP GStreamingCompiled compileStreaming(GCompileArgs &&args = {});
|
||||||
|
|
||||||
|
/// @private -- Exclude this function from OpenCV documentation
|
||||||
|
GAPI_WRAP GStreamingCompiled compileStreaming(const cv::detail::ExtractMetaCallback &callback,
|
||||||
|
GCompileArgs &&args = {});
|
||||||
|
|
||||||
// 2. Direct metadata version
|
// 2. Direct metadata version
|
||||||
/**
|
/**
|
||||||
* @overload
|
* @overload
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
// of this distribution and at http://opencv.org/license.html.
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2018 Intel Corporation
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
|
||||||
|
|
||||||
#ifndef OPENCV_GAPI_GSTREAMING_COMPILED_HPP
|
#ifndef OPENCV_GAPI_GSTREAMING_COMPILED_HPP
|
||||||
@@ -65,12 +65,23 @@ using OptionalOpaqueRef = OptRef<cv::detail::OpaqueRef>;
|
|||||||
using GOptRunArgP = util::variant<
|
using GOptRunArgP = util::variant<
|
||||||
optional<cv::Mat>*,
|
optional<cv::Mat>*,
|
||||||
optional<cv::RMat>*,
|
optional<cv::RMat>*,
|
||||||
|
optional<cv::MediaFrame>*,
|
||||||
optional<cv::Scalar>*,
|
optional<cv::Scalar>*,
|
||||||
cv::detail::OptionalVectorRef,
|
cv::detail::OptionalVectorRef,
|
||||||
cv::detail::OptionalOpaqueRef
|
cv::detail::OptionalOpaqueRef
|
||||||
>;
|
>;
|
||||||
using GOptRunArgsP = std::vector<GOptRunArgP>;
|
using GOptRunArgsP = std::vector<GOptRunArgP>;
|
||||||
|
|
||||||
|
using GOptRunArg = util::variant<
|
||||||
|
optional<cv::Mat>,
|
||||||
|
optional<cv::RMat>,
|
||||||
|
optional<cv::MediaFrame>,
|
||||||
|
optional<cv::Scalar>,
|
||||||
|
optional<cv::detail::VectorRef>,
|
||||||
|
optional<cv::detail::OpaqueRef>
|
||||||
|
>;
|
||||||
|
using GOptRunArgs = std::vector<GOptRunArg>;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<typename T> inline GOptRunArgP wrap_opt_arg(optional<T>& arg) {
|
template<typename T> inline GOptRunArgP wrap_opt_arg(optional<T>& arg) {
|
||||||
@@ -86,6 +97,14 @@ template<> inline GOptRunArgP wrap_opt_arg(optional<cv::Mat> &m) {
|
|||||||
return GOptRunArgP{&m};
|
return GOptRunArgP{&m};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> inline GOptRunArgP wrap_opt_arg(optional<cv::RMat> &m) {
|
||||||
|
return GOptRunArgP{&m};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline GOptRunArgP wrap_opt_arg(optional<cv::MediaFrame> &f) {
|
||||||
|
return GOptRunArgP{&f};
|
||||||
|
}
|
||||||
|
|
||||||
template<> inline GOptRunArgP wrap_opt_arg(optional<cv::Scalar> &s) {
|
template<> inline GOptRunArgP wrap_opt_arg(optional<cv::Scalar> &s) {
|
||||||
return GOptRunArgP{&s};
|
return GOptRunArgP{&s};
|
||||||
}
|
}
|
||||||
@@ -196,7 +215,7 @@ public:
|
|||||||
* @param s a shared pointer to IStreamSource representing the
|
* @param s a shared pointer to IStreamSource representing the
|
||||||
* input video stream.
|
* input video stream.
|
||||||
*/
|
*/
|
||||||
GAPI_WRAP void setSource(const gapi::wip::IStreamSource::Ptr& s);
|
void setSource(const gapi::wip::IStreamSource::Ptr& s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructs and specifies an input video stream for a
|
* @brief Constructs and specifies an input video stream for a
|
||||||
@@ -255,7 +274,7 @@ public:
|
|||||||
|
|
||||||
// NB: Used from python
|
// NB: Used from python
|
||||||
/// @private -- Exclude this function from OpenCV documentation
|
/// @private -- Exclude this function from OpenCV documentation
|
||||||
GAPI_WRAP std::tuple<bool, cv::GRunArgs> pull();
|
GAPI_WRAP std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> pull();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get some next available data from the pipeline.
|
* @brief Get some next available data from the pipeline.
|
||||||
@@ -379,9 +398,11 @@ namespace streaming {
|
|||||||
* In the streaming mode the pipeline steps are connected with queues
|
* In the streaming mode the pipeline steps are connected with queues
|
||||||
* and this compile argument controls every queue's size.
|
* and this compile argument controls every queue's size.
|
||||||
*/
|
*/
|
||||||
struct GAPI_EXPORTS queue_capacity
|
struct GAPI_EXPORTS_W_SIMPLE queue_capacity
|
||||||
{
|
{
|
||||||
|
GAPI_WRAP
|
||||||
explicit queue_capacity(size_t cap = 1) : capacity(cap) { };
|
explicit queue_capacity(size_t cap = 1) : capacity(cap) { };
|
||||||
|
GAPI_PROP_RW
|
||||||
size_t capacity;
|
size_t capacity;
|
||||||
};
|
};
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@@ -136,11 +136,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
void setInput(const std::string& name, U in)
|
GInferInputsTyped<Ts...>& setInput(const std::string& name, U in)
|
||||||
{
|
{
|
||||||
m_priv->blobs.emplace(std::piecewise_construct,
|
m_priv->blobs.emplace(std::piecewise_construct,
|
||||||
std::forward_as_tuple(name),
|
std::forward_as_tuple(name),
|
||||||
std::forward_as_tuple(in));
|
std::forward_as_tuple(in));
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
using StorageT = cv::util::variant<Ts...>;
|
using StorageT = cv::util::variant<Ts...>;
|
||||||
@@ -653,7 +654,8 @@ namespace gapi {
|
|||||||
|
|
||||||
// A type-erased form of network parameters.
|
// A type-erased form of network parameters.
|
||||||
// Similar to how a type-erased GKernel is represented and used.
|
// Similar to how a type-erased GKernel is represented and used.
|
||||||
struct GAPI_EXPORTS GNetParam {
|
/// @private
|
||||||
|
struct GAPI_EXPORTS_W_SIMPLE GNetParam {
|
||||||
std::string tag; // FIXME: const?
|
std::string tag; // FIXME: const?
|
||||||
GBackend backend; // Specifies the execution model
|
GBackend backend; // Specifies the execution model
|
||||||
util::any params; // Backend-interpreted parameter structure
|
util::any params; // Backend-interpreted parameter structure
|
||||||
@@ -670,6 +672,7 @@ struct GAPI_EXPORTS GNetParam {
|
|||||||
*/
|
*/
|
||||||
struct GAPI_EXPORTS_W_SIMPLE GNetPackage {
|
struct GAPI_EXPORTS_W_SIMPLE GNetPackage {
|
||||||
GAPI_WRAP GNetPackage() = default;
|
GAPI_WRAP GNetPackage() = default;
|
||||||
|
GAPI_WRAP explicit GNetPackage(std::vector<GNetParam> nets);
|
||||||
explicit GNetPackage(std::initializer_list<GNetParam> ii);
|
explicit GNetPackage(std::initializer_list<GNetParam> ii);
|
||||||
std::vector<GBackend> backends() const;
|
std::vector<GBackend> backends() const;
|
||||||
std::vector<GNetParam> networks;
|
std::vector<GNetParam> networks;
|
||||||
|
|||||||
@@ -22,17 +22,28 @@ namespace ie {
|
|||||||
// This class can be marked as SIMPLE, because it's implemented as pimpl
|
// This class can be marked as SIMPLE, because it's implemented as pimpl
|
||||||
class GAPI_EXPORTS_W_SIMPLE PyParams {
|
class GAPI_EXPORTS_W_SIMPLE PyParams {
|
||||||
public:
|
public:
|
||||||
|
GAPI_WRAP
|
||||||
PyParams() = default;
|
PyParams() = default;
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
PyParams(const std::string &tag,
|
PyParams(const std::string &tag,
|
||||||
const std::string &model,
|
const std::string &model,
|
||||||
const std::string &weights,
|
const std::string &weights,
|
||||||
const std::string &device);
|
const std::string &device);
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
PyParams(const std::string &tag,
|
PyParams(const std::string &tag,
|
||||||
const std::string &model,
|
const std::string &model,
|
||||||
const std::string &device);
|
const std::string &device);
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
|
PyParams& constInput(const std::string &layer_name,
|
||||||
|
const cv::Mat &data,
|
||||||
|
TraitAs hint = TraitAs::TENSOR);
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
|
PyParams& cfgNumRequests(size_t nireq);
|
||||||
|
|
||||||
GBackend backend() const;
|
GBackend backend() const;
|
||||||
std::string tag() const;
|
std::string tag() const;
|
||||||
cv::util::any params() const;
|
cv::util::any params() const;
|
||||||
|
|||||||
@@ -64,12 +64,13 @@ detection is smaller than confidence threshold, detection is rejected.
|
|||||||
given label will get to the output.
|
given label will get to the output.
|
||||||
@return a tuple with a vector of detected boxes and a vector of appropriate labels.
|
@return a tuple with a vector of detected boxes and a vector of appropriate labels.
|
||||||
*/
|
*/
|
||||||
GAPI_EXPORTS std::tuple<GArray<Rect>, GArray<int>> parseSSD(const GMat& in,
|
GAPI_EXPORTS_W std::tuple<GArray<Rect>, GArray<int>> parseSSD(const GMat& in,
|
||||||
const GOpaque<Size>& inSz,
|
const GOpaque<Size>& inSz,
|
||||||
const float confidenceThreshold = 0.5f,
|
const float confidenceThreshold = 0.5f,
|
||||||
const int filterLabel = -1);
|
const int filterLabel = -1);
|
||||||
|
|
||||||
|
/** @brief Parses output of SSD network.
|
||||||
|
|
||||||
/** @overload
|
|
||||||
Extracts detection information (box, confidence) from SSD output and
|
Extracts detection information (box, confidence) from SSD output and
|
||||||
filters it by given confidence and by going out of bounds.
|
filters it by given confidence and by going out of bounds.
|
||||||
|
|
||||||
@@ -87,9 +88,9 @@ the larger side of the rectangle.
|
|||||||
*/
|
*/
|
||||||
GAPI_EXPORTS_W GArray<Rect> parseSSD(const GMat& in,
|
GAPI_EXPORTS_W GArray<Rect> parseSSD(const GMat& in,
|
||||||
const GOpaque<Size>& inSz,
|
const GOpaque<Size>& inSz,
|
||||||
const float confidenceThreshold = 0.5f,
|
const float confidenceThreshold,
|
||||||
const bool alignmentToSquare = false,
|
const bool alignmentToSquare,
|
||||||
const bool filterOutOfBounds = false);
|
const bool filterOutOfBounds);
|
||||||
|
|
||||||
/** @brief Parses output of Yolo network.
|
/** @brief Parses output of Yolo network.
|
||||||
|
|
||||||
@@ -112,12 +113,12 @@ If 1.f, nms is not performed and no boxes are rejected.
|
|||||||
<a href="https://github.com/openvinotoolkit/open_model_zoo/blob/master/models/public/yolo-v2-tiny-tf/yolo-v2-tiny-tf.md">documentation</a>.
|
<a href="https://github.com/openvinotoolkit/open_model_zoo/blob/master/models/public/yolo-v2-tiny-tf/yolo-v2-tiny-tf.md">documentation</a>.
|
||||||
@return a tuple with a vector of detected boxes and a vector of appropriate labels.
|
@return a tuple with a vector of detected boxes and a vector of appropriate labels.
|
||||||
*/
|
*/
|
||||||
GAPI_EXPORTS std::tuple<GArray<Rect>, GArray<int>> parseYolo(const GMat& in,
|
GAPI_EXPORTS_W std::tuple<GArray<Rect>, GArray<int>> parseYolo(const GMat& in,
|
||||||
const GOpaque<Size>& inSz,
|
const GOpaque<Size>& inSz,
|
||||||
const float confidenceThreshold = 0.5f,
|
const float confidenceThreshold = 0.5f,
|
||||||
const float nmsThreshold = 0.5f,
|
const float nmsThreshold = 0.5f,
|
||||||
const std::vector<float>& anchors
|
const std::vector<float>& anchors
|
||||||
= nn::parsers::GParseYolo::defaultAnchors());
|
= nn::parsers::GParseYolo::defaultAnchors());
|
||||||
|
|
||||||
} // namespace gapi
|
} // namespace gapi
|
||||||
} // namespace cv
|
} // namespace cv
|
||||||
|
|||||||
@@ -13,11 +13,13 @@
|
|||||||
# define GAPI_EXPORTS CV_EXPORTS
|
# define GAPI_EXPORTS CV_EXPORTS
|
||||||
/* special informative macros for wrapper generators */
|
/* special informative macros for wrapper generators */
|
||||||
# define GAPI_PROP CV_PROP
|
# define GAPI_PROP CV_PROP
|
||||||
|
# define GAPI_PROP_RW CV_PROP_RW
|
||||||
# define GAPI_WRAP CV_WRAP
|
# define GAPI_WRAP CV_WRAP
|
||||||
# define GAPI_EXPORTS_W_SIMPLE CV_EXPORTS_W_SIMPLE
|
# define GAPI_EXPORTS_W_SIMPLE CV_EXPORTS_W_SIMPLE
|
||||||
# define GAPI_EXPORTS_W CV_EXPORTS_W
|
# define GAPI_EXPORTS_W CV_EXPORTS_W
|
||||||
# else
|
# else
|
||||||
# define GAPI_PROP
|
# define GAPI_PROP
|
||||||
|
# define GAPI_PROP_RW
|
||||||
# define GAPI_WRAP
|
# define GAPI_WRAP
|
||||||
# define GAPI_EXPORTS
|
# define GAPI_EXPORTS
|
||||||
# define GAPI_EXPORTS_W_SIMPLE
|
# define GAPI_EXPORTS_W_SIMPLE
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ using GMatDesc2 = std::tuple<cv::GMatDesc,cv::GMatDesc>;
|
|||||||
@param prims vector of drawing primitivies
|
@param prims vector of drawing primitivies
|
||||||
@param args graph compile time parameters
|
@param args graph compile time parameters
|
||||||
*/
|
*/
|
||||||
void GAPI_EXPORTS render(cv::Mat& bgr,
|
void GAPI_EXPORTS_W render(cv::Mat& bgr,
|
||||||
const Prims& prims,
|
const Prims& prims,
|
||||||
cv::GCompileArgs&& args = {});
|
cv::GCompileArgs&& args = {});
|
||||||
|
|
||||||
/** @brief The function renders on two NV12 planes passed drawing primitivies
|
/** @brief The function renders on two NV12 planes passed drawing primitivies
|
||||||
|
|
||||||
@@ -92,10 +92,10 @@ void GAPI_EXPORTS render(cv::Mat& bgr,
|
|||||||
@param prims vector of drawing primitivies
|
@param prims vector of drawing primitivies
|
||||||
@param args graph compile time parameters
|
@param args graph compile time parameters
|
||||||
*/
|
*/
|
||||||
void GAPI_EXPORTS render(cv::Mat& y_plane,
|
void GAPI_EXPORTS_W render(cv::Mat& y_plane,
|
||||||
cv::Mat& uv_plane,
|
cv::Mat& uv_plane,
|
||||||
const Prims& prims,
|
const Prims& prims,
|
||||||
cv::GCompileArgs&& args = {});
|
cv::GCompileArgs&& args = {});
|
||||||
|
|
||||||
/** @brief The function renders on the input media frame passed drawing primitivies
|
/** @brief The function renders on the input media frame passed drawing primitivies
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ Output image must be 8-bit unsigned planar 3-channel image
|
|||||||
@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3
|
@param src input image: 8-bit unsigned 3-channel image @ref CV_8UC3
|
||||||
@param prims draw primitives
|
@param prims draw primitives
|
||||||
*/
|
*/
|
||||||
GAPI_EXPORTS GMat render3ch(const GMat& src, const GArray<Prim>& prims);
|
GAPI_EXPORTS_W GMat render3ch(const GMat& src, const GArray<Prim>& prims);
|
||||||
|
|
||||||
/** @brief Renders on two planes
|
/** @brief Renders on two planes
|
||||||
|
|
||||||
@@ -150,9 +150,9 @@ uv image must be 8-bit unsigned planar 2-channel image @ref CV_8UC2
|
|||||||
@param uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2
|
@param uv input image: 8-bit unsigned 2-channel image @ref CV_8UC2
|
||||||
@param prims draw primitives
|
@param prims draw primitives
|
||||||
*/
|
*/
|
||||||
GAPI_EXPORTS GMat2 renderNV12(const GMat& y,
|
GAPI_EXPORTS_W GMat2 renderNV12(const GMat& y,
|
||||||
const GMat& uv,
|
const GMat& uv,
|
||||||
const GArray<Prim>& prims);
|
const GArray<Prim>& prims);
|
||||||
|
|
||||||
/** @brief Renders Media Frame
|
/** @brief Renders Media Frame
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ namespace render
|
|||||||
{
|
{
|
||||||
namespace ocv
|
namespace ocv
|
||||||
{
|
{
|
||||||
GAPI_EXPORTS cv::gapi::GKernelPackage kernels();
|
GAPI_EXPORTS_W cv::gapi::GKernelPackage kernels();
|
||||||
|
|
||||||
} // namespace ocv
|
} // namespace ocv
|
||||||
} // namespace render
|
} // namespace render
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ struct freetype_font
|
|||||||
*
|
*
|
||||||
* Parameters match cv::putText().
|
* Parameters match cv::putText().
|
||||||
*/
|
*/
|
||||||
struct Text
|
struct GAPI_EXPORTS_W_SIMPLE Text
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Text constructor
|
* @brief Text constructor
|
||||||
@@ -55,6 +55,7 @@ struct Text
|
|||||||
* @param lt_ The line type. See #LineTypes
|
* @param lt_ The line type. See #LineTypes
|
||||||
* @param bottom_left_origin_ When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
|
* @param bottom_left_origin_ When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
|
||||||
*/
|
*/
|
||||||
|
GAPI_WRAP
|
||||||
Text(const std::string& text_,
|
Text(const std::string& text_,
|
||||||
const cv::Point& org_,
|
const cv::Point& org_,
|
||||||
int ff_,
|
int ff_,
|
||||||
@@ -68,17 +69,18 @@ struct Text
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
Text() = default;
|
Text() = default;
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
std::string text; //!< The text string to be drawn
|
GAPI_PROP_RW std::string text; //!< The text string to be drawn
|
||||||
cv::Point org; //!< The bottom-left corner of the text string in the image
|
GAPI_PROP_RW cv::Point org; //!< The bottom-left corner of the text string in the image
|
||||||
int ff; //!< The font type, see #HersheyFonts
|
GAPI_PROP_RW int ff; //!< The font type, see #HersheyFonts
|
||||||
double fs; //!< The font scale factor that is multiplied by the font-specific base size
|
GAPI_PROP_RW double fs; //!< The font scale factor that is multiplied by the font-specific base size
|
||||||
cv::Scalar color; //!< The text color
|
GAPI_PROP_RW cv::Scalar color; //!< The text color
|
||||||
int thick; //!< The thickness of the lines used to draw a text
|
GAPI_PROP_RW int thick; //!< The thickness of the lines used to draw a text
|
||||||
int lt; //!< The line type. See #LineTypes
|
GAPI_PROP_RW int lt; //!< The line type. See #LineTypes
|
||||||
bool bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
|
GAPI_PROP_RW bool bottom_left_origin; //!< When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner
|
||||||
/*@{*/
|
/*@{*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -122,7 +124,7 @@ struct FText
|
|||||||
*
|
*
|
||||||
* Parameters match cv::rectangle().
|
* Parameters match cv::rectangle().
|
||||||
*/
|
*/
|
||||||
struct Rect
|
struct GAPI_EXPORTS_W_SIMPLE Rect
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Rect constructor
|
* @brief Rect constructor
|
||||||
@@ -142,14 +144,15 @@ struct Rect
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
Rect() = default;
|
Rect() = default;
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
cv::Rect rect; //!< Coordinates of the rectangle
|
GAPI_PROP_RW cv::Rect rect; //!< Coordinates of the rectangle
|
||||||
cv::Scalar color; //!< The rectangle color or brightness (grayscale image)
|
GAPI_PROP_RW cv::Scalar color; //!< The rectangle color or brightness (grayscale image)
|
||||||
int thick; //!< The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle
|
GAPI_PROP_RW int thick; //!< The thickness of lines that make up the rectangle. Negative values, like #FILLED, mean that the function has to draw a filled rectangle
|
||||||
int lt; //!< The type of the line. See #LineTypes
|
GAPI_PROP_RW int lt; //!< The type of the line. See #LineTypes
|
||||||
int shift; //!< The number of fractional bits in the point coordinates
|
GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinates
|
||||||
/*@{*/
|
/*@{*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -158,7 +161,7 @@ struct Rect
|
|||||||
*
|
*
|
||||||
* Parameters match cv::circle().
|
* Parameters match cv::circle().
|
||||||
*/
|
*/
|
||||||
struct Circle
|
struct GAPI_EXPORTS_W_SIMPLE Circle
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Circle constructor
|
* @brief Circle constructor
|
||||||
@@ -170,6 +173,7 @@ struct Circle
|
|||||||
* @param lt_ The Type of the circle boundary. See #LineTypes
|
* @param lt_ The Type of the circle boundary. See #LineTypes
|
||||||
* @param shift_ The Number of fractional bits in the coordinates of the center and in the radius value
|
* @param shift_ The Number of fractional bits in the coordinates of the center and in the radius value
|
||||||
*/
|
*/
|
||||||
|
GAPI_WRAP
|
||||||
Circle(const cv::Point& center_,
|
Circle(const cv::Point& center_,
|
||||||
int radius_,
|
int radius_,
|
||||||
const cv::Scalar& color_,
|
const cv::Scalar& color_,
|
||||||
@@ -180,15 +184,16 @@ struct Circle
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
Circle() = default;
|
Circle() = default;
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
cv::Point center; //!< The center of the circle
|
GAPI_PROP_RW cv::Point center; //!< The center of the circle
|
||||||
int radius; //!< The radius of the circle
|
GAPI_PROP_RW int radius; //!< The radius of the circle
|
||||||
cv::Scalar color; //!< The color of the circle
|
GAPI_PROP_RW cv::Scalar color; //!< The color of the circle
|
||||||
int thick; //!< The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn
|
GAPI_PROP_RW int thick; //!< The thickness of the circle outline, if positive. Negative values, like #FILLED, mean that a filled circle is to be drawn
|
||||||
int lt; //!< The Type of the circle boundary. See #LineTypes
|
GAPI_PROP_RW int lt; //!< The Type of the circle boundary. See #LineTypes
|
||||||
int shift; //!< The Number of fractional bits in the coordinates of the center and in the radius value
|
GAPI_PROP_RW int shift; //!< The Number of fractional bits in the coordinates of the center and in the radius value
|
||||||
/*@{*/
|
/*@{*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -197,7 +202,7 @@ struct Circle
|
|||||||
*
|
*
|
||||||
* Parameters match cv::line().
|
* Parameters match cv::line().
|
||||||
*/
|
*/
|
||||||
struct Line
|
struct GAPI_EXPORTS_W_SIMPLE Line
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Line constructor
|
* @brief Line constructor
|
||||||
@@ -209,6 +214,7 @@ struct Line
|
|||||||
* @param lt_ The Type of the line. See #LineTypes
|
* @param lt_ The Type of the line. See #LineTypes
|
||||||
* @param shift_ The number of fractional bits in the point coordinates
|
* @param shift_ The number of fractional bits in the point coordinates
|
||||||
*/
|
*/
|
||||||
|
GAPI_WRAP
|
||||||
Line(const cv::Point& pt1_,
|
Line(const cv::Point& pt1_,
|
||||||
const cv::Point& pt2_,
|
const cv::Point& pt2_,
|
||||||
const cv::Scalar& color_,
|
const cv::Scalar& color_,
|
||||||
@@ -219,15 +225,16 @@ struct Line
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
Line() = default;
|
Line() = default;
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
cv::Point pt1; //!< The first point of the line segment
|
GAPI_PROP_RW cv::Point pt1; //!< The first point of the line segment
|
||||||
cv::Point pt2; //!< The second point of the line segment
|
GAPI_PROP_RW cv::Point pt2; //!< The second point of the line segment
|
||||||
cv::Scalar color; //!< The line color
|
GAPI_PROP_RW cv::Scalar color; //!< The line color
|
||||||
int thick; //!< The thickness of line
|
GAPI_PROP_RW int thick; //!< The thickness of line
|
||||||
int lt; //!< The Type of the line. See #LineTypes
|
GAPI_PROP_RW int lt; //!< The Type of the line. See #LineTypes
|
||||||
int shift; //!< The number of fractional bits in the point coordinates
|
GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinates
|
||||||
/*@{*/
|
/*@{*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -236,7 +243,7 @@ struct Line
|
|||||||
*
|
*
|
||||||
* Mosaicing is a very basic method to obfuscate regions in the image.
|
* Mosaicing is a very basic method to obfuscate regions in the image.
|
||||||
*/
|
*/
|
||||||
struct Mosaic
|
struct GAPI_EXPORTS_W_SIMPLE Mosaic
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Mosaic constructor
|
* @brief Mosaic constructor
|
||||||
@@ -252,12 +259,13 @@ struct Mosaic
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
Mosaic() : cellSz(0), decim(0) {}
|
Mosaic() : cellSz(0), decim(0) {}
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
cv::Rect mos; //!< Coordinates of the mosaic
|
GAPI_PROP_RW cv::Rect mos; //!< Coordinates of the mosaic
|
||||||
int cellSz; //!< Cell size (same for X, Y)
|
GAPI_PROP_RW int cellSz; //!< Cell size (same for X, Y)
|
||||||
int decim; //!< Decimation (0 stands for no decimation)
|
GAPI_PROP_RW int decim; //!< Decimation (0 stands for no decimation)
|
||||||
/*@{*/
|
/*@{*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -266,7 +274,7 @@ struct Mosaic
|
|||||||
*
|
*
|
||||||
* Image is blended on a frame using the specified mask.
|
* Image is blended on a frame using the specified mask.
|
||||||
*/
|
*/
|
||||||
struct Image
|
struct GAPI_EXPORTS_W_SIMPLE Image
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Mosaic constructor
|
* @brief Mosaic constructor
|
||||||
@@ -275,6 +283,7 @@ struct Image
|
|||||||
* @param img_ Image to draw
|
* @param img_ Image to draw
|
||||||
* @param alpha_ Alpha channel for image to draw (same size and number of channels)
|
* @param alpha_ Alpha channel for image to draw (same size and number of channels)
|
||||||
*/
|
*/
|
||||||
|
GAPI_WRAP
|
||||||
Image(const cv::Point& org_,
|
Image(const cv::Point& org_,
|
||||||
const cv::Mat& img_,
|
const cv::Mat& img_,
|
||||||
const cv::Mat& alpha_) :
|
const cv::Mat& alpha_) :
|
||||||
@@ -282,19 +291,20 @@ struct Image
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
Image() = default;
|
Image() = default;
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
cv::Point org; //!< The bottom-left corner of the image
|
GAPI_PROP_RW cv::Point org; //!< The bottom-left corner of the image
|
||||||
cv::Mat img; //!< Image to draw
|
GAPI_PROP_RW cv::Mat img; //!< Image to draw
|
||||||
cv::Mat alpha; //!< Alpha channel for image to draw (same size and number of channels)
|
GAPI_PROP_RW cv::Mat alpha; //!< Alpha channel for image to draw (same size and number of channels)
|
||||||
/*@{*/
|
/*@{*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This structure represents a polygon to draw.
|
* @brief This structure represents a polygon to draw.
|
||||||
*/
|
*/
|
||||||
struct Poly
|
struct GAPI_EXPORTS_W_SIMPLE Poly
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Mosaic constructor
|
* @brief Mosaic constructor
|
||||||
@@ -305,6 +315,7 @@ struct Poly
|
|||||||
* @param lt_ The Type of the line. See #LineTypes
|
* @param lt_ The Type of the line. See #LineTypes
|
||||||
* @param shift_ The number of fractional bits in the point coordinate
|
* @param shift_ The number of fractional bits in the point coordinate
|
||||||
*/
|
*/
|
||||||
|
GAPI_WRAP
|
||||||
Poly(const std::vector<cv::Point>& points_,
|
Poly(const std::vector<cv::Point>& points_,
|
||||||
const cv::Scalar& color_,
|
const cv::Scalar& color_,
|
||||||
int thick_ = 1,
|
int thick_ = 1,
|
||||||
@@ -314,14 +325,15 @@ struct Poly
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GAPI_WRAP
|
||||||
Poly() = default;
|
Poly() = default;
|
||||||
|
|
||||||
/*@{*/
|
/*@{*/
|
||||||
std::vector<cv::Point> points; //!< Points to connect
|
GAPI_PROP_RW std::vector<cv::Point> points; //!< Points to connect
|
||||||
cv::Scalar color; //!< The line color
|
GAPI_PROP_RW cv::Scalar color; //!< The line color
|
||||||
int thick; //!< The thickness of line
|
GAPI_PROP_RW int thick; //!< The thickness of line
|
||||||
int lt; //!< The Type of the line. See #LineTypes
|
GAPI_PROP_RW int lt; //!< The Type of the line. See #LineTypes
|
||||||
int shift; //!< The number of fractional bits in the point coordinate
|
GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinate
|
||||||
/*@{*/
|
/*@{*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -336,7 +348,7 @@ using Prim = util::variant
|
|||||||
, Poly
|
, Poly
|
||||||
>;
|
>;
|
||||||
|
|
||||||
using Prims = std::vector<Prim>;
|
using Prims = std::vector<Prim>;
|
||||||
//! @} gapi_draw_prims
|
//! @} gapi_draw_prims
|
||||||
|
|
||||||
} // namespace draw
|
} // namespace draw
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
// of this distribution and at http://opencv.org/license.html.
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2020 Intel Corporation
|
// Copyright (C) 2020-2021 Intel Corporation
|
||||||
|
|
||||||
|
|
||||||
#ifndef OPENCV_GAPI_GSTREAMING_DESYNC_HPP
|
#ifndef OPENCV_GAPI_GSTREAMING_DESYNC_HPP
|
||||||
@@ -73,9 +73,10 @@ G desync(const G &g) {
|
|||||||
* which produces an array of cv::util::optional<> objects.
|
* which produces an array of cv::util::optional<> objects.
|
||||||
*
|
*
|
||||||
* @note This feature is highly experimental now and is currently
|
* @note This feature is highly experimental now and is currently
|
||||||
* limited to a single GMat argument only.
|
* limited to a single GMat/GFrame argument only.
|
||||||
*/
|
*/
|
||||||
GAPI_EXPORTS GMat desync(const GMat &g);
|
GAPI_EXPORTS GMat desync(const GMat &g);
|
||||||
|
GAPI_EXPORTS GFrame desync(const GFrame &f);
|
||||||
|
|
||||||
} // namespace streaming
|
} // namespace streaming
|
||||||
} // namespace gapi
|
} // namespace gapi
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ e.g when graph's input needs to be passed directly to output, like in Streaming
|
|||||||
@param in Input image
|
@param in Input image
|
||||||
@return Copy of the input
|
@return Copy of the input
|
||||||
*/
|
*/
|
||||||
GAPI_EXPORTS GMat copy(const GMat& in);
|
GAPI_EXPORTS_W GMat copy(const GMat& in);
|
||||||
|
|
||||||
/** @brief Makes a copy of the input frame. Note that this copy may be not real
|
/** @brief Makes a copy of the input frame. Note that this copy may be not real
|
||||||
(no actual data copied). Use this function to maintain graph contracts,
|
(no actual data copied). Use this function to maintain graph contracts,
|
||||||
|
|||||||
@@ -11,6 +11,36 @@ def register(mname):
|
|||||||
return parameterized
|
return parameterized
|
||||||
|
|
||||||
|
|
||||||
|
@register('cv2.gapi')
|
||||||
|
def networks(*args):
|
||||||
|
return cv.gapi_GNetPackage(list(map(cv.detail.strip, args)))
|
||||||
|
|
||||||
|
|
||||||
|
@register('cv2.gapi')
|
||||||
|
def compile_args(*args):
|
||||||
|
return list(map(cv.GCompileArg, args))
|
||||||
|
|
||||||
|
|
||||||
|
@register('cv2')
|
||||||
|
def GIn(*args):
|
||||||
|
return [*args]
|
||||||
|
|
||||||
|
|
||||||
|
@register('cv2')
|
||||||
|
def GOut(*args):
|
||||||
|
return [*args]
|
||||||
|
|
||||||
|
|
||||||
|
@register('cv2')
|
||||||
|
def gin(*args):
|
||||||
|
return [*args]
|
||||||
|
|
||||||
|
|
||||||
|
@register('cv2.gapi')
|
||||||
|
def descr_of(*args):
|
||||||
|
return [*args]
|
||||||
|
|
||||||
|
|
||||||
@register('cv2')
|
@register('cv2')
|
||||||
class GOpaque():
|
class GOpaque():
|
||||||
# NB: Inheritance from c++ class cause segfault.
|
# NB: Inheritance from c++ class cause segfault.
|
||||||
@@ -54,6 +84,10 @@ class GOpaque():
|
|||||||
def __new__(self):
|
def __new__(self):
|
||||||
return cv.GOpaqueT(cv.gapi.CV_RECT)
|
return cv.GOpaqueT(cv.gapi.CV_RECT)
|
||||||
|
|
||||||
|
class Prim():
|
||||||
|
def __new__(self):
|
||||||
|
return cv.GOpaqueT(cv.gapi.CV_DRAW_PRIM)
|
||||||
|
|
||||||
class Any():
|
class Any():
|
||||||
def __new__(self):
|
def __new__(self):
|
||||||
return cv.GOpaqueT(cv.gapi.CV_ANY)
|
return cv.GOpaqueT(cv.gapi.CV_ANY)
|
||||||
@@ -113,6 +147,10 @@ class GArray():
|
|||||||
def __new__(self):
|
def __new__(self):
|
||||||
return cv.GArrayT(cv.gapi.CV_GMAT)
|
return cv.GArrayT(cv.gapi.CV_GMAT)
|
||||||
|
|
||||||
|
class Prim():
|
||||||
|
def __new__(self):
|
||||||
|
return cv.GArray(cv.gapi.CV_DRAW_PRIM)
|
||||||
|
|
||||||
class Any():
|
class Any():
|
||||||
def __new__(self):
|
def __new__(self):
|
||||||
return cv.GArray(cv.gapi.CV_ANY)
|
return cv.GArray(cv.gapi.CV_ANY)
|
||||||
@@ -134,6 +172,7 @@ def op(op_id, in_types, out_types):
|
|||||||
cv.GArray.Scalar: cv.gapi.CV_SCALAR,
|
cv.GArray.Scalar: cv.gapi.CV_SCALAR,
|
||||||
cv.GArray.Mat: cv.gapi.CV_MAT,
|
cv.GArray.Mat: cv.gapi.CV_MAT,
|
||||||
cv.GArray.GMat: cv.gapi.CV_GMAT,
|
cv.GArray.GMat: cv.gapi.CV_GMAT,
|
||||||
|
cv.GArray.Prim: cv.gapi.CV_DRAW_PRIM,
|
||||||
cv.GArray.Any: cv.gapi.CV_ANY
|
cv.GArray.Any: cv.gapi.CV_ANY
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,22 +188,24 @@ def op(op_id, in_types, out_types):
|
|||||||
cv.GOpaque.Point2f: cv.gapi.CV_POINT2F,
|
cv.GOpaque.Point2f: cv.gapi.CV_POINT2F,
|
||||||
cv.GOpaque.Size: cv.gapi.CV_SIZE,
|
cv.GOpaque.Size: cv.gapi.CV_SIZE,
|
||||||
cv.GOpaque.Rect: cv.gapi.CV_RECT,
|
cv.GOpaque.Rect: cv.gapi.CV_RECT,
|
||||||
|
cv.GOpaque.Prim: cv.gapi.CV_DRAW_PRIM,
|
||||||
cv.GOpaque.Any: cv.gapi.CV_ANY
|
cv.GOpaque.Any: cv.gapi.CV_ANY
|
||||||
}
|
}
|
||||||
|
|
||||||
type2str = {
|
type2str = {
|
||||||
cv.gapi.CV_BOOL: 'cv.gapi.CV_BOOL' ,
|
cv.gapi.CV_BOOL: 'cv.gapi.CV_BOOL' ,
|
||||||
cv.gapi.CV_INT: 'cv.gapi.CV_INT' ,
|
cv.gapi.CV_INT: 'cv.gapi.CV_INT' ,
|
||||||
cv.gapi.CV_DOUBLE: 'cv.gapi.CV_DOUBLE' ,
|
cv.gapi.CV_DOUBLE: 'cv.gapi.CV_DOUBLE' ,
|
||||||
cv.gapi.CV_FLOAT: 'cv.gapi.CV_FLOAT' ,
|
cv.gapi.CV_FLOAT: 'cv.gapi.CV_FLOAT' ,
|
||||||
cv.gapi.CV_STRING: 'cv.gapi.CV_STRING' ,
|
cv.gapi.CV_STRING: 'cv.gapi.CV_STRING' ,
|
||||||
cv.gapi.CV_POINT: 'cv.gapi.CV_POINT' ,
|
cv.gapi.CV_POINT: 'cv.gapi.CV_POINT' ,
|
||||||
cv.gapi.CV_POINT2F: 'cv.gapi.CV_POINT2F' ,
|
cv.gapi.CV_POINT2F: 'cv.gapi.CV_POINT2F' ,
|
||||||
cv.gapi.CV_SIZE: 'cv.gapi.CV_SIZE',
|
cv.gapi.CV_SIZE: 'cv.gapi.CV_SIZE',
|
||||||
cv.gapi.CV_RECT: 'cv.gapi.CV_RECT',
|
cv.gapi.CV_RECT: 'cv.gapi.CV_RECT',
|
||||||
cv.gapi.CV_SCALAR: 'cv.gapi.CV_SCALAR',
|
cv.gapi.CV_SCALAR: 'cv.gapi.CV_SCALAR',
|
||||||
cv.gapi.CV_MAT: 'cv.gapi.CV_MAT',
|
cv.gapi.CV_MAT: 'cv.gapi.CV_MAT',
|
||||||
cv.gapi.CV_GMAT: 'cv.gapi.CV_GMAT'
|
cv.gapi.CV_GMAT: 'cv.gapi.CV_GMAT',
|
||||||
|
cv.gapi.CV_DRAW_PRIM: 'cv.gapi.CV_DRAW_PRIM'
|
||||||
}
|
}
|
||||||
|
|
||||||
# NB: Second lvl decorator takes class to decorate
|
# NB: Second lvl decorator takes class to decorate
|
||||||
@@ -244,3 +285,15 @@ def kernel(op_cls):
|
|||||||
return cls
|
return cls
|
||||||
|
|
||||||
return kernel_with_params
|
return kernel_with_params
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME: On the c++ side every class is placed in cv2 module.
|
||||||
|
cv.gapi.wip.draw.Rect = cv.gapi_wip_draw_Rect
|
||||||
|
cv.gapi.wip.draw.Text = cv.gapi_wip_draw_Text
|
||||||
|
cv.gapi.wip.draw.Circle = cv.gapi_wip_draw_Circle
|
||||||
|
cv.gapi.wip.draw.Line = cv.gapi_wip_draw_Line
|
||||||
|
cv.gapi.wip.draw.Mosaic = cv.gapi_wip_draw_Mosaic
|
||||||
|
cv.gapi.wip.draw.Image = cv.gapi_wip_draw_Image
|
||||||
|
cv.gapi.wip.draw.Poly = cv.gapi_wip_draw_Poly
|
||||||
|
|
||||||
|
cv.gapi.streaming.queue_capacity = cv.gapi_streaming_queue_capacity
|
||||||
|
|||||||
@@ -11,12 +11,14 @@
|
|||||||
#include <opencv2/gapi/python/python.hpp>
|
#include <opencv2/gapi/python/python.hpp>
|
||||||
|
|
||||||
// NB: Python wrapper replaces :: with _ for classes
|
// NB: Python wrapper replaces :: with _ for classes
|
||||||
using gapi_GKernelPackage = cv::gapi::GKernelPackage;
|
using gapi_GKernelPackage = cv::gapi::GKernelPackage;
|
||||||
using gapi_GNetPackage = cv::gapi::GNetPackage;
|
using gapi_GNetPackage = cv::gapi::GNetPackage;
|
||||||
using gapi_ie_PyParams = cv::gapi::ie::PyParams;
|
using gapi_ie_PyParams = cv::gapi::ie::PyParams;
|
||||||
using gapi_wip_IStreamSource_Ptr = cv::Ptr<cv::gapi::wip::IStreamSource>;
|
using gapi_wip_IStreamSource_Ptr = cv::Ptr<cv::gapi::wip::IStreamSource>;
|
||||||
using detail_ExtractArgsCallback = cv::detail::ExtractArgsCallback;
|
using detail_ExtractArgsCallback = cv::detail::ExtractArgsCallback;
|
||||||
using detail_ExtractMetaCallback = cv::detail::ExtractMetaCallback;
|
using detail_ExtractMetaCallback = cv::detail::ExtractMetaCallback;
|
||||||
|
using vector_GNetParam = std::vector<cv::gapi::GNetParam>;
|
||||||
|
using gapi_streaming_queue_capacity = cv::gapi::streaming::queue_capacity;
|
||||||
|
|
||||||
// NB: Python wrapper generate T_U for T<U>
|
// NB: Python wrapper generate T_U for T<U>
|
||||||
// This behavior is only observed for inputs
|
// This behavior is only observed for inputs
|
||||||
@@ -42,6 +44,7 @@ using GArray_Rect = cv::GArray<cv::Rect>;
|
|||||||
using GArray_Scalar = cv::GArray<cv::Scalar>;
|
using GArray_Scalar = cv::GArray<cv::Scalar>;
|
||||||
using GArray_Mat = cv::GArray<cv::Mat>;
|
using GArray_Mat = cv::GArray<cv::Mat>;
|
||||||
using GArray_GMat = cv::GArray<cv::GMat>;
|
using GArray_GMat = cv::GArray<cv::GMat>;
|
||||||
|
using GArray_Prim = cv::GArray<cv::gapi::wip::draw::Prim>;
|
||||||
|
|
||||||
// FIXME: Python wrapper generate code without namespace std,
|
// FIXME: Python wrapper generate code without namespace std,
|
||||||
// so it cause error: "string wasn't declared"
|
// so it cause error: "string wasn't declared"
|
||||||
@@ -124,6 +127,95 @@ PyObject* pyopencv_from(const cv::detail::PyObjectHolder& v)
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #FIXME: Is it possible to implement pyopencv_from/pyopencv_to for generic
|
||||||
|
// cv::variant<Types...> ?
|
||||||
|
template <>
|
||||||
|
PyObject* pyopencv_from(const cv::gapi::wip::draw::Prim& prim)
|
||||||
|
{
|
||||||
|
switch (prim.index())
|
||||||
|
{
|
||||||
|
case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Rect>():
|
||||||
|
return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Rect>(prim));
|
||||||
|
case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Text>():
|
||||||
|
return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Text>(prim));
|
||||||
|
case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Circle>():
|
||||||
|
return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Circle>(prim));
|
||||||
|
case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Line>():
|
||||||
|
return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Line>(prim));
|
||||||
|
case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Poly>():
|
||||||
|
return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Poly>(prim));
|
||||||
|
case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Mosaic>():
|
||||||
|
return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Mosaic>(prim));
|
||||||
|
case cv::gapi::wip::draw::Prim::index_of<cv::gapi::wip::draw::Image>():
|
||||||
|
return pyopencv_from(cv::util::get<cv::gapi::wip::draw::Image>(prim));
|
||||||
|
}
|
||||||
|
|
||||||
|
util::throw_error(std::logic_error("Unsupported draw primitive type"));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
PyObject* pyopencv_from(const cv::gapi::wip::draw::Prims& value)
|
||||||
|
{
|
||||||
|
return pyopencv_from_generic_vec(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prim& value, const ArgInfo&)
|
||||||
|
{
|
||||||
|
#define TRY_EXTRACT(Prim) \
|
||||||
|
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_gapi_wip_draw_##Prim##_TypePtr))) \
|
||||||
|
{ \
|
||||||
|
value = reinterpret_cast<pyopencv_gapi_wip_draw_##Prim##_t*>(obj)->v; \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
TRY_EXTRACT(Rect)
|
||||||
|
TRY_EXTRACT(Text)
|
||||||
|
TRY_EXTRACT(Circle)
|
||||||
|
TRY_EXTRACT(Line)
|
||||||
|
TRY_EXTRACT(Mosaic)
|
||||||
|
TRY_EXTRACT(Image)
|
||||||
|
TRY_EXTRACT(Poly)
|
||||||
|
#undef TRY_EXTRACT
|
||||||
|
|
||||||
|
failmsg("Unsupported primitive type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prims& value, const ArgInfo& info)
|
||||||
|
{
|
||||||
|
return pyopencv_to_generic_vec(obj, value, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool pyopencv_to(PyObject* obj, cv::GMetaArg& value, const ArgInfo&)
|
||||||
|
{
|
||||||
|
#define TRY_EXTRACT(Meta) \
|
||||||
|
if (PyObject_TypeCheck(obj, \
|
||||||
|
reinterpret_cast<PyTypeObject*>(pyopencv_##Meta##_TypePtr))) \
|
||||||
|
{ \
|
||||||
|
value = reinterpret_cast<pyopencv_##Meta##_t*>(obj)->v; \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
|
||||||
|
TRY_EXTRACT(GMatDesc)
|
||||||
|
TRY_EXTRACT(GScalarDesc)
|
||||||
|
TRY_EXTRACT(GArrayDesc)
|
||||||
|
TRY_EXTRACT(GOpaqueDesc)
|
||||||
|
#undef TRY_EXTRACT
|
||||||
|
|
||||||
|
failmsg("Unsupported cv::GMetaArg type");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool pyopencv_to(PyObject* obj, cv::GMetaArgs& value, const ArgInfo& info)
|
||||||
|
{
|
||||||
|
return pyopencv_to_generic_vec(obj, value, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
PyObject* pyopencv_from(const cv::GArg& value)
|
PyObject* pyopencv_from(const cv::GArg& value)
|
||||||
{
|
{
|
||||||
@@ -136,20 +228,21 @@ PyObject* pyopencv_from(const cv::GArg& value)
|
|||||||
#define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break
|
#define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break
|
||||||
switch (value.opaque_kind)
|
switch (value.opaque_kind)
|
||||||
{
|
{
|
||||||
HANDLE_CASE(BOOL, bool);
|
HANDLE_CASE(BOOL, bool);
|
||||||
HANDLE_CASE(INT, int);
|
HANDLE_CASE(INT, int);
|
||||||
HANDLE_CASE(DOUBLE, double);
|
HANDLE_CASE(INT64, int64_t);
|
||||||
HANDLE_CASE(FLOAT, float);
|
HANDLE_CASE(DOUBLE, double);
|
||||||
HANDLE_CASE(STRING, std::string);
|
HANDLE_CASE(FLOAT, float);
|
||||||
HANDLE_CASE(POINT, cv::Point);
|
HANDLE_CASE(STRING, std::string);
|
||||||
HANDLE_CASE(POINT2F, cv::Point2f);
|
HANDLE_CASE(POINT, cv::Point);
|
||||||
HANDLE_CASE(SIZE, cv::Size);
|
HANDLE_CASE(POINT2F, cv::Point2f);
|
||||||
HANDLE_CASE(RECT, cv::Rect);
|
HANDLE_CASE(SIZE, cv::Size);
|
||||||
HANDLE_CASE(SCALAR, cv::Scalar);
|
HANDLE_CASE(RECT, cv::Rect);
|
||||||
HANDLE_CASE(MAT, cv::Mat);
|
HANDLE_CASE(SCALAR, cv::Scalar);
|
||||||
HANDLE_CASE(UNKNOWN, cv::detail::PyObjectHolder);
|
HANDLE_CASE(MAT, cv::Mat);
|
||||||
|
HANDLE_CASE(UNKNOWN, cv::detail::PyObjectHolder);
|
||||||
|
HANDLE_CASE(DRAW_PRIM, cv::gapi::wip::draw::Prim);
|
||||||
UNSUPPORTED(UINT64);
|
UNSUPPORTED(UINT64);
|
||||||
UNSUPPORTED(DRAW_PRIM);
|
|
||||||
#undef HANDLE_CASE
|
#undef HANDLE_CASE
|
||||||
#undef UNSUPPORTED
|
#undef UNSUPPORTED
|
||||||
}
|
}
|
||||||
@@ -163,6 +256,18 @@ bool pyopencv_to(PyObject* obj, cv::GArg& value, const ArgInfo& info)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool pyopencv_to(PyObject* obj, std::vector<cv::gapi::GNetParam>& value, const ArgInfo& info)
|
||||||
|
{
|
||||||
|
return pyopencv_to_generic_vec(obj, value, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
PyObject* pyopencv_from(const std::vector<cv::gapi::GNetParam>& value)
|
||||||
|
{
|
||||||
|
return pyopencv_from_generic_vec(value);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
bool pyopencv_to(PyObject* obj, std::vector<GCompileArg>& value, const ArgInfo& info)
|
bool pyopencv_to(PyObject* obj, std::vector<GCompileArg>& value, const ArgInfo& info)
|
||||||
{
|
{
|
||||||
@@ -175,12 +280,6 @@ PyObject* pyopencv_from(const std::vector<GCompileArg>& value)
|
|||||||
return pyopencv_from_generic_vec(value);
|
return pyopencv_from_generic_vec(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
|
||||||
bool pyopencv_to(PyObject* obj, GRunArgs& value, const ArgInfo& info)
|
|
||||||
{
|
|
||||||
return pyopencv_to_generic_vec(obj, value, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
PyObject* pyopencv_from(const cv::detail::OpaqueRef& o)
|
PyObject* pyopencv_from(const cv::detail::OpaqueRef& o)
|
||||||
{
|
{
|
||||||
@@ -188,6 +287,7 @@ PyObject* pyopencv_from(const cv::detail::OpaqueRef& o)
|
|||||||
{
|
{
|
||||||
case cv::detail::OpaqueKind::CV_BOOL : return pyopencv_from(o.rref<bool>());
|
case cv::detail::OpaqueKind::CV_BOOL : return pyopencv_from(o.rref<bool>());
|
||||||
case cv::detail::OpaqueKind::CV_INT : return pyopencv_from(o.rref<int>());
|
case cv::detail::OpaqueKind::CV_INT : return pyopencv_from(o.rref<int>());
|
||||||
|
case cv::detail::OpaqueKind::CV_INT64 : return pyopencv_from(o.rref<int64_t>());
|
||||||
case cv::detail::OpaqueKind::CV_DOUBLE : return pyopencv_from(o.rref<double>());
|
case cv::detail::OpaqueKind::CV_DOUBLE : return pyopencv_from(o.rref<double>());
|
||||||
case cv::detail::OpaqueKind::CV_FLOAT : return pyopencv_from(o.rref<float>());
|
case cv::detail::OpaqueKind::CV_FLOAT : return pyopencv_from(o.rref<float>());
|
||||||
case cv::detail::OpaqueKind::CV_STRING : return pyopencv_from(o.rref<std::string>());
|
case cv::detail::OpaqueKind::CV_STRING : return pyopencv_from(o.rref<std::string>());
|
||||||
@@ -196,10 +296,10 @@ PyObject* pyopencv_from(const cv::detail::OpaqueRef& o)
|
|||||||
case cv::detail::OpaqueKind::CV_SIZE : return pyopencv_from(o.rref<cv::Size>());
|
case cv::detail::OpaqueKind::CV_SIZE : return pyopencv_from(o.rref<cv::Size>());
|
||||||
case cv::detail::OpaqueKind::CV_RECT : return pyopencv_from(o.rref<cv::Rect>());
|
case cv::detail::OpaqueKind::CV_RECT : return pyopencv_from(o.rref<cv::Rect>());
|
||||||
case cv::detail::OpaqueKind::CV_UNKNOWN : return pyopencv_from(o.rref<cv::GArg>());
|
case cv::detail::OpaqueKind::CV_UNKNOWN : return pyopencv_from(o.rref<cv::GArg>());
|
||||||
|
case cv::detail::OpaqueKind::CV_DRAW_PRIM : return pyopencv_from(o.rref<cv::gapi::wip::draw::Prim>());
|
||||||
case cv::detail::OpaqueKind::CV_UINT64 : break;
|
case cv::detail::OpaqueKind::CV_UINT64 : break;
|
||||||
case cv::detail::OpaqueKind::CV_SCALAR : break;
|
case cv::detail::OpaqueKind::CV_SCALAR : break;
|
||||||
case cv::detail::OpaqueKind::CV_MAT : break;
|
case cv::detail::OpaqueKind::CV_MAT : break;
|
||||||
case cv::detail::OpaqueKind::CV_DRAW_PRIM : break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyErr_SetString(PyExc_TypeError, "Unsupported GOpaque type");
|
PyErr_SetString(PyExc_TypeError, "Unsupported GOpaque type");
|
||||||
@@ -213,6 +313,7 @@ PyObject* pyopencv_from(const cv::detail::VectorRef& v)
|
|||||||
{
|
{
|
||||||
case cv::detail::OpaqueKind::CV_BOOL : return pyopencv_from_generic_vec(v.rref<bool>());
|
case cv::detail::OpaqueKind::CV_BOOL : return pyopencv_from_generic_vec(v.rref<bool>());
|
||||||
case cv::detail::OpaqueKind::CV_INT : return pyopencv_from_generic_vec(v.rref<int>());
|
case cv::detail::OpaqueKind::CV_INT : return pyopencv_from_generic_vec(v.rref<int>());
|
||||||
|
case cv::detail::OpaqueKind::CV_INT64 : return pyopencv_from_generic_vec(v.rref<int64_t>());
|
||||||
case cv::detail::OpaqueKind::CV_DOUBLE : return pyopencv_from_generic_vec(v.rref<double>());
|
case cv::detail::OpaqueKind::CV_DOUBLE : return pyopencv_from_generic_vec(v.rref<double>());
|
||||||
case cv::detail::OpaqueKind::CV_FLOAT : return pyopencv_from_generic_vec(v.rref<float>());
|
case cv::detail::OpaqueKind::CV_FLOAT : return pyopencv_from_generic_vec(v.rref<float>());
|
||||||
case cv::detail::OpaqueKind::CV_STRING : return pyopencv_from_generic_vec(v.rref<std::string>());
|
case cv::detail::OpaqueKind::CV_STRING : return pyopencv_from_generic_vec(v.rref<std::string>());
|
||||||
@@ -223,8 +324,8 @@ PyObject* pyopencv_from(const cv::detail::VectorRef& v)
|
|||||||
case cv::detail::OpaqueKind::CV_SCALAR : return pyopencv_from_generic_vec(v.rref<cv::Scalar>());
|
case cv::detail::OpaqueKind::CV_SCALAR : return pyopencv_from_generic_vec(v.rref<cv::Scalar>());
|
||||||
case cv::detail::OpaqueKind::CV_MAT : return pyopencv_from_generic_vec(v.rref<cv::Mat>());
|
case cv::detail::OpaqueKind::CV_MAT : return pyopencv_from_generic_vec(v.rref<cv::Mat>());
|
||||||
case cv::detail::OpaqueKind::CV_UNKNOWN : return pyopencv_from_generic_vec(v.rref<cv::GArg>());
|
case cv::detail::OpaqueKind::CV_UNKNOWN : return pyopencv_from_generic_vec(v.rref<cv::GArg>());
|
||||||
|
case cv::detail::OpaqueKind::CV_DRAW_PRIM : return pyopencv_from_generic_vec(v.rref<cv::gapi::wip::draw::Prim>());
|
||||||
case cv::detail::OpaqueKind::CV_UINT64 : break;
|
case cv::detail::OpaqueKind::CV_UINT64 : break;
|
||||||
case cv::detail::OpaqueKind::CV_DRAW_PRIM : break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyErr_SetString(PyExc_TypeError, "Unsupported GArray type");
|
PyErr_SetString(PyExc_TypeError, "Unsupported GArray type");
|
||||||
@@ -249,52 +350,69 @@ PyObject* pyopencv_from(const GRunArg& v)
|
|||||||
return pyopencv_from(util::get<cv::detail::OpaqueRef>(v));
|
return pyopencv_from(util::get<cv::detail::OpaqueRef>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs");
|
PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs. Index of variant is unknown");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
PyObject* pyopencv_from(const cv::optional<T>& opt)
|
||||||
|
{
|
||||||
|
if (!opt.has_value())
|
||||||
|
{
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
return pyopencv_from(*opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
PyObject* pyopencv_from(const GOptRunArg& v)
|
||||||
|
{
|
||||||
|
switch (v.index())
|
||||||
|
{
|
||||||
|
case GOptRunArg::index_of<cv::optional<cv::Mat>>():
|
||||||
|
return pyopencv_from(util::get<cv::optional<cv::Mat>>(v));
|
||||||
|
|
||||||
|
case GOptRunArg::index_of<cv::optional<cv::Scalar>>():
|
||||||
|
return pyopencv_from(util::get<cv::optional<cv::Scalar>>(v));
|
||||||
|
|
||||||
|
case GOptRunArg::index_of<optional<cv::detail::VectorRef>>():
|
||||||
|
return pyopencv_from(util::get<optional<cv::detail::VectorRef>>(v));
|
||||||
|
|
||||||
|
case GOptRunArg::index_of<optional<cv::detail::OpaqueRef>>():
|
||||||
|
return pyopencv_from(util::get<optional<cv::detail::OpaqueRef>>(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Failed to unpack GOptRunArg. Index of variant is unknown");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
PyObject* pyopencv_from(const GRunArgs& value)
|
PyObject* pyopencv_from(const GRunArgs& value)
|
||||||
{
|
{
|
||||||
size_t i, n = value.size();
|
return value.size() == 1 ? pyopencv_from(value[0]) : pyopencv_from_generic_vec(value);
|
||||||
|
|
||||||
// NB: It doesn't make sense to return list with a single element
|
|
||||||
if (n == 1)
|
|
||||||
{
|
|
||||||
PyObject* item = pyopencv_from(value[0]);
|
|
||||||
if(!item)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyObject* list = PyList_New(n);
|
|
||||||
for(i = 0; i < n; ++i)
|
|
||||||
{
|
|
||||||
PyObject* item = pyopencv_from(value[i]);
|
|
||||||
if(!item)
|
|
||||||
{
|
|
||||||
Py_DECREF(list);
|
|
||||||
PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
PyList_SetItem(list, i, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
bool pyopencv_to(PyObject* obj, GMetaArgs& value, const ArgInfo& info)
|
PyObject* pyopencv_from(const GOptRunArgs& value)
|
||||||
{
|
{
|
||||||
return pyopencv_to_generic_vec(obj, value, info);
|
return value.size() == 1 ? pyopencv_from(value[0]) : pyopencv_from_generic_vec(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
// FIXME: cv::variant should be wrapped once for all types.
|
||||||
PyObject* pyopencv_from(const GMetaArgs& value)
|
template <>
|
||||||
|
PyObject* pyopencv_from(const cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>& v)
|
||||||
{
|
{
|
||||||
return pyopencv_from_generic_vec(value);
|
using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
|
||||||
|
switch (v.index())
|
||||||
|
{
|
||||||
|
case RunArgs::index_of<cv::GRunArgs>():
|
||||||
|
return pyopencv_from(util::get<cv::GRunArgs>(v));
|
||||||
|
case RunArgs::index_of<cv::GOptRunArgs>():
|
||||||
|
return pyopencv_from(util::get<cv::GOptRunArgs>(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_SetString(PyExc_TypeError, "Failed to recognize kind of RunArgs. Index of variant is unknown");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@@ -318,16 +436,16 @@ void pyopencv_to_generic_vec_with_check(PyObject* from,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static PyObject* extract_proto_args(PyObject* py_args, PyObject* kw)
|
static T extract_proto_args(PyObject* py_args)
|
||||||
{
|
{
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
GProtoArgs args;
|
GProtoArgs args;
|
||||||
Py_ssize_t size = PyTuple_Size(py_args);
|
Py_ssize_t size = PyList_Size(py_args);
|
||||||
args.reserve(size);
|
args.reserve(size);
|
||||||
for (int i = 0; i < size; ++i)
|
for (int i = 0; i < size; ++i)
|
||||||
{
|
{
|
||||||
PyObject* item = PyTuple_GetItem(py_args, i);
|
PyObject* item = PyList_GetItem(py_args, i);
|
||||||
if (PyObject_TypeCheck(item, reinterpret_cast<PyTypeObject*>(pyopencv_GScalar_TypePtr)))
|
if (PyObject_TypeCheck(item, reinterpret_cast<PyTypeObject*>(pyopencv_GScalar_TypePtr)))
|
||||||
{
|
{
|
||||||
args.emplace_back(reinterpret_cast<pyopencv_GScalar_t*>(item)->v);
|
args.emplace_back(reinterpret_cast<pyopencv_GScalar_t*>(item)->v);
|
||||||
@@ -346,22 +464,11 @@ static PyObject* extract_proto_args(PyObject* py_args, PyObject* kw)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "Unsupported type for cv.GIn()/cv.GOut()");
|
util::throw_error(std::logic_error("Unsupported type for GProtoArgs"));
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pyopencv_from<T>(T{std::move(args)});
|
return T(std::move(args));
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject* pyopencv_cv_GIn(PyObject* , PyObject* py_args, PyObject* kw)
|
|
||||||
{
|
|
||||||
return extract_proto_args<GProtoInputArgs>(py_args, kw);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject* pyopencv_cv_GOut(PyObject* , PyObject* py_args, PyObject* kw)
|
|
||||||
{
|
|
||||||
return extract_proto_args<GProtoOutputArgs>(py_args, kw);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static cv::detail::OpaqueRef extract_opaque_ref(PyObject* from, cv::detail::OpaqueKind kind)
|
static cv::detail::OpaqueRef extract_opaque_ref(PyObject* from, cv::detail::OpaqueKind kind)
|
||||||
@@ -386,6 +493,7 @@ static cv::detail::OpaqueRef extract_opaque_ref(PyObject* from, cv::detail::Opaq
|
|||||||
HANDLE_CASE(RECT, cv::Rect);
|
HANDLE_CASE(RECT, cv::Rect);
|
||||||
HANDLE_CASE(UNKNOWN, cv::GArg);
|
HANDLE_CASE(UNKNOWN, cv::GArg);
|
||||||
UNSUPPORTED(UINT64);
|
UNSUPPORTED(UINT64);
|
||||||
|
UNSUPPORTED(INT64);
|
||||||
UNSUPPORTED(SCALAR);
|
UNSUPPORTED(SCALAR);
|
||||||
UNSUPPORTED(MAT);
|
UNSUPPORTED(MAT);
|
||||||
UNSUPPORTED(DRAW_PRIM);
|
UNSUPPORTED(DRAW_PRIM);
|
||||||
@@ -406,20 +514,21 @@ static cv::detail::VectorRef extract_vector_ref(PyObject* from, cv::detail::Opaq
|
|||||||
#define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break
|
#define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break
|
||||||
switch (kind)
|
switch (kind)
|
||||||
{
|
{
|
||||||
HANDLE_CASE(BOOL, bool);
|
HANDLE_CASE(BOOL, bool);
|
||||||
HANDLE_CASE(INT, int);
|
HANDLE_CASE(INT, int);
|
||||||
HANDLE_CASE(DOUBLE, double);
|
HANDLE_CASE(DOUBLE, double);
|
||||||
HANDLE_CASE(FLOAT, float);
|
HANDLE_CASE(FLOAT, float);
|
||||||
HANDLE_CASE(STRING, std::string);
|
HANDLE_CASE(STRING, std::string);
|
||||||
HANDLE_CASE(POINT, cv::Point);
|
HANDLE_CASE(POINT, cv::Point);
|
||||||
HANDLE_CASE(POINT2F, cv::Point2f);
|
HANDLE_CASE(POINT2F, cv::Point2f);
|
||||||
HANDLE_CASE(SIZE, cv::Size);
|
HANDLE_CASE(SIZE, cv::Size);
|
||||||
HANDLE_CASE(RECT, cv::Rect);
|
HANDLE_CASE(RECT, cv::Rect);
|
||||||
HANDLE_CASE(SCALAR, cv::Scalar);
|
HANDLE_CASE(SCALAR, cv::Scalar);
|
||||||
HANDLE_CASE(MAT, cv::Mat);
|
HANDLE_CASE(MAT, cv::Mat);
|
||||||
HANDLE_CASE(UNKNOWN, cv::GArg);
|
HANDLE_CASE(UNKNOWN, cv::GArg);
|
||||||
|
HANDLE_CASE(DRAW_PRIM, cv::gapi::wip::draw::Prim);
|
||||||
UNSUPPORTED(UINT64);
|
UNSUPPORTED(UINT64);
|
||||||
UNSUPPORTED(DRAW_PRIM);
|
UNSUPPORTED(INT64);
|
||||||
#undef HANDLE_CASE
|
#undef HANDLE_CASE
|
||||||
#undef UNSUPPORTED
|
#undef UNSUPPORTED
|
||||||
}
|
}
|
||||||
@@ -470,13 +579,15 @@ static cv::GRunArg extract_run_arg(const cv::GTypeInfo& info, PyObject* item)
|
|||||||
|
|
||||||
static cv::GRunArgs extract_run_args(const cv::GTypesInfo& info, PyObject* py_args)
|
static cv::GRunArgs extract_run_args(const cv::GTypesInfo& info, PyObject* py_args)
|
||||||
{
|
{
|
||||||
cv::GRunArgs args;
|
GAPI_Assert(PyList_Check(py_args));
|
||||||
Py_ssize_t tuple_size = PyTuple_Size(py_args);
|
|
||||||
args.reserve(tuple_size);
|
|
||||||
|
|
||||||
for (int i = 0; i < tuple_size; ++i)
|
cv::GRunArgs args;
|
||||||
|
Py_ssize_t list_size = PyList_Size(py_args);
|
||||||
|
args.reserve(list_size);
|
||||||
|
|
||||||
|
for (int i = 0; i < list_size; ++i)
|
||||||
{
|
{
|
||||||
args.push_back(extract_run_arg(info[i], PyTuple_GetItem(py_args, i)));
|
args.push_back(extract_run_arg(info[i], PyList_GetItem(py_args, i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
@@ -517,13 +628,15 @@ static cv::GMetaArg extract_meta_arg(const cv::GTypeInfo& info, PyObject* item)
|
|||||||
|
|
||||||
static cv::GMetaArgs extract_meta_args(const cv::GTypesInfo& info, PyObject* py_args)
|
static cv::GMetaArgs extract_meta_args(const cv::GTypesInfo& info, PyObject* py_args)
|
||||||
{
|
{
|
||||||
cv::GMetaArgs metas;
|
GAPI_Assert(PyList_Check(py_args));
|
||||||
Py_ssize_t tuple_size = PyTuple_Size(py_args);
|
|
||||||
metas.reserve(tuple_size);
|
|
||||||
|
|
||||||
for (int i = 0; i < tuple_size; ++i)
|
cv::GMetaArgs metas;
|
||||||
|
Py_ssize_t list_size = PyList_Size(py_args);
|
||||||
|
metas.reserve(list_size);
|
||||||
|
|
||||||
|
for (int i = 0; i < list_size; ++i)
|
||||||
{
|
{
|
||||||
metas.push_back(extract_meta_arg(info[i], PyTuple_GetItem(py_args, i)));
|
metas.push_back(extract_meta_arg(info[i], PyList_GetItem(py_args, i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return metas;
|
return metas;
|
||||||
@@ -581,7 +694,8 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel,
|
|||||||
cv::detail::PyObjectHolder result(
|
cv::detail::PyObjectHolder result(
|
||||||
PyObject_CallObject(kernel.get(), args.get()), false);
|
PyObject_CallObject(kernel.get(), args.get()), false);
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred())
|
||||||
|
{
|
||||||
PyErr_PrintEx(0);
|
PyErr_PrintEx(0);
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
throw std::logic_error("Python kernel failed with error!");
|
throw std::logic_error("Python kernel failed with error!");
|
||||||
@@ -589,8 +703,27 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel,
|
|||||||
// NB: In fact it's impossible situation, becase errors were handled above.
|
// NB: In fact it's impossible situation, becase errors were handled above.
|
||||||
GAPI_Assert(result.get() && "Python kernel returned NULL!");
|
GAPI_Assert(result.get() && "Python kernel returned NULL!");
|
||||||
|
|
||||||
outs = out_info.size() == 1 ? cv::GRunArgs{extract_run_arg(out_info[0], result.get())}
|
if (out_info.size() == 1)
|
||||||
: extract_run_args(out_info, result.get());
|
{
|
||||||
|
outs = cv::GRunArgs{extract_run_arg(out_info[0], result.get())};
|
||||||
|
}
|
||||||
|
else if (out_info.size() > 1)
|
||||||
|
{
|
||||||
|
GAPI_Assert(PyTuple_Check(result.get()));
|
||||||
|
|
||||||
|
Py_ssize_t tuple_size = PyTuple_Size(result.get());
|
||||||
|
outs.reserve(tuple_size);
|
||||||
|
|
||||||
|
for (int i = 0; i < tuple_size; ++i)
|
||||||
|
{
|
||||||
|
outs.push_back(extract_run_arg(out_info[i], PyTuple_GetItem(result.get(), i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Seems to be impossible case.
|
||||||
|
GAPI_Assert(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@@ -604,30 +737,12 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel,
|
|||||||
|
|
||||||
static GMetaArg get_meta_arg(PyObject* obj)
|
static GMetaArg get_meta_arg(PyObject* obj)
|
||||||
{
|
{
|
||||||
if (PyObject_TypeCheck(obj,
|
cv::GMetaArg arg;
|
||||||
reinterpret_cast<PyTypeObject*>(pyopencv_GMatDesc_TypePtr)))
|
if (!pyopencv_to(obj, arg, ArgInfo("arg", false)))
|
||||||
{
|
|
||||||
return cv::GMetaArg{reinterpret_cast<pyopencv_GMatDesc_t*>(obj)->v};
|
|
||||||
}
|
|
||||||
else if (PyObject_TypeCheck(obj,
|
|
||||||
reinterpret_cast<PyTypeObject*>(pyopencv_GScalarDesc_TypePtr)))
|
|
||||||
{
|
|
||||||
return cv::GMetaArg{reinterpret_cast<pyopencv_GScalarDesc_t*>(obj)->v};
|
|
||||||
}
|
|
||||||
else if (PyObject_TypeCheck(obj,
|
|
||||||
reinterpret_cast<PyTypeObject*>(pyopencv_GArrayDesc_TypePtr)))
|
|
||||||
{
|
|
||||||
return cv::GMetaArg{reinterpret_cast<pyopencv_GArrayDesc_t*>(obj)->v};
|
|
||||||
}
|
|
||||||
else if (PyObject_TypeCheck(obj,
|
|
||||||
reinterpret_cast<PyTypeObject*>(pyopencv_GOpaqueDesc_TypePtr)))
|
|
||||||
{
|
|
||||||
return cv::GMetaArg{reinterpret_cast<pyopencv_GOpaqueDesc_t*>(obj)->v};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
util::throw_error(std::logic_error("Unsupported output meta type"));
|
util::throw_error(std::logic_error("Unsupported output meta type"));
|
||||||
}
|
}
|
||||||
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cv::GMetaArgs get_meta_args(PyObject* tuple)
|
static cv::GMetaArgs get_meta_args(PyObject* tuple)
|
||||||
@@ -645,8 +760,9 @@ static cv::GMetaArgs get_meta_args(PyObject* tuple)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GMetaArgs run_py_meta(cv::detail::PyObjectHolder out_meta,
|
static GMetaArgs run_py_meta(cv::detail::PyObjectHolder out_meta,
|
||||||
const cv::GMetaArgs &meta,
|
const cv::GMetaArgs &meta,
|
||||||
const cv::GArgs &gargs) {
|
const cv::GArgs &gargs)
|
||||||
|
{
|
||||||
PyGILState_STATE gstate;
|
PyGILState_STATE gstate;
|
||||||
gstate = PyGILState_Ensure();
|
gstate = PyGILState_Ensure();
|
||||||
|
|
||||||
@@ -688,7 +804,8 @@ static GMetaArgs run_py_meta(cv::detail::PyObjectHolder out_meta,
|
|||||||
cv::detail::PyObjectHolder result(
|
cv::detail::PyObjectHolder result(
|
||||||
PyObject_CallObject(out_meta.get(), args.get()), false);
|
PyObject_CallObject(out_meta.get(), args.get()), false);
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
if (PyErr_Occurred())
|
||||||
|
{
|
||||||
PyErr_PrintEx(0);
|
PyErr_PrintEx(0);
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
throw std::logic_error("Python outMeta failed with error!");
|
throw std::logic_error("Python outMeta failed with error!");
|
||||||
@@ -720,21 +837,24 @@ static PyObject* pyopencv_cv_gapi_kernels(PyObject* , PyObject* py_args, PyObjec
|
|||||||
PyObject* user_kernel = PyTuple_GetItem(py_args, i);
|
PyObject* user_kernel = PyTuple_GetItem(py_args, i);
|
||||||
|
|
||||||
PyObject* id_obj = PyObject_GetAttrString(user_kernel, "id");
|
PyObject* id_obj = PyObject_GetAttrString(user_kernel, "id");
|
||||||
if (!id_obj) {
|
if (!id_obj)
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"Python kernel should contain id, please use cv.gapi.kernel to define kernel");
|
"Python kernel should contain id, please use cv.gapi.kernel to define kernel");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* out_meta = PyObject_GetAttrString(user_kernel, "outMeta");
|
PyObject* out_meta = PyObject_GetAttrString(user_kernel, "outMeta");
|
||||||
if (!out_meta) {
|
if (!out_meta)
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"Python kernel should contain outMeta, please use cv.gapi.kernel to define kernel");
|
"Python kernel should contain outMeta, please use cv.gapi.kernel to define kernel");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* run = PyObject_GetAttrString(user_kernel, "run");
|
PyObject* run = PyObject_GetAttrString(user_kernel, "run");
|
||||||
if (!run) {
|
if (!run)
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"Python kernel should contain run, please use cv.gapi.kernel to define kernel");
|
"Python kernel should contain run, please use cv.gapi.kernel to define kernel");
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -756,23 +876,6 @@ static PyObject* pyopencv_cv_gapi_kernels(PyObject* , PyObject* py_args, PyObjec
|
|||||||
return pyopencv_from(pkg);
|
return pyopencv_from(pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject* pyopencv_cv_gapi_networks(PyObject*, PyObject* py_args, PyObject*)
|
|
||||||
{
|
|
||||||
using namespace cv;
|
|
||||||
gapi::GNetPackage pkg;
|
|
||||||
Py_ssize_t size = PyTuple_Size(py_args);
|
|
||||||
for (int i = 0; i < size; ++i)
|
|
||||||
{
|
|
||||||
gapi_ie_PyParams params;
|
|
||||||
PyObject* item = PyTuple_GetItem(py_args, i);
|
|
||||||
if (pyopencv_to(item, params, ArgInfo("PyParams", false)))
|
|
||||||
{
|
|
||||||
pkg += gapi::networks(params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pyopencv_from(pkg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject* pyopencv_cv_gapi_op(PyObject* , PyObject* py_args, PyObject*)
|
static PyObject* pyopencv_cv_gapi_op(PyObject* , PyObject* py_args, PyObject*)
|
||||||
{
|
{
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
@@ -834,53 +937,54 @@ static PyObject* pyopencv_cv_gapi_op(PyObject* , PyObject* py_args, PyObject*)
|
|||||||
return pyopencv_from(cv::gapi::wip::op(id, outMetaWrapper, std::move(args)));
|
return pyopencv_from(cv::gapi::wip::op(id, outMetaWrapper, std::move(args)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject* pyopencv_cv_gin(PyObject*, PyObject* py_args, PyObject*)
|
template<>
|
||||||
|
bool pyopencv_to(PyObject* obj, cv::detail::ExtractArgsCallback& value, const ArgInfo&)
|
||||||
{
|
{
|
||||||
cv::detail::PyObjectHolder holder{py_args};
|
cv::detail::PyObjectHolder holder{obj};
|
||||||
auto callback = cv::detail::ExtractArgsCallback{[=](const cv::GTypesInfo& info)
|
value = cv::detail::ExtractArgsCallback{[=](const cv::GTypesInfo& info)
|
||||||
|
{
|
||||||
|
PyGILState_STATE gstate;
|
||||||
|
gstate = PyGILState_Ensure();
|
||||||
|
|
||||||
|
cv::GRunArgs args;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
args = extract_run_args(info, holder.get());
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
{
|
{
|
||||||
PyGILState_STATE gstate;
|
|
||||||
gstate = PyGILState_Ensure();
|
|
||||||
|
|
||||||
cv::GRunArgs args;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
args = extract_run_args(info, holder.get());
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
PyGILState_Release(gstate);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
PyGILState_Release(gstate);
|
PyGILState_Release(gstate);
|
||||||
return args;
|
throw;
|
||||||
}};
|
}
|
||||||
|
PyGILState_Release(gstate);
|
||||||
return pyopencv_from(callback);
|
return args;
|
||||||
|
}};
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject* pyopencv_cv_descr_of(PyObject*, PyObject* py_args, PyObject*)
|
template<>
|
||||||
|
bool pyopencv_to(PyObject* obj, cv::detail::ExtractMetaCallback& value, const ArgInfo&)
|
||||||
{
|
{
|
||||||
Py_INCREF(py_args);
|
cv::detail::PyObjectHolder holder{obj};
|
||||||
auto callback = cv::detail::ExtractMetaCallback{[=](const cv::GTypesInfo& info)
|
value = cv::detail::ExtractMetaCallback{[=](const cv::GTypesInfo& info)
|
||||||
{
|
{
|
||||||
PyGILState_STATE gstate;
|
PyGILState_STATE gstate;
|
||||||
gstate = PyGILState_Ensure();
|
gstate = PyGILState_Ensure();
|
||||||
|
|
||||||
cv::GMetaArgs args;
|
cv::GMetaArgs args;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
args = extract_meta_args(info, py_args);
|
args = extract_meta_args(info, holder.get());
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
PyGILState_Release(gstate);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
PyGILState_Release(gstate);
|
PyGILState_Release(gstate);
|
||||||
return args;
|
throw;
|
||||||
}};
|
}
|
||||||
return pyopencv_from(callback);
|
PyGILState_Release(gstate);
|
||||||
|
return args;
|
||||||
|
}};
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -895,9 +999,12 @@ struct PyOpenCV_Converter<cv::GArray<T>>
|
|||||||
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_GArrayT_TypePtr)))
|
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_GArrayT_TypePtr)))
|
||||||
{
|
{
|
||||||
auto& array = reinterpret_cast<pyopencv_GArrayT_t*>(obj)->v;
|
auto& array = reinterpret_cast<pyopencv_GArrayT_t*>(obj)->v;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
value = cv::util::get<cv::GArray<T>>(array.arg());
|
value = cv::util::get<cv::GArray<T>>(array.arg());
|
||||||
} catch (...) {
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -918,9 +1025,12 @@ struct PyOpenCV_Converter<cv::GOpaque<T>>
|
|||||||
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_GOpaqueT_TypePtr)))
|
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_GOpaqueT_TypePtr)))
|
||||||
{
|
{
|
||||||
auto& opaque = reinterpret_cast<pyopencv_GOpaqueT_t*>(obj)->v;
|
auto& opaque = reinterpret_cast<pyopencv_GOpaqueT_t*>(obj)->v;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
value = cv::util::get<cv::GOpaque<T>>(opaque.arg());
|
value = cv::util::get<cv::GOpaque<T>>(opaque.arg());
|
||||||
} catch (...) {
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -929,11 +1039,39 @@ struct PyOpenCV_Converter<cv::GOpaque<T>>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool pyopencv_to(PyObject* obj, cv::GProtoInputArgs& value, const ArgInfo& info)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value = extract_proto_args<cv::GProtoInputArgs>(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
failmsg("Can't parse cv::GProtoInputArgs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
bool pyopencv_to(PyObject* obj, cv::GProtoOutputArgs& value, const ArgInfo& info)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
value = extract_proto_args<cv::GProtoOutputArgs>(obj);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
failmsg("Can't parse cv::GProtoOutputArgs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// extend cv.gapi methods
|
// extend cv.gapi methods
|
||||||
#define PYOPENCV_EXTRA_METHODS_GAPI \
|
#define PYOPENCV_EXTRA_METHODS_GAPI \
|
||||||
{"kernels", CV_PY_FN_WITH_KW(pyopencv_cv_gapi_kernels), "kernels(...) -> GKernelPackage"}, \
|
{"kernels", CV_PY_FN_WITH_KW(pyopencv_cv_gapi_kernels), "kernels(...) -> GKernelPackage"}, \
|
||||||
{"networks", CV_PY_FN_WITH_KW(pyopencv_cv_gapi_networks), "networks(...) -> GNetPackage"}, \
|
|
||||||
{"__op", CV_PY_FN_WITH_KW(pyopencv_cv_gapi_op), "__op(...) -> retval\n"},
|
{"__op", CV_PY_FN_WITH_KW(pyopencv_cv_gapi_op), "__op(...) -> retval\n"},
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include <opencv2/gapi.hpp>
|
#include <opencv2/gapi.hpp>
|
||||||
#include <opencv2/gapi/garg.hpp>
|
#include <opencv2/gapi/garg.hpp>
|
||||||
#include <opencv2/gapi/gopaque.hpp>
|
#include <opencv2/gapi/gopaque.hpp>
|
||||||
|
#include <opencv2/gapi/render/render_types.hpp> // Prim
|
||||||
|
|
||||||
#define ID(T, E) T
|
#define ID(T, E) T
|
||||||
#define ID_(T, E) ID(T, E),
|
#define ID_(T, E) ID(T, E),
|
||||||
@@ -24,24 +25,29 @@
|
|||||||
GAPI_Assert(false && "Unsupported type"); \
|
GAPI_Assert(false && "Unsupported type"); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using cv::gapi::wip::draw::Prim;
|
||||||
|
|
||||||
#define GARRAY_TYPE_LIST_G(G, G2) \
|
#define GARRAY_TYPE_LIST_G(G, G2) \
|
||||||
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \
|
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \
|
||||||
WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \
|
WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \
|
||||||
WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \
|
WRAP_ARGS(int64_t , cv::gapi::ArgType::CV_INT64, G) \
|
||||||
WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \
|
WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \
|
||||||
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
|
WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \
|
||||||
WRAP_ARGS(cv::Point , cv::gapi::ArgType::CV_POINT, G) \
|
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
|
||||||
WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G) \
|
WRAP_ARGS(cv::Point , cv::gapi::ArgType::CV_POINT, G) \
|
||||||
WRAP_ARGS(cv::Size , cv::gapi::ArgType::CV_SIZE, G) \
|
WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G) \
|
||||||
WRAP_ARGS(cv::Rect , cv::gapi::ArgType::CV_RECT, G) \
|
WRAP_ARGS(cv::Size , cv::gapi::ArgType::CV_SIZE, G) \
|
||||||
WRAP_ARGS(cv::Scalar , cv::gapi::ArgType::CV_SCALAR, G) \
|
WRAP_ARGS(cv::Rect , cv::gapi::ArgType::CV_RECT, G) \
|
||||||
WRAP_ARGS(cv::Mat , cv::gapi::ArgType::CV_MAT, G) \
|
WRAP_ARGS(cv::Scalar , cv::gapi::ArgType::CV_SCALAR, G) \
|
||||||
WRAP_ARGS(cv::GArg , cv::gapi::ArgType::CV_ANY, G) \
|
WRAP_ARGS(cv::Mat , cv::gapi::ArgType::CV_MAT, G) \
|
||||||
WRAP_ARGS(cv::GMat , cv::gapi::ArgType::CV_GMAT, G2) \
|
WRAP_ARGS(Prim , cv::gapi::ArgType::CV_DRAW_PRIM, G) \
|
||||||
|
WRAP_ARGS(cv::GArg , cv::gapi::ArgType::CV_ANY, G) \
|
||||||
|
WRAP_ARGS(cv::GMat , cv::gapi::ArgType::CV_GMAT, G2) \
|
||||||
|
|
||||||
#define GOPAQUE_TYPE_LIST_G(G, G2) \
|
#define GOPAQUE_TYPE_LIST_G(G, G2) \
|
||||||
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \
|
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \
|
||||||
WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \
|
WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \
|
||||||
|
WRAP_ARGS(int64_t , cv::gapi::ArgType::CV_INT64, G) \
|
||||||
WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \
|
WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \
|
||||||
WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \
|
WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \
|
||||||
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
|
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
|
||||||
@@ -58,6 +64,7 @@ namespace gapi {
|
|||||||
enum ArgType {
|
enum ArgType {
|
||||||
CV_BOOL,
|
CV_BOOL,
|
||||||
CV_INT,
|
CV_INT,
|
||||||
|
CV_INT64,
|
||||||
CV_DOUBLE,
|
CV_DOUBLE,
|
||||||
CV_FLOAT,
|
CV_FLOAT,
|
||||||
CV_STRING,
|
CV_STRING,
|
||||||
@@ -68,6 +75,7 @@ enum ArgType {
|
|||||||
CV_SCALAR,
|
CV_SCALAR,
|
||||||
CV_MAT,
|
CV_MAT,
|
||||||
CV_GMAT,
|
CV_GMAT,
|
||||||
|
CV_DRAW_PRIM,
|
||||||
CV_ANY,
|
CV_ANY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,64 +3,81 @@
|
|||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
struct GAPI_EXPORTS_W_SIMPLE GCompileArg { };
|
struct GAPI_EXPORTS_W_SIMPLE GCompileArg
|
||||||
|
{
|
||||||
|
GAPI_WRAP GCompileArg(gapi::GKernelPackage arg);
|
||||||
|
GAPI_WRAP GCompileArg(gapi::GNetPackage arg);
|
||||||
|
GAPI_WRAP GCompileArg(gapi::streaming::queue_capacity arg);
|
||||||
|
};
|
||||||
|
|
||||||
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage pkg);
|
class GAPI_EXPORTS_W_SIMPLE GInferInputs
|
||||||
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GNetPackage pkg);
|
{
|
||||||
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage kernels, gapi::GNetPackage nets);
|
public:
|
||||||
|
GAPI_WRAP GInferInputs();
|
||||||
|
GAPI_WRAP GInferInputs& setInput(const std::string& name, const cv::GMat& value);
|
||||||
|
GAPI_WRAP GInferInputs& setInput(const std::string& name, const cv::GFrame& value);
|
||||||
|
};
|
||||||
|
|
||||||
// NB: This classes doesn't exist in *.so
|
class GAPI_EXPORTS_W_SIMPLE GInferListInputs
|
||||||
// HACK: Mark them as a class to force python wrapper generate code for this entities
|
{
|
||||||
class GAPI_EXPORTS_W_SIMPLE GProtoArg { };
|
public:
|
||||||
class GAPI_EXPORTS_W_SIMPLE GProtoInputArgs { };
|
GAPI_WRAP GInferListInputs();
|
||||||
class GAPI_EXPORTS_W_SIMPLE GProtoOutputArgs { };
|
GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray<cv::GMat>& value);
|
||||||
class GAPI_EXPORTS_W_SIMPLE GRunArg { };
|
GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray<cv::Rect>& value);
|
||||||
class GAPI_EXPORTS_W_SIMPLE GMetaArg { GAPI_WRAP GMetaArg(); };
|
};
|
||||||
|
|
||||||
using GProtoInputArgs = GIOProtoArgs<In_Tag>;
|
class GAPI_EXPORTS_W_SIMPLE GInferOutputs
|
||||||
using GProtoOutputArgs = GIOProtoArgs<Out_Tag>;
|
{
|
||||||
|
public:
|
||||||
|
GAPI_WRAP GInferOutputs();
|
||||||
|
GAPI_WRAP cv::GMat at(const std::string& name);
|
||||||
|
};
|
||||||
|
|
||||||
class GAPI_EXPORTS_W_SIMPLE GInferInputs
|
class GAPI_EXPORTS_W_SIMPLE GInferListOutputs
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GAPI_WRAP GInferInputs();
|
GAPI_WRAP GInferListOutputs();
|
||||||
GAPI_WRAP void setInput(const std::string& name, const cv::GMat& value);
|
GAPI_WRAP cv::GArray<cv::GMat> at(const std::string& name);
|
||||||
GAPI_WRAP void setInput(const std::string& name, const cv::GFrame& value);
|
};
|
||||||
};
|
|
||||||
|
|
||||||
class GAPI_EXPORTS_W_SIMPLE GInferListInputs
|
namespace gapi
|
||||||
{
|
{
|
||||||
public:
|
namespace wip
|
||||||
GAPI_WRAP GInferListInputs();
|
{
|
||||||
GAPI_WRAP void setInput(const std::string& name, const cv::GArray<cv::GMat>& value);
|
class GAPI_EXPORTS_W IStreamSource { };
|
||||||
GAPI_WRAP void setInput(const std::string& name, const cv::GArray<cv::Rect>& value);
|
namespace draw
|
||||||
};
|
{
|
||||||
|
// NB: These render primitives are partially wrapped in shadow file
|
||||||
|
// because cv::Rect conflicts with cv::gapi::wip::draw::Rect in python generator
|
||||||
|
// and cv::Rect2i breaks standalone mode.
|
||||||
|
struct Rect
|
||||||
|
{
|
||||||
|
GAPI_WRAP Rect(const cv::Rect2i& rect_,
|
||||||
|
const cv::Scalar& color_,
|
||||||
|
int thick_ = 1,
|
||||||
|
int lt_ = 8,
|
||||||
|
int shift_ = 0);
|
||||||
|
};
|
||||||
|
|
||||||
class GAPI_EXPORTS_W_SIMPLE GInferOutputs
|
struct Mosaic
|
||||||
{
|
{
|
||||||
public:
|
GAPI_WRAP Mosaic(const cv::Rect2i& mos_, int cellSz_, int decim_);
|
||||||
GAPI_WRAP GInferOutputs();
|
};
|
||||||
GAPI_WRAP cv::GMat at(const std::string& name);
|
} // namespace draw
|
||||||
};
|
} // namespace wip
|
||||||
|
namespace streaming
|
||||||
|
{
|
||||||
|
// FIXME: Extend to work with an arbitrary G-type.
|
||||||
|
cv::GOpaque<int64_t> GAPI_EXPORTS_W timestamp(cv::GMat);
|
||||||
|
cv::GOpaque<int64_t> GAPI_EXPORTS_W seqNo(cv::GMat);
|
||||||
|
cv::GOpaque<int64_t> GAPI_EXPORTS_W seq_id(cv::GMat);
|
||||||
|
|
||||||
class GAPI_EXPORTS_W_SIMPLE GInferListOutputs
|
GAPI_EXPORTS_W cv::GMat desync(const cv::GMat &g);
|
||||||
{
|
} // namespace streaming
|
||||||
public:
|
} // namespace gapi
|
||||||
GAPI_WRAP GInferListOutputs();
|
|
||||||
GAPI_WRAP cv::GArray<cv::GMat> at(const std::string& name);
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
struct GAPI_EXPORTS_W_SIMPLE ExtractArgsCallback { };
|
gapi::GNetParam GAPI_EXPORTS_W strip(gapi::ie::PyParams params);
|
||||||
struct GAPI_EXPORTS_W_SIMPLE ExtractMetaCallback { };
|
} // namespace detail
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
namespace gapi
|
|
||||||
{
|
|
||||||
namespace wip
|
|
||||||
{
|
|
||||||
class GAPI_EXPORTS_W IStreamSource { };
|
|
||||||
} // namespace wip
|
|
||||||
} // namespace gapi
|
|
||||||
} // namespace cv
|
} // namespace cv
|
||||||
|
|||||||
@@ -3,187 +3,209 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
from tests_common import NewOpenCVTests
|
from tests_common import NewOpenCVTests
|
||||||
|
|
||||||
|
|
||||||
# Plaidml is an optional backend
|
try:
|
||||||
pkgs = [
|
|
||||||
('ocl' , cv.gapi.core.ocl.kernels()),
|
if sys.version_info[:2] < (3, 0):
|
||||||
('cpu' , cv.gapi.core.cpu.kernels()),
|
raise unittest.SkipTest('Python 2.x is not supported')
|
||||||
('fluid' , cv.gapi.core.fluid.kernels())
|
|
||||||
# ('plaidml', cv.gapi.core.plaidml.kernels())
|
# Plaidml is an optional backend
|
||||||
]
|
pkgs = [
|
||||||
|
('ocl' , cv.gapi.core.ocl.kernels()),
|
||||||
|
('cpu' , cv.gapi.core.cpu.kernels()),
|
||||||
|
('fluid' , cv.gapi.core.fluid.kernels())
|
||||||
|
# ('plaidml', cv.gapi.core.plaidml.kernels())
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class gapi_core_test(NewOpenCVTests):
|
class gapi_core_test(NewOpenCVTests):
|
||||||
|
|
||||||
def test_add(self):
|
def test_add(self):
|
||||||
# TODO: Extend to use any type and size here
|
# TODO: Extend to use any type and size here
|
||||||
sz = (720, 1280)
|
sz = (720, 1280)
|
||||||
in1 = np.full(sz, 100)
|
in1 = np.full(sz, 100)
|
||||||
in2 = np.full(sz, 50)
|
in2 = np.full(sz, 50)
|
||||||
|
|
||||||
# OpenCV
|
# OpenCV
|
||||||
expected = cv.add(in1, in2)
|
expected = cv.add(in1, in2)
|
||||||
|
|
||||||
# G-API
|
# G-API
|
||||||
g_in1 = cv.GMat()
|
g_in1 = cv.GMat()
|
||||||
g_in2 = cv.GMat()
|
g_in2 = cv.GMat()
|
||||||
g_out = cv.gapi.add(g_in1, g_in2)
|
g_out = cv.gapi.add(g_in1, g_in2)
|
||||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||||
|
|
||||||
for pkg_name, pkg in pkgs:
|
for pkg_name, pkg in pkgs:
|
||||||
actual = comp.apply(cv.gin(in1, in2), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in1, in2), args=cv.gapi.compile_args(pkg))
|
||||||
# Comparison
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||||
'Failed on ' + pkg_name + ' backend')
|
|
||||||
self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend')
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_uint8(self):
|
|
||||||
sz = (720, 1280)
|
|
||||||
in1 = np.full(sz, 100, dtype=np.uint8)
|
|
||||||
in2 = np.full(sz, 50 , dtype=np.uint8)
|
|
||||||
|
|
||||||
# OpenCV
|
|
||||||
expected = cv.add(in1, in2)
|
|
||||||
|
|
||||||
# G-API
|
|
||||||
g_in1 = cv.GMat()
|
|
||||||
g_in2 = cv.GMat()
|
|
||||||
g_out = cv.gapi.add(g_in1, g_in2)
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
|
||||||
|
|
||||||
for pkg_name, pkg in pkgs:
|
|
||||||
actual = comp.apply(cv.gin(in1, in2), args=cv.compile_args(pkg))
|
|
||||||
# Comparison
|
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
|
||||||
'Failed on ' + pkg_name + ' backend')
|
|
||||||
self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend')
|
|
||||||
|
|
||||||
|
|
||||||
def test_mean(self):
|
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
|
||||||
in_mat = cv.imread(img_path)
|
|
||||||
|
|
||||||
# OpenCV
|
|
||||||
expected = cv.mean(in_mat)
|
|
||||||
|
|
||||||
# G-API
|
|
||||||
g_in = cv.GMat()
|
|
||||||
g_out = cv.gapi.mean(g_in)
|
|
||||||
comp = cv.GComputation(g_in, g_out)
|
|
||||||
|
|
||||||
for pkg_name, pkg in pkgs:
|
|
||||||
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
|
||||||
# Comparison
|
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
|
||||||
'Failed on ' + pkg_name + ' backend')
|
|
||||||
|
|
||||||
|
|
||||||
def test_split3(self):
|
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
|
||||||
in_mat = cv.imread(img_path)
|
|
||||||
|
|
||||||
# OpenCV
|
|
||||||
expected = cv.split(in_mat)
|
|
||||||
|
|
||||||
# G-API
|
|
||||||
g_in = cv.GMat()
|
|
||||||
b, g, r = cv.gapi.split3(g_in)
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r))
|
|
||||||
|
|
||||||
for pkg_name, pkg in pkgs:
|
|
||||||
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
|
||||||
# Comparison
|
|
||||||
for e, a in zip(expected, actual):
|
|
||||||
self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF),
|
|
||||||
'Failed on ' + pkg_name + ' backend')
|
'Failed on ' + pkg_name + ' backend')
|
||||||
self.assertEqual(e.dtype, a.dtype, 'Failed on ' + pkg_name + ' backend')
|
self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend')
|
||||||
|
|
||||||
|
|
||||||
def test_threshold(self):
|
def test_add_uint8(self):
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
sz = (720, 1280)
|
||||||
in_mat = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
|
in1 = np.full(sz, 100, dtype=np.uint8)
|
||||||
maxv = (30, 30)
|
in2 = np.full(sz, 50 , dtype=np.uint8)
|
||||||
|
|
||||||
# OpenCV
|
# OpenCV
|
||||||
expected_thresh, expected_mat = cv.threshold(in_mat, maxv[0], maxv[0], cv.THRESH_TRIANGLE)
|
expected = cv.add(in1, in2)
|
||||||
|
|
||||||
# G-API
|
# G-API
|
||||||
g_in = cv.GMat()
|
g_in1 = cv.GMat()
|
||||||
g_sc = cv.GScalar()
|
g_in2 = cv.GMat()
|
||||||
mat, threshold = cv.gapi.threshold(g_in, g_sc, cv.THRESH_TRIANGLE)
|
g_out = cv.gapi.add(g_in1, g_in2)
|
||||||
comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(mat, threshold))
|
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||||
|
|
||||||
for pkg_name, pkg in pkgs:
|
for pkg_name, pkg in pkgs:
|
||||||
actual_mat, actual_thresh = comp.apply(cv.gin(in_mat, maxv), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in1, in2), args=cv.gapi.compile_args(pkg))
|
||||||
# Comparison
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(expected_mat, actual_mat, cv.NORM_INF),
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||||
'Failed on ' + pkg_name + ' backend')
|
'Failed on ' + pkg_name + ' backend')
|
||||||
self.assertEqual(expected_mat.dtype, actual_mat.dtype,
|
self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend')
|
||||||
'Failed on ' + pkg_name + ' backend')
|
|
||||||
self.assertEqual(expected_thresh, actual_thresh[0],
|
|
||||||
'Failed on ' + pkg_name + ' backend')
|
|
||||||
|
|
||||||
def test_kmeans(self):
|
|
||||||
# K-means params
|
|
||||||
count = 100
|
|
||||||
sz = (count, 2)
|
|
||||||
in_mat = np.random.random(sz).astype(np.float32)
|
|
||||||
K = 5
|
|
||||||
flags = cv.KMEANS_RANDOM_CENTERS
|
|
||||||
attempts = 1;
|
|
||||||
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0)
|
|
||||||
|
|
||||||
# G-API
|
|
||||||
g_in = cv.GMat()
|
|
||||||
compactness, out_labels, centers = cv.gapi.kmeans(g_in, K, criteria, attempts, flags)
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(compactness, out_labels, centers))
|
|
||||||
|
|
||||||
compact, labels, centers = comp.apply(cv.gin(in_mat))
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
self.assertTrue(compact >= 0)
|
|
||||||
self.assertEqual(sz[0], labels.shape[0])
|
|
||||||
self.assertEqual(1, labels.shape[1])
|
|
||||||
self.assertTrue(labels.size != 0)
|
|
||||||
self.assertEqual(centers.shape[1], sz[1]);
|
|
||||||
self.assertEqual(centers.shape[0], K);
|
|
||||||
self.assertTrue(centers.size != 0);
|
|
||||||
|
|
||||||
|
|
||||||
def generate_random_points(self, sz):
|
def test_mean(self):
|
||||||
arr = np.random.random(sz).astype(np.float32).T
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
return list(zip(arr[0], arr[1]))
|
in_mat = cv.imread(img_path)
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
expected = cv.mean(in_mat)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
g_out = cv.gapi.mean(g_in)
|
||||||
|
comp = cv.GComputation(g_in, g_out)
|
||||||
|
|
||||||
|
for pkg_name, pkg in pkgs:
|
||||||
|
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||||
|
# Comparison
|
||||||
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||||
|
'Failed on ' + pkg_name + ' backend')
|
||||||
|
|
||||||
|
|
||||||
def test_kmeans_2d(self):
|
def test_split3(self):
|
||||||
# K-means 2D params
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
count = 100
|
in_mat = cv.imread(img_path)
|
||||||
sz = (count, 2)
|
|
||||||
amount = sz[0]
|
|
||||||
K = 5
|
|
||||||
flags = cv.KMEANS_RANDOM_CENTERS
|
|
||||||
attempts = 1;
|
|
||||||
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0);
|
|
||||||
in_vector = self.generate_random_points(sz)
|
|
||||||
in_labels = []
|
|
||||||
|
|
||||||
# G-API
|
# OpenCV
|
||||||
data = cv.GArrayT(cv.gapi.CV_POINT2F)
|
expected = cv.split(in_mat)
|
||||||
best_labels = cv.GArrayT(cv.gapi.CV_INT)
|
|
||||||
|
|
||||||
compactness, out_labels, centers = cv.gapi.kmeans(data, K, best_labels, criteria, attempts, flags);
|
# G-API
|
||||||
comp = cv.GComputation(cv.GIn(data, best_labels), cv.GOut(compactness, out_labels, centers));
|
g_in = cv.GMat()
|
||||||
|
b, g, r = cv.gapi.split3(g_in)
|
||||||
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r))
|
||||||
|
|
||||||
compact, labels, centers = comp.apply(cv.gin(in_vector, in_labels));
|
for pkg_name, pkg in pkgs:
|
||||||
|
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||||
|
# Comparison
|
||||||
|
for e, a in zip(expected, actual):
|
||||||
|
self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF),
|
||||||
|
'Failed on ' + pkg_name + ' backend')
|
||||||
|
self.assertEqual(e.dtype, a.dtype, 'Failed on ' + pkg_name + ' backend')
|
||||||
|
|
||||||
# Assert
|
|
||||||
self.assertTrue(compact >= 0)
|
def test_threshold(self):
|
||||||
self.assertEqual(amount, len(labels))
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
self.assertEqual(K, len(centers))
|
in_mat = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
|
||||||
|
maxv = (30, 30)
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
expected_thresh, expected_mat = cv.threshold(in_mat, maxv[0], maxv[0], cv.THRESH_TRIANGLE)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
g_sc = cv.GScalar()
|
||||||
|
mat, threshold = cv.gapi.threshold(g_in, g_sc, cv.THRESH_TRIANGLE)
|
||||||
|
comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(mat, threshold))
|
||||||
|
|
||||||
|
for pkg_name, pkg in pkgs:
|
||||||
|
actual_mat, actual_thresh = comp.apply(cv.gin(in_mat, maxv), args=cv.gapi.compile_args(pkg))
|
||||||
|
# Comparison
|
||||||
|
self.assertEqual(0.0, cv.norm(expected_mat, actual_mat, cv.NORM_INF),
|
||||||
|
'Failed on ' + pkg_name + ' backend')
|
||||||
|
self.assertEqual(expected_mat.dtype, actual_mat.dtype,
|
||||||
|
'Failed on ' + pkg_name + ' backend')
|
||||||
|
self.assertEqual(expected_thresh, actual_thresh[0],
|
||||||
|
'Failed on ' + pkg_name + ' backend')
|
||||||
|
|
||||||
|
|
||||||
|
def test_kmeans(self):
|
||||||
|
# K-means params
|
||||||
|
count = 100
|
||||||
|
sz = (count, 2)
|
||||||
|
in_mat = np.random.random(sz).astype(np.float32)
|
||||||
|
K = 5
|
||||||
|
flags = cv.KMEANS_RANDOM_CENTERS
|
||||||
|
attempts = 1
|
||||||
|
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
compactness, out_labels, centers = cv.gapi.kmeans(g_in, K, criteria, attempts, flags)
|
||||||
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(compactness, out_labels, centers))
|
||||||
|
|
||||||
|
compact, labels, centers = comp.apply(cv.gin(in_mat))
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertTrue(compact >= 0)
|
||||||
|
self.assertEqual(sz[0], labels.shape[0])
|
||||||
|
self.assertEqual(1, labels.shape[1])
|
||||||
|
self.assertTrue(labels.size != 0)
|
||||||
|
self.assertEqual(centers.shape[1], sz[1])
|
||||||
|
self.assertEqual(centers.shape[0], K)
|
||||||
|
self.assertTrue(centers.size != 0)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_random_points(self, sz):
|
||||||
|
arr = np.random.random(sz).astype(np.float32).T
|
||||||
|
return list(zip(arr[0], arr[1]))
|
||||||
|
|
||||||
|
|
||||||
|
def test_kmeans_2d(self):
|
||||||
|
# K-means 2D params
|
||||||
|
count = 100
|
||||||
|
sz = (count, 2)
|
||||||
|
amount = sz[0]
|
||||||
|
K = 5
|
||||||
|
flags = cv.KMEANS_RANDOM_CENTERS
|
||||||
|
attempts = 1
|
||||||
|
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0)
|
||||||
|
in_vector = self.generate_random_points(sz)
|
||||||
|
in_labels = []
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
data = cv.GArrayT(cv.gapi.CV_POINT2F)
|
||||||
|
best_labels = cv.GArrayT(cv.gapi.CV_INT)
|
||||||
|
|
||||||
|
compactness, out_labels, centers = cv.gapi.kmeans(data, K, best_labels, criteria, attempts, flags)
|
||||||
|
comp = cv.GComputation(cv.GIn(data, best_labels), cv.GOut(compactness, out_labels, centers))
|
||||||
|
|
||||||
|
compact, labels, centers = comp.apply(cv.gin(in_vector, in_labels))
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertTrue(compact >= 0)
|
||||||
|
self.assertEqual(amount, len(labels))
|
||||||
|
self.assertEqual(K, len(centers))
|
||||||
|
|
||||||
|
|
||||||
|
except unittest.SkipTest as e:
|
||||||
|
|
||||||
|
message = str(e)
|
||||||
|
|
||||||
|
class TestSkip(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.skipTest('Skip tests: ' + message)
|
||||||
|
|
||||||
|
def test_skip():
|
||||||
|
pass
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -3,103 +3,124 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
from tests_common import NewOpenCVTests
|
from tests_common import NewOpenCVTests
|
||||||
|
|
||||||
|
|
||||||
# Plaidml is an optional backend
|
try:
|
||||||
pkgs = [
|
|
||||||
('ocl' , cv.gapi.core.ocl.kernels()),
|
if sys.version_info[:2] < (3, 0):
|
||||||
('cpu' , cv.gapi.core.cpu.kernels()),
|
raise unittest.SkipTest('Python 2.x is not supported')
|
||||||
('fluid' , cv.gapi.core.fluid.kernels())
|
|
||||||
# ('plaidml', cv.gapi.core.plaidml.kernels())
|
# Plaidml is an optional backend
|
||||||
]
|
pkgs = [
|
||||||
|
('ocl' , cv.gapi.core.ocl.kernels()),
|
||||||
|
('cpu' , cv.gapi.core.cpu.kernels()),
|
||||||
|
('fluid' , cv.gapi.core.fluid.kernels())
|
||||||
|
# ('plaidml', cv.gapi.core.plaidml.kernels())
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class gapi_imgproc_test(NewOpenCVTests):
|
class gapi_imgproc_test(NewOpenCVTests):
|
||||||
|
|
||||||
def test_good_features_to_track(self):
|
def test_good_features_to_track(self):
|
||||||
# TODO: Extend to use any type and size here
|
# TODO: Extend to use any type and size here
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
in1 = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
|
in1 = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
|
||||||
|
|
||||||
# NB: goodFeaturesToTrack configuration
|
# NB: goodFeaturesToTrack configuration
|
||||||
max_corners = 50
|
max_corners = 50
|
||||||
quality_lvl = 0.01
|
quality_lvl = 0.01
|
||||||
min_distance = 10
|
min_distance = 10
|
||||||
block_sz = 3
|
block_sz = 3
|
||||||
use_harris_detector = True
|
use_harris_detector = True
|
||||||
k = 0.04
|
k = 0.04
|
||||||
mask = None
|
mask = None
|
||||||
|
|
||||||
# OpenCV
|
# OpenCV
|
||||||
expected = cv.goodFeaturesToTrack(in1, max_corners, quality_lvl,
|
expected = cv.goodFeaturesToTrack(in1, max_corners, quality_lvl,
|
||||||
min_distance, mask=mask,
|
min_distance, mask=mask,
|
||||||
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
|
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
|
||||||
|
|
||||||
# G-API
|
# G-API
|
||||||
g_in = cv.GMat()
|
g_in = cv.GMat()
|
||||||
g_out = cv.gapi.goodFeaturesToTrack(g_in, max_corners, quality_lvl,
|
g_out = cv.gapi.goodFeaturesToTrack(g_in, max_corners, quality_lvl,
|
||||||
min_distance, mask, block_sz, use_harris_detector, k)
|
min_distance, mask, block_sz, use_harris_detector, k)
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||||
|
|
||||||
for pkg_name, pkg in pkgs:
|
for pkg_name, pkg in pkgs:
|
||||||
actual = comp.apply(cv.gin(in1), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in1), args=cv.gapi.compile_args(pkg))
|
||||||
# NB: OpenCV & G-API have different output shapes:
|
# NB: OpenCV & G-API have different output shapes:
|
||||||
# OpenCV - (num_points, 1, 2)
|
# OpenCV - (num_points, 1, 2)
|
||||||
# G-API - (num_points, 2)
|
# G-API - (num_points, 2)
|
||||||
# Comparison
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(expected.flatten(),
|
self.assertEqual(0.0, cv.norm(expected.flatten(),
|
||||||
np.array(actual, dtype=np.float32).flatten(),
|
np.array(actual, dtype=np.float32).flatten(),
|
||||||
cv.NORM_INF),
|
cv.NORM_INF),
|
||||||
'Failed on ' + pkg_name + ' backend')
|
'Failed on ' + pkg_name + ' backend')
|
||||||
|
|
||||||
|
|
||||||
def test_rgb2gray(self):
|
def test_rgb2gray(self):
|
||||||
# TODO: Extend to use any type and size here
|
# TODO: Extend to use any type and size here
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
in1 = cv.imread(img_path)
|
in1 = cv.imread(img_path)
|
||||||
|
|
||||||
# OpenCV
|
# OpenCV
|
||||||
expected = cv.cvtColor(in1, cv.COLOR_RGB2GRAY)
|
expected = cv.cvtColor(in1, cv.COLOR_RGB2GRAY)
|
||||||
|
|
||||||
# G-API
|
# G-API
|
||||||
g_in = cv.GMat()
|
g_in = cv.GMat()
|
||||||
g_out = cv.gapi.RGB2Gray(g_in)
|
g_out = cv.gapi.RGB2Gray(g_in)
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||||
|
|
||||||
for pkg_name, pkg in pkgs:
|
for pkg_name, pkg in pkgs:
|
||||||
actual = comp.apply(cv.gin(in1), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in1), args=cv.gapi.compile_args(pkg))
|
||||||
# Comparison
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||||
'Failed on ' + pkg_name + ' backend')
|
'Failed on ' + pkg_name + ' backend')
|
||||||
|
|
||||||
|
|
||||||
def test_bounding_rect(self):
|
def test_bounding_rect(self):
|
||||||
sz = 1280
|
sz = 1280
|
||||||
fscale = 256
|
fscale = 256
|
||||||
|
|
||||||
def sample_value(fscale):
|
def sample_value(fscale):
|
||||||
return np.random.uniform(0, 255 * fscale) / fscale
|
return np.random.uniform(0, 255 * fscale) / fscale
|
||||||
|
|
||||||
points = np.array([(sample_value(fscale), sample_value(fscale)) for _ in range(1280)], np.float32)
|
points = np.array([(sample_value(fscale), sample_value(fscale)) for _ in range(1280)], np.float32)
|
||||||
|
|
||||||
# OpenCV
|
# OpenCV
|
||||||
expected = cv.boundingRect(points)
|
expected = cv.boundingRect(points)
|
||||||
|
|
||||||
# G-API
|
# G-API
|
||||||
g_in = cv.GMat()
|
g_in = cv.GMat()
|
||||||
g_out = cv.gapi.boundingRect(g_in)
|
g_out = cv.gapi.boundingRect(g_in)
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||||
|
|
||||||
for pkg_name, pkg in pkgs:
|
for pkg_name, pkg in pkgs:
|
||||||
actual = comp.apply(cv.gin(points), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(points), args=cv.gapi.compile_args(pkg))
|
||||||
# Comparison
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
|
||||||
'Failed on ' + pkg_name + ' backend')
|
'Failed on ' + pkg_name + ' backend')
|
||||||
|
|
||||||
|
|
||||||
|
except unittest.SkipTest as e:
|
||||||
|
|
||||||
|
message = str(e)
|
||||||
|
|
||||||
|
class TestSkip(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.skipTest('Skip tests: ' + message)
|
||||||
|
|
||||||
|
def test_skip():
|
||||||
|
pass
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -3,318 +3,338 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
from tests_common import NewOpenCVTests
|
from tests_common import NewOpenCVTests
|
||||||
|
|
||||||
|
|
||||||
class test_gapi_infer(NewOpenCVTests):
|
try:
|
||||||
|
|
||||||
def infer_reference_network(self, model_path, weights_path, img):
|
if sys.version_info[:2] < (3, 0):
|
||||||
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
raise unittest.SkipTest('Python 2.x is not supported')
|
||||||
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
|
||||||
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
|
||||||
|
|
||||||
blob = cv.dnn.blobFromImage(img)
|
|
||||||
|
|
||||||
net.setInput(blob)
|
|
||||||
return net.forward(net.getUnconnectedOutLayersNames())
|
|
||||||
|
|
||||||
|
|
||||||
def make_roi(self, img, roi):
|
class test_gapi_infer(NewOpenCVTests):
|
||||||
return img[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2], ...]
|
|
||||||
|
def infer_reference_network(self, model_path, weights_path, img):
|
||||||
|
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
||||||
|
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
||||||
|
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
||||||
|
|
||||||
|
blob = cv.dnn.blobFromImage(img)
|
||||||
|
|
||||||
|
net.setInput(blob)
|
||||||
|
return net.forward(net.getUnconnectedOutLayersNames())
|
||||||
|
|
||||||
|
|
||||||
def test_age_gender_infer(self):
|
def make_roi(self, img, roi):
|
||||||
# NB: Check IE
|
return img[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2], ...]
|
||||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
|
||||||
return
|
|
||||||
|
|
||||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
|
||||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
|
||||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
|
||||||
device_id = 'CPU'
|
|
||||||
|
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
|
||||||
img = cv.resize(cv.imread(img_path), (62,62))
|
|
||||||
|
|
||||||
# OpenCV DNN
|
|
||||||
dnn_age, dnn_gender = self.infer_reference_network(model_path, weights_path, img)
|
|
||||||
|
|
||||||
# OpenCV G-API
|
|
||||||
g_in = cv.GMat()
|
|
||||||
inputs = cv.GInferInputs()
|
|
||||||
inputs.setInput('data', g_in)
|
|
||||||
|
|
||||||
outputs = cv.gapi.infer("net", inputs)
|
|
||||||
age_g = outputs.at("age_conv3")
|
|
||||||
gender_g = outputs.at("prob")
|
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(age_g, gender_g))
|
|
||||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
|
||||||
|
|
||||||
gapi_age, gapi_gender = comp.apply(cv.gin(img), args=cv.compile_args(cv.gapi.networks(pp)))
|
|
||||||
|
|
||||||
# Check
|
|
||||||
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
|
||||||
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
|
||||||
|
|
||||||
|
|
||||||
def test_age_gender_infer_roi(self):
|
def test_age_gender_infer(self):
|
||||||
# NB: Check IE
|
# NB: Check IE
|
||||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||||
return
|
return
|
||||||
|
|
||||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
device_id = 'CPU'
|
device_id = 'CPU'
|
||||||
|
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
img = cv.imread(img_path)
|
img = cv.resize(cv.imread(img_path), (62,62))
|
||||||
roi = (10, 10, 62, 62)
|
|
||||||
|
|
||||||
# OpenCV DNN
|
# OpenCV DNN
|
||||||
dnn_age, dnn_gender = self.infer_reference_network(model_path,
|
dnn_age, dnn_gender = self.infer_reference_network(model_path, weights_path, img)
|
||||||
|
|
||||||
|
# OpenCV G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
inputs = cv.GInferInputs()
|
||||||
|
inputs.setInput('data', g_in)
|
||||||
|
|
||||||
|
outputs = cv.gapi.infer("net", inputs)
|
||||||
|
age_g = outputs.at("age_conv3")
|
||||||
|
gender_g = outputs.at("prob")
|
||||||
|
|
||||||
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(age_g, gender_g))
|
||||||
|
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||||
|
|
||||||
|
gapi_age, gapi_gender = comp.apply(cv.gin(img), args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||||
|
|
||||||
|
# Check
|
||||||
|
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
||||||
|
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
||||||
|
|
||||||
|
|
||||||
|
def test_age_gender_infer_roi(self):
|
||||||
|
# NB: Check IE
|
||||||
|
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||||
|
return
|
||||||
|
|
||||||
|
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||||
|
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
|
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
|
device_id = 'CPU'
|
||||||
|
|
||||||
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
|
img = cv.imread(img_path)
|
||||||
|
roi = (10, 10, 62, 62)
|
||||||
|
|
||||||
|
# OpenCV DNN
|
||||||
|
dnn_age, dnn_gender = self.infer_reference_network(model_path,
|
||||||
|
weights_path,
|
||||||
|
self.make_roi(img, roi))
|
||||||
|
|
||||||
|
# OpenCV G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
g_roi = cv.GOpaqueT(cv.gapi.CV_RECT)
|
||||||
|
inputs = cv.GInferInputs()
|
||||||
|
inputs.setInput('data', g_in)
|
||||||
|
|
||||||
|
outputs = cv.gapi.infer("net", g_roi, inputs)
|
||||||
|
age_g = outputs.at("age_conv3")
|
||||||
|
gender_g = outputs.at("prob")
|
||||||
|
|
||||||
|
comp = cv.GComputation(cv.GIn(g_in, g_roi), cv.GOut(age_g, gender_g))
|
||||||
|
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||||
|
|
||||||
|
gapi_age, gapi_gender = comp.apply(cv.gin(img, roi), args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||||
|
|
||||||
|
# Check
|
||||||
|
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
||||||
|
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
||||||
|
|
||||||
|
|
||||||
|
def test_age_gender_infer_roi_list(self):
|
||||||
|
# NB: Check IE
|
||||||
|
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||||
|
return
|
||||||
|
|
||||||
|
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||||
|
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
|
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
|
device_id = 'CPU'
|
||||||
|
|
||||||
|
rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)]
|
||||||
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
|
img = cv.imread(img_path)
|
||||||
|
|
||||||
|
# OpenCV DNN
|
||||||
|
dnn_age_list = []
|
||||||
|
dnn_gender_list = []
|
||||||
|
for roi in rois:
|
||||||
|
age, gender = self.infer_reference_network(model_path,
|
||||||
weights_path,
|
weights_path,
|
||||||
self.make_roi(img, roi))
|
self.make_roi(img, roi))
|
||||||
|
dnn_age_list.append(age)
|
||||||
|
dnn_gender_list.append(gender)
|
||||||
|
|
||||||
# OpenCV G-API
|
# OpenCV G-API
|
||||||
g_in = cv.GMat()
|
g_in = cv.GMat()
|
||||||
g_roi = cv.GOpaqueT(cv.gapi.CV_RECT)
|
g_rois = cv.GArrayT(cv.gapi.CV_RECT)
|
||||||
inputs = cv.GInferInputs()
|
inputs = cv.GInferInputs()
|
||||||
inputs.setInput('data', g_in)
|
inputs.setInput('data', g_in)
|
||||||
|
|
||||||
outputs = cv.gapi.infer("net", g_roi, inputs)
|
outputs = cv.gapi.infer("net", g_rois, inputs)
|
||||||
age_g = outputs.at("age_conv3")
|
age_g = outputs.at("age_conv3")
|
||||||
gender_g = outputs.at("prob")
|
gender_g = outputs.at("prob")
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in, g_roi), cv.GOut(age_g, gender_g))
|
comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g))
|
||||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||||
|
|
||||||
gapi_age, gapi_gender = comp.apply(cv.gin(img, roi), args=cv.compile_args(cv.gapi.networks(pp)))
|
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
|
||||||
|
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||||
|
|
||||||
# Check
|
# Check
|
||||||
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list,
|
||||||
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
gapi_gender_list,
|
||||||
|
dnn_age_list,
|
||||||
|
dnn_gender_list):
|
||||||
|
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
||||||
|
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
||||||
|
|
||||||
|
|
||||||
def test_age_gender_infer_roi_list(self):
|
def test_age_gender_infer2_roi(self):
|
||||||
# NB: Check IE
|
# NB: Check IE
|
||||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||||
return
|
return
|
||||||
|
|
||||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
||||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
device_id = 'CPU'
|
device_id = 'CPU'
|
||||||
|
|
||||||
rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)]
|
rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)]
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
img = cv.imread(img_path)
|
img = cv.imread(img_path)
|
||||||
|
|
||||||
# OpenCV DNN
|
# OpenCV DNN
|
||||||
dnn_age_list = []
|
dnn_age_list = []
|
||||||
dnn_gender_list = []
|
dnn_gender_list = []
|
||||||
for roi in rois:
|
for roi in rois:
|
||||||
age, gender = self.infer_reference_network(model_path,
|
age, gender = self.infer_reference_network(model_path,
|
||||||
weights_path,
|
weights_path,
|
||||||
self.make_roi(img, roi))
|
self.make_roi(img, roi))
|
||||||
dnn_age_list.append(age)
|
dnn_age_list.append(age)
|
||||||
dnn_gender_list.append(gender)
|
dnn_gender_list.append(gender)
|
||||||
|
|
||||||
# OpenCV G-API
|
# OpenCV G-API
|
||||||
g_in = cv.GMat()
|
g_in = cv.GMat()
|
||||||
g_rois = cv.GArrayT(cv.gapi.CV_RECT)
|
g_rois = cv.GArrayT(cv.gapi.CV_RECT)
|
||||||
inputs = cv.GInferInputs()
|
inputs = cv.GInferListInputs()
|
||||||
inputs.setInput('data', g_in)
|
inputs.setInput('data', g_rois)
|
||||||
|
|
||||||
outputs = cv.gapi.infer("net", g_rois, inputs)
|
outputs = cv.gapi.infer2("net", g_in, inputs)
|
||||||
age_g = outputs.at("age_conv3")
|
age_g = outputs.at("age_conv3")
|
||||||
gender_g = outputs.at("prob")
|
gender_g = outputs.at("prob")
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g))
|
comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g))
|
||||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||||
|
|
||||||
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
|
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
|
||||||
args=cv.compile_args(cv.gapi.networks(pp)))
|
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||||
|
|
||||||
# Check
|
# Check
|
||||||
for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list,
|
for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list,
|
||||||
gapi_gender_list,
|
gapi_gender_list,
|
||||||
dnn_age_list,
|
dnn_age_list,
|
||||||
dnn_gender_list):
|
dnn_gender_list):
|
||||||
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
||||||
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
||||||
|
|
||||||
|
|
||||||
def test_age_gender_infer2_roi(self):
|
|
||||||
# NB: Check IE
|
|
||||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
|
||||||
return
|
|
||||||
|
|
||||||
root_path = '/omz_intel_models/intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013'
|
|
||||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
|
||||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
|
||||||
device_id = 'CPU'
|
|
||||||
|
|
||||||
rois = [(10, 15, 62, 62), (23, 50, 62, 62), (14, 100, 62, 62), (80, 50, 62, 62)]
|
|
||||||
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
|
||||||
img = cv.imread(img_path)
|
|
||||||
|
|
||||||
# OpenCV DNN
|
|
||||||
dnn_age_list = []
|
|
||||||
dnn_gender_list = []
|
|
||||||
for roi in rois:
|
|
||||||
age, gender = self.infer_reference_network(model_path,
|
|
||||||
weights_path,
|
|
||||||
self.make_roi(img, roi))
|
|
||||||
dnn_age_list.append(age)
|
|
||||||
dnn_gender_list.append(gender)
|
|
||||||
|
|
||||||
# OpenCV G-API
|
|
||||||
g_in = cv.GMat()
|
|
||||||
g_rois = cv.GArrayT(cv.gapi.CV_RECT)
|
|
||||||
inputs = cv.GInferListInputs()
|
|
||||||
inputs.setInput('data', g_rois)
|
|
||||||
|
|
||||||
outputs = cv.gapi.infer2("net", g_in, inputs)
|
|
||||||
age_g = outputs.at("age_conv3")
|
|
||||||
gender_g = outputs.at("prob")
|
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in, g_rois), cv.GOut(age_g, gender_g))
|
|
||||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
|
||||||
|
|
||||||
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
|
|
||||||
args=cv.compile_args(cv.gapi.networks(pp)))
|
|
||||||
|
|
||||||
# Check
|
|
||||||
for gapi_age, gapi_gender, dnn_age, dnn_gender in zip(gapi_age_list,
|
|
||||||
gapi_gender_list,
|
|
||||||
dnn_age_list,
|
|
||||||
dnn_gender_list):
|
|
||||||
self.assertEqual(0.0, cv.norm(dnn_gender, gapi_gender, cv.NORM_INF))
|
|
||||||
self.assertEqual(0.0, cv.norm(dnn_age, gapi_age, cv.NORM_INF))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_person_detection_retail_0013(self):
|
def test_person_detection_retail_0013(self):
|
||||||
# NB: Check IE
|
# NB: Check IE
|
||||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||||
return
|
return
|
||||||
|
|
||||||
root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013'
|
root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013'
|
||||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
device_id = 'CPU'
|
device_id = 'CPU'
|
||||||
img = cv.resize(cv.imread(img_path), (544, 320))
|
img = cv.resize(cv.imread(img_path), (544, 320))
|
||||||
|
|
||||||
# OpenCV DNN
|
# OpenCV DNN
|
||||||
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
||||||
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
||||||
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
||||||
|
|
||||||
blob = cv.dnn.blobFromImage(img)
|
blob = cv.dnn.blobFromImage(img)
|
||||||
|
|
||||||
def parseSSD(detections, size):
|
def parseSSD(detections, size):
|
||||||
h, w = size
|
h, w = size
|
||||||
bboxes = []
|
bboxes = []
|
||||||
detections = detections.reshape(-1, 7)
|
detections = detections.reshape(-1, 7)
|
||||||
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
|
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
|
||||||
if confidence >= 0.5:
|
if confidence >= 0.5:
|
||||||
x = int(xmin * w)
|
x = int(xmin * w)
|
||||||
y = int(ymin * h)
|
y = int(ymin * h)
|
||||||
width = int(xmax * w - x)
|
width = int(xmax * w - x)
|
||||||
height = int(ymax * h - y)
|
height = int(ymax * h - y)
|
||||||
bboxes.append((x, y, width, height))
|
bboxes.append((x, y, width, height))
|
||||||
|
|
||||||
return bboxes
|
return bboxes
|
||||||
|
|
||||||
net.setInput(blob)
|
net.setInput(blob)
|
||||||
dnn_detections = net.forward()
|
dnn_detections = net.forward()
|
||||||
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
|
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
|
||||||
|
|
||||||
# OpenCV G-API
|
# OpenCV G-API
|
||||||
g_in = cv.GMat()
|
g_in = cv.GMat()
|
||||||
inputs = cv.GInferInputs()
|
inputs = cv.GInferInputs()
|
||||||
inputs.setInput('data', g_in)
|
inputs.setInput('data', g_in)
|
||||||
|
|
||||||
g_sz = cv.gapi.streaming.size(g_in)
|
g_sz = cv.gapi.streaming.size(g_in)
|
||||||
outputs = cv.gapi.infer("net", inputs)
|
outputs = cv.gapi.infer("net", inputs)
|
||||||
detections = outputs.at("detection_out")
|
detections = outputs.at("detection_out")
|
||||||
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
|
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
|
||||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||||
|
|
||||||
gapi_age, gapi_gender = comp.apply(cv.gin(img), args=cv.compile_args(cv.gapi.networks(pp)))
|
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
|
||||||
|
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||||
|
|
||||||
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
|
# Comparison
|
||||||
args=cv.compile_args(cv.gapi.networks(pp)))
|
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
|
||||||
|
np.array(gapi_boxes).flatten(),
|
||||||
# Comparison
|
cv.NORM_INF))
|
||||||
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
|
|
||||||
np.array(gapi_boxes).flatten(),
|
|
||||||
cv.NORM_INF))
|
|
||||||
|
|
||||||
|
|
||||||
def test_person_detection_retail_0013(self):
|
def test_person_detection_retail_0013(self):
|
||||||
# NB: Check IE
|
# NB: Check IE
|
||||||
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
|
||||||
return
|
return
|
||||||
|
|
||||||
root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013'
|
root_path = '/omz_intel_models/intel/person-detection-retail-0013/FP32/person-detection-retail-0013'
|
||||||
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
model_path = self.find_file(root_path + '.xml', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
weights_path = self.find_file(root_path + '.bin', [os.environ.get('OPENCV_DNN_TEST_DATA_PATH')])
|
||||||
img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
img_path = self.find_file('gpu/lbpcascade/er.png', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
device_id = 'CPU'
|
device_id = 'CPU'
|
||||||
img = cv.resize(cv.imread(img_path), (544, 320))
|
img = cv.resize(cv.imread(img_path), (544, 320))
|
||||||
|
|
||||||
# OpenCV DNN
|
# OpenCV DNN
|
||||||
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
|
||||||
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
|
||||||
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
|
||||||
|
|
||||||
blob = cv.dnn.blobFromImage(img)
|
blob = cv.dnn.blobFromImage(img)
|
||||||
|
|
||||||
def parseSSD(detections, size):
|
def parseSSD(detections, size):
|
||||||
h, w = size
|
h, w = size
|
||||||
bboxes = []
|
bboxes = []
|
||||||
detections = detections.reshape(-1, 7)
|
detections = detections.reshape(-1, 7)
|
||||||
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
|
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
|
||||||
if confidence >= 0.5:
|
if confidence >= 0.5:
|
||||||
x = int(xmin * w)
|
x = int(xmin * w)
|
||||||
y = int(ymin * h)
|
y = int(ymin * h)
|
||||||
width = int(xmax * w - x)
|
width = int(xmax * w - x)
|
||||||
height = int(ymax * h - y)
|
height = int(ymax * h - y)
|
||||||
bboxes.append((x, y, width, height))
|
bboxes.append((x, y, width, height))
|
||||||
|
|
||||||
return bboxes
|
return bboxes
|
||||||
|
|
||||||
net.setInput(blob)
|
net.setInput(blob)
|
||||||
dnn_detections = net.forward()
|
dnn_detections = net.forward()
|
||||||
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
|
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
|
||||||
|
|
||||||
# OpenCV G-API
|
# OpenCV G-API
|
||||||
g_in = cv.GMat()
|
g_in = cv.GMat()
|
||||||
inputs = cv.GInferInputs()
|
inputs = cv.GInferInputs()
|
||||||
inputs.setInput('data', g_in)
|
inputs.setInput('data', g_in)
|
||||||
|
|
||||||
g_sz = cv.gapi.streaming.size(g_in)
|
g_sz = cv.gapi.streaming.size(g_in)
|
||||||
outputs = cv.gapi.infer("net", inputs)
|
outputs = cv.gapi.infer("net", inputs)
|
||||||
detections = outputs.at("detection_out")
|
detections = outputs.at("detection_out")
|
||||||
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
|
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
|
||||||
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
|
||||||
|
|
||||||
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
|
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
|
||||||
args=cv.compile_args(cv.gapi.networks(pp)))
|
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
|
||||||
|
|
||||||
# Comparison
|
# Comparison
|
||||||
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
|
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
|
||||||
np.array(gapi_boxes).flatten(),
|
np.array(gapi_boxes).flatten(),
|
||||||
cv.NORM_INF))
|
cv.NORM_INF))
|
||||||
|
|
||||||
|
|
||||||
|
except unittest.SkipTest as e:
|
||||||
|
|
||||||
|
message = str(e)
|
||||||
|
|
||||||
|
class TestSkip(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.skipTest('Skip tests: ' + message)
|
||||||
|
|
||||||
|
def test_skip():
|
||||||
|
pass
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -0,0 +1,227 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
import cv2 as cv
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from tests_common import NewOpenCVTests
|
||||||
|
|
||||||
|
try:
|
||||||
|
|
||||||
|
if sys.version_info[:2] < (3, 0):
|
||||||
|
raise unittest.SkipTest('Python 2.x is not supported')
|
||||||
|
|
||||||
|
# FIXME: FText isn't supported yet.
|
||||||
|
class gapi_render_test(NewOpenCVTests):
|
||||||
|
def __init__(self, *args):
|
||||||
|
super().__init__(*args)
|
||||||
|
|
||||||
|
self.size = (300, 300, 3)
|
||||||
|
|
||||||
|
# Rect
|
||||||
|
self.rect = (30, 30, 50, 50)
|
||||||
|
self.rcolor = (0, 255, 0)
|
||||||
|
self.rlt = cv.LINE_4
|
||||||
|
self.rthick = 2
|
||||||
|
self.rshift = 3
|
||||||
|
|
||||||
|
# Text
|
||||||
|
self.text = 'Hello, world!'
|
||||||
|
self.org = (100, 100)
|
||||||
|
self.ff = cv.FONT_HERSHEY_SIMPLEX
|
||||||
|
self.fs = 1.0
|
||||||
|
self.tthick = 2
|
||||||
|
self.tlt = cv.LINE_8
|
||||||
|
self.tcolor = (255, 255, 255)
|
||||||
|
self.blo = False
|
||||||
|
|
||||||
|
# Circle
|
||||||
|
self.center = (200, 200)
|
||||||
|
self.radius = 200
|
||||||
|
self.ccolor = (255, 255, 0)
|
||||||
|
self.cthick = 2
|
||||||
|
self.clt = cv.LINE_4
|
||||||
|
self.cshift = 1
|
||||||
|
|
||||||
|
# Line
|
||||||
|
self.pt1 = (50, 50)
|
||||||
|
self.pt2 = (200, 200)
|
||||||
|
self.lcolor = (0, 255, 128)
|
||||||
|
self.lthick = 5
|
||||||
|
self.llt = cv.LINE_8
|
||||||
|
self.lshift = 2
|
||||||
|
|
||||||
|
# Poly
|
||||||
|
self.pts = [(50, 100), (100, 200), (25, 250)]
|
||||||
|
self.pcolor = (0, 0, 255)
|
||||||
|
self.pthick = 3
|
||||||
|
self.plt = cv.LINE_4
|
||||||
|
self.pshift = 1
|
||||||
|
|
||||||
|
# Image
|
||||||
|
self.iorg = (150, 150)
|
||||||
|
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
|
||||||
|
self.img = cv.resize(cv.imread(img_path), (50, 50))
|
||||||
|
self.alpha = np.full(self.img.shape[:2], 0.8, dtype=np.float32)
|
||||||
|
|
||||||
|
# Mosaic
|
||||||
|
self.mos = (100, 100, 100, 100)
|
||||||
|
self.cell_sz = 25
|
||||||
|
self.decim = 0
|
||||||
|
|
||||||
|
# Render primitives
|
||||||
|
self.prims = [cv.gapi.wip.draw.Rect(self.rect, self.rcolor, self.rthick, self.rlt, self.rshift),
|
||||||
|
cv.gapi.wip.draw.Text(self.text, self.org, self.ff, self.fs, self.tcolor, self.tthick, self.tlt, self.blo),
|
||||||
|
cv.gapi.wip.draw.Circle(self.center, self.radius, self.ccolor, self.cthick, self.clt, self.cshift),
|
||||||
|
cv.gapi.wip.draw.Line(self.pt1, self.pt2, self.lcolor, self.lthick, self.llt, self.lshift),
|
||||||
|
cv.gapi.wip.draw.Mosaic(self.mos, self.cell_sz, self.decim),
|
||||||
|
cv.gapi.wip.draw.Image(self.iorg, self.img, self.alpha),
|
||||||
|
cv.gapi.wip.draw.Poly(self.pts, self.pcolor, self.pthick, self.plt, self.pshift)]
|
||||||
|
|
||||||
|
def cvt_nv12_to_yuv(self, y, uv):
|
||||||
|
h,w,_ = uv.shape
|
||||||
|
upsample_uv = cv.resize(uv, (h * 2, w * 2))
|
||||||
|
return cv.merge([y, upsample_uv])
|
||||||
|
|
||||||
|
def cvt_yuv_to_nv12(self, yuv, y_out, uv_out):
|
||||||
|
chs = cv.split(yuv, [y_out, None, None])
|
||||||
|
uv = cv.merge([chs[1], chs[2]])
|
||||||
|
uv_out = cv.resize(uv, (uv.shape[0] // 2, uv.shape[1] // 2), dst=uv_out)
|
||||||
|
return y_out, uv_out
|
||||||
|
|
||||||
|
def cvt_bgr_to_yuv_color(self, bgr):
|
||||||
|
y = bgr[2] * 0.299000 + bgr[1] * 0.587000 + bgr[0] * 0.114000;
|
||||||
|
u = bgr[2] * -0.168736 + bgr[1] * -0.331264 + bgr[0] * 0.500000 + 128;
|
||||||
|
v = bgr[2] * 0.500000 + bgr[1] * -0.418688 + bgr[0] * -0.081312 + 128;
|
||||||
|
return (y, u, v)
|
||||||
|
|
||||||
|
def blend_img(self, background, org, img, alpha):
|
||||||
|
x, y = org
|
||||||
|
h, w, _ = img.shape
|
||||||
|
roi_img = background[x:x+w, y:y+h, :]
|
||||||
|
img32f_w = cv.merge([alpha] * 3).astype(np.float32)
|
||||||
|
roi32f_w = np.full(roi_img.shape, 1.0, dtype=np.float32)
|
||||||
|
roi32f_w -= img32f_w
|
||||||
|
img32f = (img / 255).astype(np.float32)
|
||||||
|
roi32f = (roi_img / 255).astype(np.float32)
|
||||||
|
cv.multiply(img32f, img32f_w, dst=img32f)
|
||||||
|
cv.multiply(roi32f, roi32f_w, dst=roi32f)
|
||||||
|
roi32f += img32f
|
||||||
|
roi_img[...] = np.round(roi32f * 255)
|
||||||
|
|
||||||
|
# This is quite naive implementations used as a simple reference
|
||||||
|
# doesn't consider corner cases.
|
||||||
|
def draw_mosaic(self, img, mos, cell_sz, decim):
|
||||||
|
x,y,w,h = mos
|
||||||
|
mosaic_area = img[x:x+w, y:y+h, :]
|
||||||
|
for i in range(0, mosaic_area.shape[0], cell_sz):
|
||||||
|
for j in range(0, mosaic_area.shape[1], cell_sz):
|
||||||
|
cell_roi = mosaic_area[j:j+cell_sz, i:i+cell_sz, :]
|
||||||
|
s0, s1, s2 = cv.mean(cell_roi)[:3]
|
||||||
|
mosaic_area[j:j+cell_sz, i:i+cell_sz] = (round(s0), round(s1), round(s2))
|
||||||
|
|
||||||
|
def render_primitives_bgr_ref(self, img):
|
||||||
|
cv.rectangle(img, self.rect, self.rcolor, self.rthick, self.rlt, self.rshift)
|
||||||
|
cv.putText(img, self.text, self.org, self.ff, self.fs, self.tcolor, self.tthick, self.tlt, self.blo)
|
||||||
|
cv.circle(img, self.center, self.radius, self.ccolor, self.cthick, self.clt, self.cshift)
|
||||||
|
cv.line(img, self.pt1, self.pt2, self.lcolor, self.lthick, self.llt, self.lshift)
|
||||||
|
cv.fillPoly(img, np.expand_dims(np.array([self.pts]), axis=0), self.pcolor, self.plt, self.pshift)
|
||||||
|
self.draw_mosaic(img, self.mos, self.cell_sz, self.decim)
|
||||||
|
self.blend_img(img, self.iorg, self.img, self.alpha)
|
||||||
|
|
||||||
|
def render_primitives_nv12_ref(self, y_plane, uv_plane):
|
||||||
|
yuv = self.cvt_nv12_to_yuv(y_plane, uv_plane)
|
||||||
|
cv.rectangle(yuv, self.rect, self.cvt_bgr_to_yuv_color(self.rcolor), self.rthick, self.rlt, self.rshift)
|
||||||
|
cv.putText(yuv, self.text, self.org, self.ff, self.fs, self.cvt_bgr_to_yuv_color(self.tcolor), self.tthick, self.tlt, self.blo)
|
||||||
|
cv.circle(yuv, self.center, self.radius, self.cvt_bgr_to_yuv_color(self.ccolor), self.cthick, self.clt, self.cshift)
|
||||||
|
cv.line(yuv, self.pt1, self.pt2, self.cvt_bgr_to_yuv_color(self.lcolor), self.lthick, self.llt, self.lshift)
|
||||||
|
cv.fillPoly(yuv, np.expand_dims(np.array([self.pts]), axis=0), self.cvt_bgr_to_yuv_color(self.pcolor), self.plt, self.pshift)
|
||||||
|
self.draw_mosaic(yuv, self.mos, self.cell_sz, self.decim)
|
||||||
|
self.blend_img(yuv, self.iorg, cv.cvtColor(self.img, cv.COLOR_BGR2YUV), self.alpha)
|
||||||
|
self.cvt_yuv_to_nv12(yuv, y_plane, uv_plane)
|
||||||
|
|
||||||
|
def test_render_primitives_on_bgr_graph(self):
|
||||||
|
expected = np.zeros(self.size, dtype=np.uint8)
|
||||||
|
actual = np.array(expected, copy=True)
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
self.render_primitives_bgr_ref(expected)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
g_prims = cv.GArray.Prim()
|
||||||
|
g_out = cv.gapi.wip.draw.render3ch(g_in, g_prims)
|
||||||
|
|
||||||
|
|
||||||
|
comp = cv.GComputation(cv.GIn(g_in, g_prims), cv.GOut(g_out))
|
||||||
|
actual = comp.apply(cv.gin(actual, self.prims))
|
||||||
|
|
||||||
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|
||||||
|
def test_render_primitives_on_bgr_function(self):
|
||||||
|
expected = np.zeros(self.size, dtype=np.uint8)
|
||||||
|
actual = np.array(expected, copy=True)
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
self.render_primitives_bgr_ref(expected)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
cv.gapi.wip.draw.render(actual, self.prims)
|
||||||
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|
||||||
|
def test_render_primitives_on_nv12_graph(self):
|
||||||
|
y_expected = np.zeros((self.size[0], self.size[1], 1), dtype=np.uint8)
|
||||||
|
uv_expected = np.zeros((self.size[0] // 2, self.size[1] // 2, 2), dtype=np.uint8)
|
||||||
|
|
||||||
|
y_actual = np.array(y_expected, copy=True)
|
||||||
|
uv_actual = np.array(uv_expected, copy=True)
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
self.render_primitives_nv12_ref(y_expected, uv_expected)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_y = cv.GMat()
|
||||||
|
g_uv = cv.GMat()
|
||||||
|
g_prims = cv.GArray.Prim()
|
||||||
|
g_out_y, g_out_uv = cv.gapi.wip.draw.renderNV12(g_y, g_uv, g_prims)
|
||||||
|
|
||||||
|
comp = cv.GComputation(cv.GIn(g_y, g_uv, g_prims), cv.GOut(g_out_y, g_out_uv))
|
||||||
|
y_actual, uv_actual = comp.apply(cv.gin(y_actual, uv_actual, self.prims))
|
||||||
|
|
||||||
|
self.assertEqual(0.0, cv.norm(y_expected, y_actual, cv.NORM_INF))
|
||||||
|
self.assertEqual(0.0, cv.norm(uv_expected, uv_actual, cv.NORM_INF))
|
||||||
|
|
||||||
|
def test_render_primitives_on_nv12_function(self):
|
||||||
|
y_expected = np.zeros((self.size[0], self.size[1], 1), dtype=np.uint8)
|
||||||
|
uv_expected = np.zeros((self.size[0] // 2, self.size[1] // 2, 2), dtype=np.uint8)
|
||||||
|
|
||||||
|
y_actual = np.array(y_expected, copy=True)
|
||||||
|
uv_actual = np.array(uv_expected, copy=True)
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
self.render_primitives_nv12_ref(y_expected, uv_expected)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
cv.gapi.wip.draw.render(y_actual, uv_actual, self.prims)
|
||||||
|
|
||||||
|
self.assertEqual(0.0, cv.norm(y_expected, y_actual, cv.NORM_INF))
|
||||||
|
self.assertEqual(0.0, cv.norm(uv_expected, uv_actual, cv.NORM_INF))
|
||||||
|
|
||||||
|
|
||||||
|
except unittest.SkipTest as e:
|
||||||
|
|
||||||
|
message = str(e)
|
||||||
|
|
||||||
|
class TestSkip(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.skipTest('Skip tests: ' + message)
|
||||||
|
|
||||||
|
def test_skip():
|
||||||
|
pass
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
NewOpenCVTests.bootstrap()
|
||||||
@@ -225,7 +225,7 @@ try:
|
|||||||
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
comp = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(g_out))
|
||||||
|
|
||||||
pkg = cv.gapi.kernels(GAddImpl)
|
pkg = cv.gapi.kernels(GAddImpl)
|
||||||
actual = comp.apply(cv.gin(in_mat1, in_mat2), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in_mat1, in_mat2), args=cv.gapi.compile_args(pkg))
|
||||||
|
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ try:
|
|||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_ch1, g_ch2, g_ch3))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_ch1, g_ch2, g_ch3))
|
||||||
|
|
||||||
pkg = cv.gapi.kernels(GSplit3Impl)
|
pkg = cv.gapi.kernels(GSplit3Impl)
|
||||||
ch1, ch2, ch3 = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
ch1, ch2, ch3 = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||||
|
|
||||||
self.assertEqual(0.0, cv.norm(in_ch1, ch1, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(in_ch1, ch1, cv.NORM_INF))
|
||||||
self.assertEqual(0.0, cv.norm(in_ch2, ch2, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(in_ch2, ch2, cv.NORM_INF))
|
||||||
@@ -266,7 +266,7 @@ try:
|
|||||||
comp = cv.GComputation(g_in, g_out)
|
comp = cv.GComputation(g_in, g_out)
|
||||||
|
|
||||||
pkg = cv.gapi.kernels(GMeanImpl)
|
pkg = cv.gapi.kernels(GMeanImpl)
|
||||||
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||||
|
|
||||||
# Comparison
|
# Comparison
|
||||||
self.assertEqual(expected, actual)
|
self.assertEqual(expected, actual)
|
||||||
@@ -287,7 +287,7 @@ try:
|
|||||||
comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(g_out))
|
comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(g_out))
|
||||||
|
|
||||||
pkg = cv.gapi.kernels(GAddCImpl)
|
pkg = cv.gapi.kernels(GAddCImpl)
|
||||||
actual = comp.apply(cv.gin(in_mat, sc), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in_mat, sc), args=cv.gapi.compile_args(pkg))
|
||||||
|
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ try:
|
|||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_sz))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_sz))
|
||||||
|
|
||||||
pkg = cv.gapi.kernels(GSizeImpl)
|
pkg = cv.gapi.kernels(GSizeImpl)
|
||||||
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||||
|
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ try:
|
|||||||
comp = cv.GComputation(cv.GIn(g_r), cv.GOut(g_sz))
|
comp = cv.GComputation(cv.GIn(g_r), cv.GOut(g_sz))
|
||||||
|
|
||||||
pkg = cv.gapi.kernels(GSizeRImpl)
|
pkg = cv.gapi.kernels(GSizeRImpl)
|
||||||
actual = comp.apply(cv.gin(roi), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(roi), args=cv.gapi.compile_args(pkg))
|
||||||
|
|
||||||
# cv.norm works with tuples ?
|
# cv.norm works with tuples ?
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
@@ -340,7 +340,7 @@ try:
|
|||||||
comp = cv.GComputation(cv.GIn(g_pts), cv.GOut(g_br))
|
comp = cv.GComputation(cv.GIn(g_pts), cv.GOut(g_br))
|
||||||
|
|
||||||
pkg = cv.gapi.kernels(GBoundingRectImpl)
|
pkg = cv.gapi.kernels(GBoundingRectImpl)
|
||||||
actual = comp.apply(cv.gin(points), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(points), args=cv.gapi.compile_args(pkg))
|
||||||
|
|
||||||
# cv.norm works with tuples ?
|
# cv.norm works with tuples ?
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
@@ -371,7 +371,7 @@ try:
|
|||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||||
pkg = cv.gapi.kernels(GGoodFeaturesImpl)
|
pkg = cv.gapi.kernels(GGoodFeaturesImpl)
|
||||||
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
|
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
|
||||||
|
|
||||||
# NB: OpenCV & G-API have different output types.
|
# NB: OpenCV & G-API have different output types.
|
||||||
# OpenCV - numpy array with shape (num_points, 1, 2)
|
# OpenCV - numpy array with shape (num_points, 1, 2)
|
||||||
@@ -453,10 +453,10 @@ try:
|
|||||||
g_in = cv.GArray.Int()
|
g_in = cv.GArray.Int()
|
||||||
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(GSum.on(g_in)))
|
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(GSum.on(g_in)))
|
||||||
|
|
||||||
s = comp.apply(cv.gin([1, 2, 3, 4]), args=cv.compile_args(cv.gapi.kernels(GSumImpl)))
|
s = comp.apply(cv.gin([1, 2, 3, 4]), args=cv.gapi.compile_args(cv.gapi.kernels(GSumImpl)))
|
||||||
self.assertEqual(10, s)
|
self.assertEqual(10, s)
|
||||||
|
|
||||||
s = comp.apply(cv.gin([1, 2, 8, 7]), args=cv.compile_args(cv.gapi.kernels(GSumImpl)))
|
s = comp.apply(cv.gin([1, 2, 8, 7]), args=cv.gapi.compile_args(cv.gapi.kernels(GSumImpl)))
|
||||||
self.assertEqual(18, s)
|
self.assertEqual(18, s)
|
||||||
|
|
||||||
self.assertEqual(18, GSumImpl.last_result)
|
self.assertEqual(18, GSumImpl.last_result)
|
||||||
@@ -488,13 +488,13 @@ try:
|
|||||||
'tuple': (42, 42)
|
'tuple': (42, 42)
|
||||||
}
|
}
|
||||||
|
|
||||||
out = comp.apply(cv.gin(table, 'int'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
out = comp.apply(cv.gin(table, 'int'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
||||||
self.assertEqual(42, out)
|
self.assertEqual(42, out)
|
||||||
|
|
||||||
out = comp.apply(cv.gin(table, 'str'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
out = comp.apply(cv.gin(table, 'str'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
||||||
self.assertEqual('hello, world!', out)
|
self.assertEqual('hello, world!', out)
|
||||||
|
|
||||||
out = comp.apply(cv.gin(table, 'tuple'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
out = comp.apply(cv.gin(table, 'tuple'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
|
||||||
self.assertEqual((42, 42), out)
|
self.assertEqual((42, 42), out)
|
||||||
|
|
||||||
|
|
||||||
@@ -521,7 +521,7 @@ try:
|
|||||||
arr1 = [3, 'str']
|
arr1 = [3, 'str']
|
||||||
|
|
||||||
out = comp.apply(cv.gin(arr0, arr1),
|
out = comp.apply(cv.gin(arr0, arr1),
|
||||||
args=cv.compile_args(cv.gapi.kernels(GConcatImpl)))
|
args=cv.gapi.compile_args(cv.gapi.kernels(GConcatImpl)))
|
||||||
|
|
||||||
self.assertEqual(arr0 + arr1, out)
|
self.assertEqual(arr0 + arr1, out)
|
||||||
|
|
||||||
@@ -550,7 +550,7 @@ try:
|
|||||||
img1 = np.array([1, 2, 3])
|
img1 = np.array([1, 2, 3])
|
||||||
|
|
||||||
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
||||||
args=cv.compile_args(
|
args=cv.gapi.compile_args(
|
||||||
cv.gapi.kernels(GAddImpl)))
|
cv.gapi.kernels(GAddImpl)))
|
||||||
|
|
||||||
|
|
||||||
@@ -577,7 +577,7 @@ try:
|
|||||||
img1 = np.array([1, 2, 3])
|
img1 = np.array([1, 2, 3])
|
||||||
|
|
||||||
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
||||||
args=cv.compile_args(
|
args=cv.gapi.compile_args(
|
||||||
cv.gapi.kernels(GAddImpl)))
|
cv.gapi.kernels(GAddImpl)))
|
||||||
|
|
||||||
|
|
||||||
@@ -607,7 +607,7 @@ try:
|
|||||||
# FIXME: Cause Bad variant access.
|
# FIXME: Cause Bad variant access.
|
||||||
# Need to provide more descriptive error messsage.
|
# Need to provide more descriptive error messsage.
|
||||||
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
|
||||||
args=cv.compile_args(
|
args=cv.gapi.compile_args(
|
||||||
cv.gapi.kernels(GAddImpl)))
|
cv.gapi.kernels(GAddImpl)))
|
||||||
|
|
||||||
def test_pipeline_with_custom_kernels(self):
|
def test_pipeline_with_custom_kernels(self):
|
||||||
@@ -657,7 +657,7 @@ try:
|
|||||||
g_mean = cv.gapi.mean(g_transposed)
|
g_mean = cv.gapi.mean(g_transposed)
|
||||||
|
|
||||||
comp = cv.GComputation(cv.GIn(g_bgr), cv.GOut(g_mean))
|
comp = cv.GComputation(cv.GIn(g_bgr), cv.GOut(g_mean))
|
||||||
actual = comp.apply(cv.gin(img), args=cv.compile_args(
|
actual = comp.apply(cv.gin(img), args=cv.gapi.compile_args(
|
||||||
cv.gapi.kernels(GResizeImpl, GTransposeImpl)))
|
cv.gapi.kernels(GResizeImpl, GTransposeImpl)))
|
||||||
|
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|||||||
@@ -3,201 +3,367 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
import time
|
||||||
|
|
||||||
from tests_common import NewOpenCVTests
|
from tests_common import NewOpenCVTests
|
||||||
|
|
||||||
class test_gapi_streaming(NewOpenCVTests):
|
|
||||||
|
|
||||||
def test_image_input(self):
|
try:
|
||||||
sz = (1280, 720)
|
if sys.version_info[:2] < (3, 0):
|
||||||
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
|
raise unittest.SkipTest('Python 2.x is not supported')
|
||||||
|
|
||||||
# OpenCV
|
|
||||||
expected = cv.medianBlur(in_mat, 3)
|
|
||||||
|
|
||||||
# G-API
|
|
||||||
g_in = cv.GMat()
|
|
||||||
g_out = cv.gapi.medianBlur(g_in, 3)
|
|
||||||
c = cv.GComputation(g_in, g_out)
|
|
||||||
ccomp = c.compileStreaming(cv.descr_of(in_mat))
|
|
||||||
ccomp.setSource(cv.gin(in_mat))
|
|
||||||
ccomp.start()
|
|
||||||
|
|
||||||
_, actual = ccomp.pull()
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
|
||||||
|
|
||||||
|
|
||||||
def test_video_input(self):
|
@cv.gapi.op('custom.delay', in_types=[cv.GMat], out_types=[cv.GMat])
|
||||||
ksize = 3
|
class GDelay:
|
||||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
"""Delay for 10 ms."""
|
||||||
|
|
||||||
# OpenCV
|
@staticmethod
|
||||||
cap = cv.VideoCapture(path)
|
def outMeta(desc):
|
||||||
|
return desc
|
||||||
# G-API
|
|
||||||
g_in = cv.GMat()
|
|
||||||
g_out = cv.gapi.medianBlur(g_in, ksize)
|
|
||||||
c = cv.GComputation(g_in, g_out)
|
|
||||||
|
|
||||||
ccomp = c.compileStreaming()
|
|
||||||
source = cv.gapi.wip.make_capture_src(path)
|
|
||||||
ccomp.setSource(source)
|
|
||||||
ccomp.start()
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
max_num_frames = 10
|
|
||||||
proc_num_frames = 0
|
|
||||||
while cap.isOpened():
|
|
||||||
has_expected, expected = cap.read()
|
|
||||||
has_actual, actual = ccomp.pull()
|
|
||||||
|
|
||||||
self.assertEqual(has_expected, has_actual)
|
|
||||||
|
|
||||||
if not has_actual:
|
|
||||||
break
|
|
||||||
|
|
||||||
self.assertEqual(0.0, cv.norm(cv.medianBlur(expected, ksize), actual, cv.NORM_INF))
|
|
||||||
|
|
||||||
proc_num_frames += 1
|
|
||||||
if proc_num_frames == max_num_frames:
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
def test_video_split3(self):
|
@cv.gapi.kernel(GDelay)
|
||||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
class GDelayImpl:
|
||||||
|
"""Implementation for GDelay operation."""
|
||||||
|
|
||||||
# OpenCV
|
@staticmethod
|
||||||
cap = cv.VideoCapture(path)
|
def run(img):
|
||||||
|
time.sleep(0.01)
|
||||||
# G-API
|
return img
|
||||||
g_in = cv.GMat()
|
|
||||||
b, g, r = cv.gapi.split3(g_in)
|
|
||||||
c = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r))
|
|
||||||
|
|
||||||
ccomp = c.compileStreaming()
|
|
||||||
source = cv.gapi.wip.make_capture_src(path)
|
|
||||||
ccomp.setSource(source)
|
|
||||||
ccomp.start()
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
max_num_frames = 10
|
|
||||||
proc_num_frames = 0
|
|
||||||
while cap.isOpened():
|
|
||||||
has_expected, frame = cap.read()
|
|
||||||
has_actual, actual = ccomp.pull()
|
|
||||||
|
|
||||||
self.assertEqual(has_expected, has_actual)
|
|
||||||
|
|
||||||
if not has_actual:
|
|
||||||
break
|
|
||||||
|
|
||||||
expected = cv.split(frame)
|
|
||||||
for e, a in zip(expected, actual):
|
|
||||||
self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF))
|
|
||||||
|
|
||||||
proc_num_frames += 1
|
|
||||||
if proc_num_frames == max_num_frames:
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
def test_video_add(self):
|
class test_gapi_streaming(NewOpenCVTests):
|
||||||
sz = (576, 768, 3)
|
|
||||||
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
|
|
||||||
|
|
||||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
def test_image_input(self):
|
||||||
|
sz = (1280, 720)
|
||||||
# OpenCV
|
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
|
||||||
cap = cv.VideoCapture(path)
|
|
||||||
|
|
||||||
# G-API
|
|
||||||
g_in1 = cv.GMat()
|
|
||||||
g_in2 = cv.GMat()
|
|
||||||
out = cv.gapi.add(g_in1, g_in2)
|
|
||||||
c = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(out))
|
|
||||||
|
|
||||||
ccomp = c.compileStreaming()
|
|
||||||
source = cv.gapi.wip.make_capture_src(path)
|
|
||||||
ccomp.setSource(cv.gin(source, in_mat))
|
|
||||||
ccomp.start()
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
max_num_frames = 10
|
|
||||||
proc_num_frames = 0
|
|
||||||
while cap.isOpened():
|
|
||||||
has_expected, frame = cap.read()
|
|
||||||
has_actual, actual = ccomp.pull()
|
|
||||||
|
|
||||||
self.assertEqual(has_expected, has_actual)
|
|
||||||
|
|
||||||
if not has_actual:
|
|
||||||
break
|
|
||||||
|
|
||||||
expected = cv.add(frame, in_mat)
|
|
||||||
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
|
||||||
|
|
||||||
proc_num_frames += 1
|
|
||||||
if proc_num_frames == max_num_frames:
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
def test_video_good_features_to_track(self):
|
|
||||||
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
|
||||||
|
|
||||||
# NB: goodFeaturesToTrack configuration
|
|
||||||
max_corners = 50
|
|
||||||
quality_lvl = 0.01
|
|
||||||
min_distance = 10
|
|
||||||
block_sz = 3
|
|
||||||
use_harris_detector = True
|
|
||||||
k = 0.04
|
|
||||||
mask = None
|
|
||||||
|
|
||||||
# OpenCV
|
|
||||||
cap = cv.VideoCapture(path)
|
|
||||||
|
|
||||||
# G-API
|
|
||||||
g_in = cv.GMat()
|
|
||||||
g_gray = cv.gapi.RGB2Gray(g_in)
|
|
||||||
g_out = cv.gapi.goodFeaturesToTrack(g_gray, max_corners, quality_lvl,
|
|
||||||
min_distance, mask, block_sz, use_harris_detector, k)
|
|
||||||
|
|
||||||
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
|
||||||
|
|
||||||
ccomp = c.compileStreaming()
|
|
||||||
source = cv.gapi.wip.make_capture_src(path)
|
|
||||||
ccomp.setSource(source)
|
|
||||||
ccomp.start()
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
max_num_frames = 10
|
|
||||||
proc_num_frames = 0
|
|
||||||
while cap.isOpened():
|
|
||||||
has_expected, frame = cap.read()
|
|
||||||
has_actual, actual = ccomp.pull()
|
|
||||||
|
|
||||||
self.assertEqual(has_expected, has_actual)
|
|
||||||
|
|
||||||
if not has_actual:
|
|
||||||
break
|
|
||||||
|
|
||||||
# OpenCV
|
# OpenCV
|
||||||
frame = cv.cvtColor(frame, cv.COLOR_RGB2GRAY)
|
expected = cv.medianBlur(in_mat, 3)
|
||||||
expected = cv.goodFeaturesToTrack(frame, max_corners, quality_lvl,
|
|
||||||
min_distance, mask=mask,
|
# G-API
|
||||||
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
|
g_in = cv.GMat()
|
||||||
for e, a in zip(expected, actual):
|
g_out = cv.gapi.medianBlur(g_in, 3)
|
||||||
# NB: OpenCV & G-API have different output shapes:
|
c = cv.GComputation(g_in, g_out)
|
||||||
# OpenCV - (num_points, 1, 2)
|
ccomp = c.compileStreaming(cv.gapi.descr_of(in_mat))
|
||||||
# G-API - (num_points, 2)
|
ccomp.setSource(cv.gin(in_mat))
|
||||||
self.assertEqual(0.0, cv.norm(e.flatten(),
|
ccomp.start()
|
||||||
np.array(a, np.float32).flatten(),
|
|
||||||
cv.NORM_INF))
|
_, actual = ccomp.pull()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|
||||||
|
|
||||||
|
def test_video_input(self):
|
||||||
|
ksize = 3
|
||||||
|
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
cap = cv.VideoCapture(path)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
g_out = cv.gapi.medianBlur(g_in, ksize)
|
||||||
|
c = cv.GComputation(g_in, g_out)
|
||||||
|
|
||||||
|
ccomp = c.compileStreaming()
|
||||||
|
source = cv.gapi.wip.make_capture_src(path)
|
||||||
|
ccomp.setSource(cv.gin(source))
|
||||||
|
ccomp.start()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
max_num_frames = 10
|
||||||
|
proc_num_frames = 0
|
||||||
|
while cap.isOpened():
|
||||||
|
has_expected, expected = cap.read()
|
||||||
|
has_actual, actual = ccomp.pull()
|
||||||
|
|
||||||
|
self.assertEqual(has_expected, has_actual)
|
||||||
|
|
||||||
|
if not has_actual:
|
||||||
|
break
|
||||||
|
|
||||||
|
self.assertEqual(0.0, cv.norm(cv.medianBlur(expected, ksize), actual, cv.NORM_INF))
|
||||||
|
|
||||||
|
proc_num_frames += 1
|
||||||
|
if proc_num_frames == max_num_frames:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def test_video_split3(self):
|
||||||
|
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
cap = cv.VideoCapture(path)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
b, g, r = cv.gapi.split3(g_in)
|
||||||
|
c = cv.GComputation(cv.GIn(g_in), cv.GOut(b, g, r))
|
||||||
|
|
||||||
|
ccomp = c.compileStreaming()
|
||||||
|
source = cv.gapi.wip.make_capture_src(path)
|
||||||
|
ccomp.setSource(cv.gin(source))
|
||||||
|
ccomp.start()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
max_num_frames = 10
|
||||||
|
proc_num_frames = 0
|
||||||
|
while cap.isOpened():
|
||||||
|
has_expected, frame = cap.read()
|
||||||
|
has_actual, actual = ccomp.pull()
|
||||||
|
|
||||||
|
self.assertEqual(has_expected, has_actual)
|
||||||
|
|
||||||
|
if not has_actual:
|
||||||
|
break
|
||||||
|
|
||||||
|
expected = cv.split(frame)
|
||||||
|
for e, a in zip(expected, actual):
|
||||||
|
self.assertEqual(0.0, cv.norm(e, a, cv.NORM_INF))
|
||||||
|
|
||||||
|
proc_num_frames += 1
|
||||||
|
if proc_num_frames == max_num_frames:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def test_video_add(self):
|
||||||
|
sz = (576, 768, 3)
|
||||||
|
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
|
||||||
|
|
||||||
|
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
cap = cv.VideoCapture(path)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in1 = cv.GMat()
|
||||||
|
g_in2 = cv.GMat()
|
||||||
|
out = cv.gapi.add(g_in1, g_in2)
|
||||||
|
c = cv.GComputation(cv.GIn(g_in1, g_in2), cv.GOut(out))
|
||||||
|
|
||||||
|
ccomp = c.compileStreaming()
|
||||||
|
source = cv.gapi.wip.make_capture_src(path)
|
||||||
|
ccomp.setSource(cv.gin(source, in_mat))
|
||||||
|
ccomp.start()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
max_num_frames = 10
|
||||||
|
proc_num_frames = 0
|
||||||
|
while cap.isOpened():
|
||||||
|
has_expected, frame = cap.read()
|
||||||
|
has_actual, actual = ccomp.pull()
|
||||||
|
|
||||||
|
self.assertEqual(has_expected, has_actual)
|
||||||
|
|
||||||
|
if not has_actual:
|
||||||
|
break
|
||||||
|
|
||||||
|
expected = cv.add(frame, in_mat)
|
||||||
|
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
|
||||||
|
|
||||||
|
proc_num_frames += 1
|
||||||
|
if proc_num_frames == max_num_frames:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def test_video_good_features_to_track(self):
|
||||||
|
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||||
|
|
||||||
|
# NB: goodFeaturesToTrack configuration
|
||||||
|
max_corners = 50
|
||||||
|
quality_lvl = 0.01
|
||||||
|
min_distance = 10
|
||||||
|
block_sz = 3
|
||||||
|
use_harris_detector = True
|
||||||
|
k = 0.04
|
||||||
|
mask = None
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
cap = cv.VideoCapture(path)
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
g_gray = cv.gapi.RGB2Gray(g_in)
|
||||||
|
g_out = cv.gapi.goodFeaturesToTrack(g_gray, max_corners, quality_lvl,
|
||||||
|
min_distance, mask, block_sz, use_harris_detector, k)
|
||||||
|
|
||||||
|
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out))
|
||||||
|
|
||||||
|
ccomp = c.compileStreaming()
|
||||||
|
source = cv.gapi.wip.make_capture_src(path)
|
||||||
|
ccomp.setSource(cv.gin(source))
|
||||||
|
ccomp.start()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
max_num_frames = 10
|
||||||
|
proc_num_frames = 0
|
||||||
|
while cap.isOpened():
|
||||||
|
has_expected, frame = cap.read()
|
||||||
|
has_actual, actual = ccomp.pull()
|
||||||
|
|
||||||
|
self.assertEqual(has_expected, has_actual)
|
||||||
|
|
||||||
|
if not has_actual:
|
||||||
|
break
|
||||||
|
|
||||||
|
# OpenCV
|
||||||
|
frame = cv.cvtColor(frame, cv.COLOR_RGB2GRAY)
|
||||||
|
expected = cv.goodFeaturesToTrack(frame, max_corners, quality_lvl,
|
||||||
|
min_distance, mask=mask,
|
||||||
|
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
|
||||||
|
for e, a in zip(expected, actual):
|
||||||
|
# NB: OpenCV & G-API have different output shapes:
|
||||||
|
# OpenCV - (num_points, 1, 2)
|
||||||
|
# G-API - (num_points, 2)
|
||||||
|
self.assertEqual(0.0, cv.norm(e.flatten(),
|
||||||
|
np.array(a, np.float32).flatten(),
|
||||||
|
cv.NORM_INF))
|
||||||
|
|
||||||
|
proc_num_frames += 1
|
||||||
|
if proc_num_frames == max_num_frames:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def test_gapi_streaming_meta(self):
|
||||||
|
ksize = 3
|
||||||
|
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
g_ts = cv.gapi.streaming.timestamp(g_in)
|
||||||
|
g_seqno = cv.gapi.streaming.seqNo(g_in)
|
||||||
|
g_seqid = cv.gapi.streaming.seq_id(g_in)
|
||||||
|
|
||||||
|
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_ts, g_seqno, g_seqid))
|
||||||
|
|
||||||
|
ccomp = c.compileStreaming()
|
||||||
|
source = cv.gapi.wip.make_capture_src(path)
|
||||||
|
ccomp.setSource(cv.gin(source))
|
||||||
|
ccomp.start()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
max_num_frames = 10
|
||||||
|
curr_frame_number = 0
|
||||||
|
while True:
|
||||||
|
has_frame, (ts, seqno, seqid) = ccomp.pull()
|
||||||
|
|
||||||
|
if not has_frame:
|
||||||
|
break
|
||||||
|
|
||||||
|
self.assertEqual(curr_frame_number, seqno)
|
||||||
|
self.assertEqual(curr_frame_number, seqid)
|
||||||
|
|
||||||
|
curr_frame_number += 1
|
||||||
|
if curr_frame_number == max_num_frames:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def test_desync(self):
|
||||||
|
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
|
||||||
|
|
||||||
|
# G-API
|
||||||
|
g_in = cv.GMat()
|
||||||
|
g_out1 = cv.gapi.copy(g_in)
|
||||||
|
des = cv.gapi.streaming.desync(g_in)
|
||||||
|
g_out2 = GDelay.on(des)
|
||||||
|
|
||||||
|
c = cv.GComputation(cv.GIn(g_in), cv.GOut(g_out1, g_out2))
|
||||||
|
|
||||||
|
kernels = cv.gapi.kernels(GDelayImpl)
|
||||||
|
ccomp = c.compileStreaming(args=cv.gapi.compile_args(kernels))
|
||||||
|
source = cv.gapi.wip.make_capture_src(path)
|
||||||
|
ccomp.setSource(cv.gin(source))
|
||||||
|
ccomp.start()
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
max_num_frames = 10
|
||||||
|
proc_num_frames = 0
|
||||||
|
|
||||||
|
out_counter = 0
|
||||||
|
desync_out_counter = 0
|
||||||
|
none_counter = 0
|
||||||
|
while True:
|
||||||
|
has_frame, (out1, out2) = ccomp.pull()
|
||||||
|
if not has_frame:
|
||||||
|
break
|
||||||
|
|
||||||
|
if not out1 is None:
|
||||||
|
out_counter += 1
|
||||||
|
if not out2 is None:
|
||||||
|
desync_out_counter += 1
|
||||||
|
else:
|
||||||
|
none_counter += 1
|
||||||
|
|
||||||
|
proc_num_frames += 1
|
||||||
|
if proc_num_frames == max_num_frames:
|
||||||
|
ccomp.stop()
|
||||||
|
break
|
||||||
|
|
||||||
|
self.assertLess(0, proc_num_frames)
|
||||||
|
self.assertLess(desync_out_counter, out_counter)
|
||||||
|
self.assertLess(0, none_counter)
|
||||||
|
|
||||||
|
|
||||||
|
def test_compile_streaming_empty(self):
|
||||||
|
g_in = cv.GMat()
|
||||||
|
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||||
|
comp.compileStreaming()
|
||||||
|
|
||||||
|
|
||||||
|
def test_compile_streaming_args(self):
|
||||||
|
g_in = cv.GMat()
|
||||||
|
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||||
|
comp.compileStreaming(cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||||
|
|
||||||
|
|
||||||
|
def test_compile_streaming_descr_of(self):
|
||||||
|
g_in = cv.GMat()
|
||||||
|
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||||
|
img = np.zeros((3,300,300), dtype=np.float32)
|
||||||
|
comp.compileStreaming(cv.gapi.descr_of(img))
|
||||||
|
|
||||||
|
|
||||||
|
def test_compile_streaming_descr_of_and_args(self):
|
||||||
|
g_in = cv.GMat()
|
||||||
|
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||||
|
img = np.zeros((3,300,300), dtype=np.float32)
|
||||||
|
comp.compileStreaming(cv.gapi.descr_of(img),
|
||||||
|
cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||||
|
|
||||||
|
|
||||||
|
def test_compile_streaming_meta(self):
|
||||||
|
g_in = cv.GMat()
|
||||||
|
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||||
|
img = np.zeros((3,300,300), dtype=np.float32)
|
||||||
|
comp.compileStreaming([cv.GMatDesc(cv.CV_8U, 3, (300, 300))])
|
||||||
|
|
||||||
|
|
||||||
|
def test_compile_streaming_meta_and_args(self):
|
||||||
|
g_in = cv.GMat()
|
||||||
|
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||||
|
img = np.zeros((3,300,300), dtype=np.float32)
|
||||||
|
comp.compileStreaming([cv.GMatDesc(cv.CV_8U, 3, (300, 300))],
|
||||||
|
cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
except unittest.SkipTest as e:
|
||||||
|
|
||||||
|
message = str(e)
|
||||||
|
|
||||||
|
class TestSkip(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.skipTest('Skip tests: ' + message)
|
||||||
|
|
||||||
|
def test_skip():
|
||||||
|
pass
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
proc_num_frames += 1
|
|
||||||
if proc_num_frames == max_num_frames:
|
|
||||||
break;
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
NewOpenCVTests.bootstrap()
|
NewOpenCVTests.bootstrap()
|
||||||
|
|||||||
@@ -3,29 +3,51 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import cv2 as cv
|
import cv2 as cv
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
from tests_common import NewOpenCVTests
|
from tests_common import NewOpenCVTests
|
||||||
|
|
||||||
class gapi_types_test(NewOpenCVTests):
|
|
||||||
|
|
||||||
def test_garray_type(self):
|
try:
|
||||||
types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT,
|
|
||||||
cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE ,
|
|
||||||
cv.gapi.CV_RECT , cv.gapi.CV_SCALAR, cv.gapi.CV_MAT , cv.gapi.CV_GMAT]
|
|
||||||
|
|
||||||
for t in types:
|
if sys.version_info[:2] < (3, 0):
|
||||||
g_array = cv.GArrayT(t)
|
raise unittest.SkipTest('Python 2.x is not supported')
|
||||||
self.assertEqual(t, g_array.type())
|
|
||||||
|
class gapi_types_test(NewOpenCVTests):
|
||||||
|
|
||||||
|
def test_garray_type(self):
|
||||||
|
types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT,
|
||||||
|
cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE ,
|
||||||
|
cv.gapi.CV_RECT , cv.gapi.CV_SCALAR, cv.gapi.CV_MAT , cv.gapi.CV_GMAT]
|
||||||
|
|
||||||
|
for t in types:
|
||||||
|
g_array = cv.GArrayT(t)
|
||||||
|
self.assertEqual(t, g_array.type())
|
||||||
|
|
||||||
|
|
||||||
def test_gopaque_type(self):
|
def test_gopaque_type(self):
|
||||||
types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT,
|
types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT,
|
||||||
cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE ,
|
cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE ,
|
||||||
cv.gapi.CV_RECT]
|
cv.gapi.CV_RECT]
|
||||||
|
|
||||||
for t in types:
|
for t in types:
|
||||||
g_opaque = cv.GOpaqueT(t)
|
g_opaque = cv.GOpaqueT(t)
|
||||||
self.assertEqual(t, g_opaque.type())
|
self.assertEqual(t, g_opaque.type())
|
||||||
|
|
||||||
|
|
||||||
|
except unittest.SkipTest as e:
|
||||||
|
|
||||||
|
message = str(e)
|
||||||
|
|
||||||
|
class TestSkip(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.skipTest('Skip tests: ' + message)
|
||||||
|
|
||||||
|
def test_skip():
|
||||||
|
pass
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ cv::gapi::GNetPackage::GNetPackage(std::initializer_list<GNetParam> ii)
|
|||||||
: networks(ii) {
|
: networks(ii) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::gapi::GNetPackage::GNetPackage(std::vector<GNetParam> nets)
|
||||||
|
: networks(nets) {
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<cv::gapi::GBackend> cv::gapi::GNetPackage::backends() const {
|
std::vector<cv::gapi::GBackend> cv::gapi::GNetPackage::backends() const {
|
||||||
std::unordered_set<cv::gapi::GBackend> unique_set;
|
std::unordered_set<cv::gapi::GBackend> unique_set;
|
||||||
for (const auto &nn : networks) unique_set.insert(nn.backend);
|
for (const auto &nn : networks) unique_set.insert(nn.backend);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
// of this distribution and at http://opencv.org/license.html.
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2020 Intel Corporation
|
// Copyright (C) 2020-2021 Intel Corporation
|
||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
|
|
||||||
@@ -75,6 +75,11 @@ cv::GMat cv::gapi::streaming::desync(const cv::GMat &g) {
|
|||||||
// object will feed both branches of the streaming executable.
|
// object will feed both branches of the streaming executable.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All notes from the above desync(GMat) are also applicable here
|
||||||
|
cv::GFrame cv::gapi::streaming::desync(const cv::GFrame &f) {
|
||||||
|
return cv::gapi::copy(detail::desync(f));
|
||||||
|
}
|
||||||
|
|
||||||
cv::GMat cv::gapi::streaming::BGR(const cv::GFrame& in) {
|
cv::GMat cv::gapi::streaming::BGR(const cv::GFrame& in) {
|
||||||
return cv::gapi::streaming::GBGR::on(in);
|
return cv::gapi::streaming::GBGR::on(in);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ void drawPrimitivesOCV(cv::Mat& in,
|
|||||||
{
|
{
|
||||||
const auto& rp = cv::util::get<Rect>(p);
|
const auto& rp = cv::util::get<Rect>(p);
|
||||||
const auto color = converter.cvtColor(rp.color);
|
const auto color = converter.cvtColor(rp.color);
|
||||||
cv::rectangle(in, rp.rect, color , rp.thick);
|
cv::rectangle(in, rp.rect, color, rp.thick, rp.lt, rp.shift);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ void drawPrimitivesOCV(cv::Mat& in,
|
|||||||
{
|
{
|
||||||
const auto& cp = cv::util::get<Circle>(p);
|
const auto& cp = cv::util::get<Circle>(p);
|
||||||
const auto color = converter.cvtColor(cp.color);
|
const auto color = converter.cvtColor(cp.color);
|
||||||
cv::circle(in, cp.center, cp.radius, color, cp.thick);
|
cv::circle(in, cp.center, cp.radius, color, cp.thick, cp.lt, cp.shift);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ void drawPrimitivesOCV(cv::Mat& in,
|
|||||||
{
|
{
|
||||||
const auto& lp = cv::util::get<Line>(p);
|
const auto& lp = cv::util::get<Line>(p);
|
||||||
const auto color = converter.cvtColor(lp.color);
|
const auto color = converter.cvtColor(lp.color);
|
||||||
cv::line(in, lp.pt1, lp.pt2, color, lp.thick);
|
cv::line(in, lp.pt1, lp.pt2, color, lp.thick, lp.lt, lp.shift);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,19 @@ class GGraphMetaBackendImpl final: public cv::gapi::GBackend::Priv {
|
|||||||
const std::vector<cv::gimpl::Data>&) const override {
|
const std::vector<cv::gimpl::Data>&) const override {
|
||||||
return EPtr{new GraphMetaExecutable(graph, nodes)};
|
return EPtr{new GraphMetaExecutable(graph, nodes)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool controlsMerge() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool allowsMerge(const cv::gimpl::GIslandModel::Graph &,
|
||||||
|
const ade::NodeHandle &,
|
||||||
|
const ade::NodeHandle &,
|
||||||
|
const ade::NodeHandle &) const override
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cv::gapi::GBackend graph_meta_backend() {
|
cv::gapi::GBackend graph_meta_backend() {
|
||||||
|
|||||||
@@ -652,7 +652,12 @@ GAPI_OCV_KERNEL(GCPUParseSSDBL, cv::gapi::nn::parsers::GParseSSDBL)
|
|||||||
std::vector<cv::Rect>& out_boxes,
|
std::vector<cv::Rect>& out_boxes,
|
||||||
std::vector<int>& out_labels)
|
std::vector<int>& out_labels)
|
||||||
{
|
{
|
||||||
cv::parseSSDBL(in_ssd_result, in_size, confidence_threshold, filter_label, out_boxes, out_labels);
|
cv::ParseSSD(in_ssd_result, in_size,
|
||||||
|
confidence_threshold,
|
||||||
|
filter_label,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
out_boxes, out_labels);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -665,7 +670,13 @@ GAPI_OCV_KERNEL(GOCVParseSSD, cv::gapi::nn::parsers::GParseSSD)
|
|||||||
const bool filter_out_of_bounds,
|
const bool filter_out_of_bounds,
|
||||||
std::vector<cv::Rect>& out_boxes)
|
std::vector<cv::Rect>& out_boxes)
|
||||||
{
|
{
|
||||||
cv::parseSSD(in_ssd_result, in_size, confidence_threshold, alignment_to_square, filter_out_of_bounds, out_boxes);
|
std::vector<int> unused_labels;
|
||||||
|
cv::ParseSSD(in_ssd_result, in_size,
|
||||||
|
confidence_threshold,
|
||||||
|
-1,
|
||||||
|
alignment_to_square,
|
||||||
|
filter_out_of_bounds,
|
||||||
|
out_boxes, unused_labels);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -170,12 +170,14 @@ private:
|
|||||||
} // namespace nn
|
} // namespace nn
|
||||||
} // namespace gapi
|
} // namespace gapi
|
||||||
|
|
||||||
void parseSSDBL(const cv::Mat& in_ssd_result,
|
void ParseSSD(const cv::Mat& in_ssd_result,
|
||||||
const cv::Size& in_size,
|
const cv::Size& in_size,
|
||||||
const float confidence_threshold,
|
const float confidence_threshold,
|
||||||
const int filter_label,
|
const int filter_label,
|
||||||
std::vector<cv::Rect>& out_boxes,
|
const bool alignment_to_square,
|
||||||
std::vector<int>& out_labels)
|
const bool filter_out_of_bounds,
|
||||||
|
std::vector<cv::Rect>& out_boxes,
|
||||||
|
std::vector<int>& out_labels)
|
||||||
{
|
{
|
||||||
cv::gapi::nn::SSDParser parser(in_ssd_result.size, in_size, in_ssd_result.ptr<float>());
|
cv::gapi::nn::SSDParser parser(in_ssd_result.size, in_size, in_ssd_result.ptr<float>());
|
||||||
out_boxes.clear();
|
out_boxes.clear();
|
||||||
@@ -188,38 +190,6 @@ void parseSSDBL(const cv::Mat& in_ssd_result,
|
|||||||
{
|
{
|
||||||
std::tie(rc, image_id, confidence, label) = parser.extract(i);
|
std::tie(rc, image_id, confidence, label) = parser.extract(i);
|
||||||
|
|
||||||
if (image_id < 0.f)
|
|
||||||
{
|
|
||||||
break; // marks end-of-detections
|
|
||||||
}
|
|
||||||
|
|
||||||
if (confidence < confidence_threshold ||
|
|
||||||
(filter_label != -1 && label != filter_label))
|
|
||||||
{
|
|
||||||
continue; // filter out object classes if filter is specified
|
|
||||||
} // and skip objects with low confidence
|
|
||||||
out_boxes.emplace_back(rc & parser.getSurface());
|
|
||||||
out_labels.emplace_back(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parseSSD(const cv::Mat& in_ssd_result,
|
|
||||||
const cv::Size& in_size,
|
|
||||||
const float confidence_threshold,
|
|
||||||
const bool alignment_to_square,
|
|
||||||
const bool filter_out_of_bounds,
|
|
||||||
std::vector<cv::Rect>& out_boxes)
|
|
||||||
{
|
|
||||||
cv::gapi::nn::SSDParser parser(in_ssd_result.size, in_size, in_ssd_result.ptr<float>());
|
|
||||||
out_boxes.clear();
|
|
||||||
cv::Rect rc;
|
|
||||||
float image_id, confidence;
|
|
||||||
int label;
|
|
||||||
const size_t range = parser.getMaxProposals();
|
|
||||||
for (size_t i = 0; i < range; ++i)
|
|
||||||
{
|
|
||||||
std::tie(rc, image_id, confidence, label) = parser.extract(i);
|
|
||||||
|
|
||||||
if (image_id < 0.f)
|
if (image_id < 0.f)
|
||||||
{
|
{
|
||||||
break; // marks end-of-detections
|
break; // marks end-of-detections
|
||||||
@@ -228,12 +198,14 @@ void parseSSD(const cv::Mat& in_ssd_result,
|
|||||||
{
|
{
|
||||||
continue; // skip objects with low confidence
|
continue; // skip objects with low confidence
|
||||||
}
|
}
|
||||||
|
if((filter_label != -1) && (label != filter_label))
|
||||||
|
{
|
||||||
|
continue; // filter out object classes if filter is specified
|
||||||
|
}
|
||||||
if (alignment_to_square)
|
if (alignment_to_square)
|
||||||
{
|
{
|
||||||
parser.adjustBoundingBox(rc);
|
parser.adjustBoundingBox(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto clipped_rc = rc & parser.getSurface();
|
const auto clipped_rc = rc & parser.getSurface();
|
||||||
if (filter_out_of_bounds)
|
if (filter_out_of_bounds)
|
||||||
{
|
{
|
||||||
@@ -243,6 +215,7 @@ void parseSSD(const cv::Mat& in_ssd_result,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
out_boxes.emplace_back(clipped_rc);
|
out_boxes.emplace_back(clipped_rc);
|
||||||
|
out_labels.emplace_back(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,19 +11,14 @@
|
|||||||
|
|
||||||
namespace cv
|
namespace cv
|
||||||
{
|
{
|
||||||
void parseSSDBL(const cv::Mat& in_ssd_result,
|
void ParseSSD(const cv::Mat& in_ssd_result,
|
||||||
const cv::Size& in_size,
|
|
||||||
const float confidence_threshold,
|
|
||||||
const int filter_label,
|
|
||||||
std::vector<cv::Rect>& out_boxes,
|
|
||||||
std::vector<int>& out_labels);
|
|
||||||
|
|
||||||
void parseSSD(const cv::Mat& in_ssd_result,
|
|
||||||
const cv::Size& in_size,
|
const cv::Size& in_size,
|
||||||
const float confidence_threshold,
|
const float confidence_threshold,
|
||||||
|
const int filter_label,
|
||||||
const bool alignment_to_square,
|
const bool alignment_to_square,
|
||||||
const bool filter_out_of_bounds,
|
const bool filter_out_of_bounds,
|
||||||
std::vector<cv::Rect>& out_boxes);
|
std::vector<cv::Rect>& out_boxes,
|
||||||
|
std::vector<int>& out_labels);
|
||||||
|
|
||||||
void parseYolo(const cv::Mat& in_yolo_result,
|
void parseYolo(const cv::Mat& in_yolo_result,
|
||||||
const cv::Size& in_size,
|
const cv::Size& in_size,
|
||||||
|
|||||||
@@ -37,3 +37,15 @@ cv::gapi::ie::PyParams cv::gapi::ie::params(const std::string &tag,
|
|||||||
const std::string &device) {
|
const std::string &device) {
|
||||||
return {tag, model, device};
|
return {tag, model, device};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::gapi::ie::PyParams& cv::gapi::ie::PyParams::constInput(const std::string &layer_name,
|
||||||
|
const cv::Mat &data,
|
||||||
|
TraitAs hint) {
|
||||||
|
m_priv->constInput(layer_name, data, hint);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::gapi::ie::PyParams& cv::gapi::ie::PyParams::cfgNumRequests(size_t nireq) {
|
||||||
|
m_priv->cfgNumRequests(nireq);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ bool cv::GStreamingCompiled::Priv::pull(cv::GOptRunArgsP &&outs)
|
|||||||
return m_exec->pull(std::move(outs));
|
return m_exec->pull(std::move(outs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> cv::GStreamingCompiled::Priv::pull()
|
||||||
|
{
|
||||||
|
return m_exec->pull();
|
||||||
|
}
|
||||||
|
|
||||||
bool cv::GStreamingCompiled::Priv::try_pull(cv::GRunArgsP &&outs)
|
bool cv::GStreamingCompiled::Priv::try_pull(cv::GRunArgsP &&outs)
|
||||||
{
|
{
|
||||||
return m_exec->try_pull(std::move(outs));
|
return m_exec->try_pull(std::move(outs));
|
||||||
@@ -123,18 +128,9 @@ bool cv::GStreamingCompiled::pull(cv::GRunArgsP &&outs)
|
|||||||
return m_priv->pull(std::move(outs));
|
return m_priv->pull(std::move(outs));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<bool, cv::GRunArgs> cv::GStreamingCompiled::pull()
|
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> cv::GStreamingCompiled::pull()
|
||||||
{
|
{
|
||||||
GRunArgs run_args;
|
return m_priv->pull();
|
||||||
GRunArgsP outs;
|
|
||||||
const auto& out_info = m_priv->outInfo();
|
|
||||||
run_args.reserve(out_info.size());
|
|
||||||
outs.reserve(out_info.size());
|
|
||||||
|
|
||||||
cv::detail::constructGraphOutputs(m_priv->outInfo(), run_args, outs);
|
|
||||||
|
|
||||||
bool is_over = m_priv->pull(std::move(outs));
|
|
||||||
return std::make_tuple(is_over, run_args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cv::GStreamingCompiled::pull(cv::GOptRunArgsP &&outs)
|
bool cv::GStreamingCompiled::pull(cv::GOptRunArgsP &&outs)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public:
|
|||||||
void start();
|
void start();
|
||||||
bool pull(cv::GRunArgsP &&outs);
|
bool pull(cv::GRunArgsP &&outs);
|
||||||
bool pull(cv::GOptRunArgsP &&outs);
|
bool pull(cv::GOptRunArgsP &&outs);
|
||||||
|
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> pull();
|
||||||
bool try_pull(cv::GRunArgsP &&outs);
|
bool try_pull(cv::GRunArgsP &&outs);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
#include "precomp.hpp"
|
#include "precomp.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <ade/util/zip_range.hpp>
|
#include <ade/util/zip_range.hpp>
|
||||||
|
|
||||||
#include <opencv2/gapi/opencv_includes.hpp>
|
#include <opencv2/gapi/opencv_includes.hpp>
|
||||||
@@ -157,10 +155,14 @@ void writeBackExec(const Mag& mag, const RcDesc &rc, GRunArgP &g_arg)
|
|||||||
// FIXME:
|
// FIXME:
|
||||||
// Rework, find a better way to check if there should be
|
// Rework, find a better way to check if there should be
|
||||||
// a real copy (add a pass to StreamingBackend?)
|
// a real copy (add a pass to StreamingBackend?)
|
||||||
|
// NB: In case RMat adapter not equal to "RMatAdapter" need to
|
||||||
|
// copy data back to the host as well.
|
||||||
|
// FIXME: Rename "RMatAdapter" to "OpenCVAdapter".
|
||||||
auto& out_mat = *util::get<cv::Mat*>(g_arg);
|
auto& out_mat = *util::get<cv::Mat*>(g_arg);
|
||||||
const auto& rmat = mag.template slot<cv::RMat>().at(rc.id);
|
const auto& rmat = mag.template slot<cv::RMat>().at(rc.id);
|
||||||
auto mag_data = rmat.get<RMatAdapter>()->data();
|
auto* adapter = rmat.get<RMatAdapter>();
|
||||||
if (out_mat.data != mag_data) {
|
if ((adapter != nullptr && out_mat.data != adapter->data()) ||
|
||||||
|
(adapter == nullptr)) {
|
||||||
auto view = rmat.access(RMat::Access::R);
|
auto view = rmat.access(RMat::Access::R);
|
||||||
asMat(view).copyTo(out_mat);
|
asMat(view).copyTo(out_mat);
|
||||||
}
|
}
|
||||||
@@ -407,7 +409,8 @@ bool cv::gimpl::GExecutor::canReshape() const
|
|||||||
{
|
{
|
||||||
// FIXME: Introduce proper reshaping support on GExecutor level
|
// FIXME: Introduce proper reshaping support on GExecutor level
|
||||||
// for all cases!
|
// for all cases!
|
||||||
return (m_ops.size() == 1) && m_ops[0].isl_exec->canReshape();
|
return std::all_of(m_ops.begin(), m_ops.end(),
|
||||||
|
[](const OpDesc& op) { return op.isl_exec->canReshape(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::gimpl::GExecutor::reshape(const GMetaArgs& inMetas, const GCompileArgs& args)
|
void cv::gimpl::GExecutor::reshape(const GMetaArgs& inMetas, const GCompileArgs& args)
|
||||||
@@ -417,7 +420,17 @@ void cv::gimpl::GExecutor::reshape(const GMetaArgs& inMetas, const GCompileArgs&
|
|||||||
ade::passes::PassContext ctx{g};
|
ade::passes::PassContext ctx{g};
|
||||||
passes::initMeta(ctx, inMetas);
|
passes::initMeta(ctx, inMetas);
|
||||||
passes::inferMeta(ctx, true);
|
passes::inferMeta(ctx, true);
|
||||||
m_ops[0].isl_exec->reshape(g, args);
|
|
||||||
|
// NB: Before reshape islands need to re-init resources for every slot.
|
||||||
|
for (auto slot : m_slots)
|
||||||
|
{
|
||||||
|
initResource(slot.slot_nh, slot.data_nh);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& op : m_ops)
|
||||||
|
{
|
||||||
|
op.isl_exec->reshape(g, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::gimpl::GExecutor::prepareForNewStream()
|
void cv::gimpl::GExecutor::prepareForNewStream()
|
||||||
|
|||||||
@@ -186,8 +186,9 @@ void sync_data(cv::gimpl::stream::Result &r, cv::GOptRunArgsP &outputs)
|
|||||||
// FIXME: this conversion should be unified
|
// FIXME: this conversion should be unified
|
||||||
switch (out_obj.index())
|
switch (out_obj.index())
|
||||||
{
|
{
|
||||||
HANDLE_CASE(cv::Scalar); break;
|
HANDLE_CASE(cv::Scalar); break;
|
||||||
HANDLE_CASE(cv::RMat); break;
|
HANDLE_CASE(cv::RMat); break;
|
||||||
|
HANDLE_CASE(cv::MediaFrame); break;
|
||||||
|
|
||||||
case T::index_of<O<cv::Mat>*>(): {
|
case T::index_of<O<cv::Mat>*>(): {
|
||||||
// Mat: special handling.
|
// Mat: special handling.
|
||||||
@@ -1017,6 +1018,49 @@ void check_DesyncObjectConsumedByMultipleIslands(const cv::gimpl::GIslandModel::
|
|||||||
} // for(nodes)
|
} // for(nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NB: Construct GRunArgsP based on passed info and store the memory in passed cv::GRunArgs.
|
||||||
|
// Needed for python bridge, because in case python user doesn't pass output arguments to apply.
|
||||||
|
void constructOptGraphOutputs(const cv::GTypesInfo &out_info,
|
||||||
|
cv::GOptRunArgs &args,
|
||||||
|
cv::GOptRunArgsP &outs)
|
||||||
|
{
|
||||||
|
for (auto&& info : out_info)
|
||||||
|
{
|
||||||
|
switch (info.shape)
|
||||||
|
{
|
||||||
|
case cv::GShape::GMAT:
|
||||||
|
{
|
||||||
|
args.emplace_back(cv::optional<cv::Mat>{});
|
||||||
|
outs.emplace_back(&cv::util::get<cv::optional<cv::Mat>>(args.back()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case cv::GShape::GSCALAR:
|
||||||
|
{
|
||||||
|
args.emplace_back(cv::optional<cv::Scalar>{});
|
||||||
|
outs.emplace_back(&cv::util::get<cv::optional<cv::Scalar>>(args.back()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case cv::GShape::GARRAY:
|
||||||
|
{
|
||||||
|
cv::detail::VectorRef ref;
|
||||||
|
cv::util::get<cv::detail::ConstructVec>(info.ctor)(ref);
|
||||||
|
args.emplace_back(cv::util::make_optional(std::move(ref)));
|
||||||
|
outs.emplace_back(wrap_opt_arg(cv::util::get<cv::optional<cv::detail::VectorRef>>(args.back())));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case cv::GShape::GOPAQUE:
|
||||||
|
{
|
||||||
|
cv::detail::OpaqueRef ref;
|
||||||
|
cv::util::get<cv::detail::ConstructOpaque>(info.ctor)(ref);
|
||||||
|
args.emplace_back(cv::util::make_optional(std::move(ref)));
|
||||||
|
outs.emplace_back(wrap_opt_arg(cv::util::get<cv::optional<cv::detail::OpaqueRef>>(args.back())));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
cv::util::throw_error(std::logic_error("Unsupported optional output shape for Python"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
class cv::gimpl::GStreamingExecutor::Synchronizer final {
|
class cv::gimpl::GStreamingExecutor::Synchronizer final {
|
||||||
@@ -1320,6 +1364,16 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr<ade::Graph> &&
|
|||||||
// per the same input frame, so the output traffic multiplies)
|
// per the same input frame, so the output traffic multiplies)
|
||||||
GAPI_Assert(m_collector_map.size() > 0u);
|
GAPI_Assert(m_collector_map.size() > 0u);
|
||||||
m_out_queue.set_capacity(queue_capacity * m_collector_map.size());
|
m_out_queue.set_capacity(queue_capacity * m_collector_map.size());
|
||||||
|
|
||||||
|
// FIXME: The code duplicates logic of collectGraphInfo()
|
||||||
|
cv::gimpl::GModel::ConstGraph cgr(*m_orig_graph);
|
||||||
|
auto meta = cgr.metadata().get<cv::gimpl::Protocol>().out_nhs;
|
||||||
|
out_info.reserve(meta.size());
|
||||||
|
|
||||||
|
ade::util::transform(meta, std::back_inserter(out_info), [&cgr](const ade::NodeHandle& nh) {
|
||||||
|
const auto& data = cgr.metadata(nh).get<cv::gimpl::Data>();
|
||||||
|
return cv::GTypeInfo{data.shape, data.kind, data.ctor};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::gimpl::GStreamingExecutor::~GStreamingExecutor()
|
cv::gimpl::GStreamingExecutor::~GStreamingExecutor()
|
||||||
@@ -1653,6 +1707,31 @@ bool cv::gimpl::GStreamingExecutor::pull(cv::GOptRunArgsP &&outs)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> cv::gimpl::GStreamingExecutor::pull()
|
||||||
|
{
|
||||||
|
using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
|
||||||
|
bool is_over = false;
|
||||||
|
|
||||||
|
if (m_desync) {
|
||||||
|
GOptRunArgs opt_run_args;
|
||||||
|
GOptRunArgsP opt_outs;
|
||||||
|
opt_outs.reserve(out_info.size());
|
||||||
|
opt_run_args.reserve(out_info.size());
|
||||||
|
|
||||||
|
constructOptGraphOutputs(out_info, opt_run_args, opt_outs);
|
||||||
|
is_over = pull(std::move(opt_outs));
|
||||||
|
return std::make_tuple(is_over, RunArgs(opt_run_args));
|
||||||
|
}
|
||||||
|
|
||||||
|
GRunArgs run_args;
|
||||||
|
GRunArgsP outs;
|
||||||
|
run_args.reserve(out_info.size());
|
||||||
|
outs.reserve(out_info.size());
|
||||||
|
|
||||||
|
constructGraphOutputs(out_info, run_args, outs);
|
||||||
|
is_over = pull(std::move(outs));
|
||||||
|
return std::make_tuple(is_over, RunArgs(run_args));
|
||||||
|
}
|
||||||
|
|
||||||
bool cv::gimpl::GStreamingExecutor::try_pull(cv::GRunArgsP &&outs)
|
bool cv::gimpl::GStreamingExecutor::try_pull(cv::GRunArgsP &&outs)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -195,6 +195,8 @@ protected:
|
|||||||
|
|
||||||
void wait_shutdown();
|
void wait_shutdown();
|
||||||
|
|
||||||
|
cv::GTypesInfo out_info;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model,
|
explicit GStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model,
|
||||||
const cv::GCompileArgs &comp_args);
|
const cv::GCompileArgs &comp_args);
|
||||||
@@ -203,6 +205,7 @@ public:
|
|||||||
void start();
|
void start();
|
||||||
bool pull(cv::GRunArgsP &&outs);
|
bool pull(cv::GRunArgsP &&outs);
|
||||||
bool pull(cv::GOptRunArgsP &&outs);
|
bool pull(cv::GOptRunArgsP &&outs);
|
||||||
|
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> pull();
|
||||||
bool try_pull(cv::GRunArgsP &&outs);
|
bool try_pull(cv::GRunArgsP &&outs);
|
||||||
void stop();
|
void stop();
|
||||||
bool running() const;
|
bool running() const;
|
||||||
|
|||||||
@@ -6,10 +6,158 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "../test_precomp.hpp"
|
#include "../test_precomp.hpp"
|
||||||
|
#include "../gapi_mock_kernels.hpp"
|
||||||
|
|
||||||
namespace opencv_test
|
namespace opencv_test
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
class GMockExecutable final: public cv::gimpl::GIslandExecutable
|
||||||
|
{
|
||||||
|
virtual inline bool canReshape() const override {
|
||||||
|
return m_priv->m_can_reshape;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void reshape(ade::Graph&, const GCompileArgs&) override
|
||||||
|
{
|
||||||
|
m_priv->m_reshape_counter++;
|
||||||
|
}
|
||||||
|
virtual void handleNewStream() override { }
|
||||||
|
virtual void run(std::vector<InObj>&&, std::vector<OutObj>&&) { }
|
||||||
|
virtual bool allocatesOutputs() const override
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual cv::RMat allocate(const cv::GMatDesc&) const override
|
||||||
|
{
|
||||||
|
m_priv->m_allocate_counter++;
|
||||||
|
return cv::RMat();
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: GMockBackendImpl creates new unique_ptr<GMockExecutable>
|
||||||
|
// on every compile call. Need to share counters between instances in order
|
||||||
|
// to validate it in tests.
|
||||||
|
struct Priv
|
||||||
|
{
|
||||||
|
bool m_can_reshape;
|
||||||
|
int m_reshape_counter;
|
||||||
|
int m_allocate_counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<Priv> m_priv;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GMockExecutable(bool can_reshape = true)
|
||||||
|
: m_priv(new Priv{can_reshape, 0, 0})
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
void setReshape(bool can_reshape) { m_priv->m_can_reshape = can_reshape; }
|
||||||
|
|
||||||
|
int getReshapeCounter() const { return m_priv->m_reshape_counter; }
|
||||||
|
int getAllocateCounter() const { return m_priv->m_allocate_counter; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class GMockBackendImpl final: public cv::gapi::GBackend::Priv
|
||||||
|
{
|
||||||
|
virtual void unpackKernel(ade::Graph &,
|
||||||
|
const ade::NodeHandle &,
|
||||||
|
const cv::GKernelImpl &) override { }
|
||||||
|
|
||||||
|
virtual EPtr compile(const ade::Graph &,
|
||||||
|
const cv::GCompileArgs &,
|
||||||
|
const std::vector<ade::NodeHandle> &) const override
|
||||||
|
{
|
||||||
|
++m_compile_counter;
|
||||||
|
return EPtr{new GMockExecutable(m_exec)};
|
||||||
|
}
|
||||||
|
|
||||||
|
mutable int m_compile_counter = 0;
|
||||||
|
GMockExecutable m_exec;
|
||||||
|
|
||||||
|
virtual bool controlsMerge() const override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool allowsMerge(const cv::gimpl::GIslandModel::Graph &,
|
||||||
|
const ade::NodeHandle &,
|
||||||
|
const ade::NodeHandle &,
|
||||||
|
const ade::NodeHandle &) const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
GMockBackendImpl(const GMockExecutable& exec) : m_exec(exec) { };
|
||||||
|
int getCompileCounter() const { return m_compile_counter; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class GMockFunctor : public gapi::cpu::GOCVFunctor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GMockFunctor(cv::gapi::GBackend backend,
|
||||||
|
const char* id,
|
||||||
|
const Meta &meta,
|
||||||
|
const Impl& impl)
|
||||||
|
: gapi::cpu::GOCVFunctor(id, meta, impl), m_backend(backend)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::gapi::GBackend backend() const override { return m_backend; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
cv::gapi::GBackend m_backend;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename K, typename Callable>
|
||||||
|
GMockFunctor mock_kernel(const cv::gapi::GBackend& backend, Callable c)
|
||||||
|
{
|
||||||
|
using P = cv::detail::OCVCallHelper<Callable, typename K::InArgs, typename K::OutArgs>;
|
||||||
|
return GMockFunctor{ backend
|
||||||
|
, K::id()
|
||||||
|
, &K::getOutMeta
|
||||||
|
, std::bind(&P::callFunctor, std::placeholders::_1, c)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummyFooImpl(const cv::Mat&, cv::Mat&) { };
|
||||||
|
void dummyBarImpl(const cv::Mat&, const cv::Mat&, cv::Mat&) { };
|
||||||
|
|
||||||
|
struct GExecutorReshapeTest: public ::testing::Test
|
||||||
|
{
|
||||||
|
GExecutorReshapeTest()
|
||||||
|
: comp([](){
|
||||||
|
cv::GMat in;
|
||||||
|
cv::GMat out = I::Bar::on(I::Foo::on(in), in);
|
||||||
|
return cv::GComputation(in, out);
|
||||||
|
})
|
||||||
|
{
|
||||||
|
backend_impl1 = std::make_shared<GMockBackendImpl>(island1);
|
||||||
|
backend1 = cv::gapi::GBackend{backend_impl1};
|
||||||
|
backend_impl2 = std::make_shared<GMockBackendImpl>(island2);
|
||||||
|
backend2 = cv::gapi::GBackend{backend_impl2};
|
||||||
|
auto kernel1 = mock_kernel<I::Foo>(backend1, dummyFooImpl);
|
||||||
|
auto kernel2 = mock_kernel<I::Bar>(backend2, dummyBarImpl);
|
||||||
|
pkg = cv::gapi::kernels(kernel1, kernel2);
|
||||||
|
in_mat1 = cv::Mat::eye(32, 32, CV_8UC1);
|
||||||
|
in_mat2 = cv::Mat::eye(64, 64, CV_8UC1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::GComputation comp;
|
||||||
|
GMockExecutable island1;
|
||||||
|
std::shared_ptr<GMockBackendImpl> backend_impl1;
|
||||||
|
cv::gapi::GBackend backend1;
|
||||||
|
GMockExecutable island2;
|
||||||
|
std::shared_ptr<GMockBackendImpl> backend_impl2;
|
||||||
|
cv::gapi::GBackend backend2;
|
||||||
|
cv::gapi::GKernelPackage pkg;
|
||||||
|
cv::Mat in_mat1, in_mat2, out_mat;;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
// FIXME: avoid code duplication
|
// FIXME: avoid code duplication
|
||||||
// The below graph and config is taken from ComplexIslands test suite
|
// The below graph and config is taken from ComplexIslands test suite
|
||||||
TEST(GExecutor, SmokeTest)
|
TEST(GExecutor, SmokeTest)
|
||||||
@@ -77,6 +225,75 @@ TEST(GExecutor, SmokeTest)
|
|||||||
// with breakdown worked)
|
// with breakdown worked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(GExecutorReshapeTest, ReshapeInsteadOfRecompile)
|
||||||
|
{
|
||||||
|
// NB: Initial state
|
||||||
|
EXPECT_EQ(0, backend_impl1->getCompileCounter());
|
||||||
|
EXPECT_EQ(0, backend_impl2->getCompileCounter());
|
||||||
|
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||||
|
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||||
|
|
||||||
|
// NB: First compilation.
|
||||||
|
comp.apply(cv::gin(in_mat1), cv::gout(out_mat), cv::compile_args(pkg));
|
||||||
|
EXPECT_EQ(1, backend_impl1->getCompileCounter());
|
||||||
|
EXPECT_EQ(1, backend_impl2->getCompileCounter());
|
||||||
|
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||||
|
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||||
|
|
||||||
|
// NB: GMockBackendImpl implements "reshape" method,
|
||||||
|
// so it won't be recompiled if the meta is changed.
|
||||||
|
comp.apply(cv::gin(in_mat2), cv::gout(out_mat), cv::compile_args(pkg));
|
||||||
|
EXPECT_EQ(1, backend_impl1->getCompileCounter());
|
||||||
|
EXPECT_EQ(1, backend_impl2->getCompileCounter());
|
||||||
|
EXPECT_EQ(1, island1.getReshapeCounter());
|
||||||
|
EXPECT_EQ(1, island2.getReshapeCounter());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GExecutorReshapeTest, OneBackendNotReshapable)
|
||||||
|
{
|
||||||
|
// NB: Make first island not reshapable
|
||||||
|
island1.setReshape(false);
|
||||||
|
|
||||||
|
// NB: Initial state
|
||||||
|
EXPECT_EQ(0, backend_impl1->getCompileCounter());
|
||||||
|
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||||
|
EXPECT_EQ(0, backend_impl2->getCompileCounter());
|
||||||
|
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||||
|
|
||||||
|
// NB: First compilation.
|
||||||
|
comp.apply(cv::gin(in_mat1), cv::gout(out_mat), cv::compile_args(pkg));
|
||||||
|
EXPECT_EQ(1, backend_impl1->getCompileCounter());
|
||||||
|
EXPECT_EQ(1, backend_impl2->getCompileCounter());
|
||||||
|
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||||
|
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||||
|
|
||||||
|
// NB: Since one of islands isn't reshapable
|
||||||
|
// the entire graph isn't reshapable as well.
|
||||||
|
comp.apply(cv::gin(in_mat2), cv::gout(out_mat), cv::compile_args(pkg));
|
||||||
|
EXPECT_EQ(2, backend_impl1->getCompileCounter());
|
||||||
|
EXPECT_EQ(2, backend_impl2->getCompileCounter());
|
||||||
|
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||||
|
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(GExecutorReshapeTest, ReshapeCallAllocate)
|
||||||
|
{
|
||||||
|
// NB: Initial state
|
||||||
|
EXPECT_EQ(0, island1.getAllocateCounter());
|
||||||
|
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||||
|
|
||||||
|
// NB: First compilation.
|
||||||
|
comp.apply(cv::gin(in_mat1), cv::gout(out_mat), cv::compile_args(pkg));
|
||||||
|
EXPECT_EQ(1, island1.getAllocateCounter());
|
||||||
|
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||||
|
|
||||||
|
// NB: The entire graph is reshapable, so it won't be recompiled, but reshaped.
|
||||||
|
// Check that reshape call "allocate" to reallocate buffers.
|
||||||
|
comp.apply(cv::gin(in_mat2), cv::gout(out_mat), cv::compile_args(pkg));
|
||||||
|
EXPECT_EQ(2, island1.getAllocateCounter());
|
||||||
|
EXPECT_EQ(1, island1.getReshapeCounter());
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Add explicit tests on GMat/GScalar/GArray<T> being connectors
|
// FIXME: Add explicit tests on GMat/GScalar/GArray<T> being connectors
|
||||||
// between executed islands
|
// between executed islands
|
||||||
|
|
||||||
|
|||||||
@@ -639,8 +639,8 @@ INSTANTIATE_TEST_CASE_P(RenderBGROCVTestRectsImpl, RenderBGROCVTestRects,
|
|||||||
Values(cv::Rect(100, 100, 200, 200)),
|
Values(cv::Rect(100, 100, 200, 200)),
|
||||||
Values(cv::Scalar(100, 50, 150)),
|
Values(cv::Scalar(100, 50, 150)),
|
||||||
Values(2),
|
Values(2),
|
||||||
Values(LINE_8),
|
Values(LINE_8, LINE_4),
|
||||||
Values(0)));
|
Values(0, 1)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestRectsImpl, RenderNV12OCVTestRects,
|
INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestRectsImpl, RenderNV12OCVTestRects,
|
||||||
Combine(Values(cv::Size(1280, 720)),
|
Combine(Values(cv::Size(1280, 720)),
|
||||||
@@ -673,8 +673,8 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestCirclesImpl, RenderNV12OCVTestCircles,
|
|||||||
Values(10),
|
Values(10),
|
||||||
Values(cv::Scalar(100, 50, 150)),
|
Values(cv::Scalar(100, 50, 150)),
|
||||||
Values(2),
|
Values(2),
|
||||||
Values(LINE_8),
|
Values(LINE_8, LINE_4),
|
||||||
Values(0)));
|
Values(0, 1)));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestCirclesImpl, RenderMFrameOCVTestCircles,
|
INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestCirclesImpl, RenderMFrameOCVTestCircles,
|
||||||
Combine(Values(cv::Size(1280, 720)),
|
Combine(Values(cv::Size(1280, 720)),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||||
// of this distribution and at http://opencv.org/license.html.
|
// of this distribution and at http://opencv.org/license.html.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2019-2020 Intel Corporation
|
// Copyright (C) 2019-2021 Intel Corporation
|
||||||
|
|
||||||
|
|
||||||
#include "../test_precomp.hpp"
|
#include "../test_precomp.hpp"
|
||||||
@@ -244,6 +244,35 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void checkPullOverload(const cv::Mat& ref,
|
||||||
|
const bool has_output,
|
||||||
|
cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>& args) {
|
||||||
|
EXPECT_TRUE(has_output);
|
||||||
|
using runArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
|
||||||
|
cv::Mat out_mat;
|
||||||
|
switch (args.index()) {
|
||||||
|
case runArgs::index_of<cv::GRunArgs>():
|
||||||
|
{
|
||||||
|
auto outputs = util::get<cv::GRunArgs>(args);
|
||||||
|
EXPECT_EQ(1u, outputs.size());
|
||||||
|
out_mat = cv::util::get<cv::Mat>(outputs[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case runArgs::index_of<cv::GOptRunArgs>():
|
||||||
|
{
|
||||||
|
auto outputs = util::get<cv::GOptRunArgs>(args);
|
||||||
|
EXPECT_EQ(1u, outputs.size());
|
||||||
|
auto opt_mat = cv::util::get<cv::optional<cv::Mat>>(outputs[0]);
|
||||||
|
ASSERT_TRUE(opt_mat.has_value());
|
||||||
|
out_mat = *opt_mat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: GAPI_Assert(false && "Incorrect type of Args");
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(0., cv::norm(ref, out_mat, cv::NORM_INF));
|
||||||
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
TEST_P(GAPI_Streaming, SmokeTest_ConstInput_GMat)
|
TEST_P(GAPI_Streaming, SmokeTest_ConstInput_GMat)
|
||||||
@@ -1336,13 +1365,45 @@ TEST(Streaming, Python_Pull_Overload)
|
|||||||
|
|
||||||
bool has_output;
|
bool has_output;
|
||||||
cv::GRunArgs outputs;
|
cv::GRunArgs outputs;
|
||||||
std::tie(has_output, outputs) = ccomp.pull();
|
using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
|
||||||
|
RunArgs args;
|
||||||
|
|
||||||
EXPECT_TRUE(has_output);
|
std::tie(has_output, args) = ccomp.pull();
|
||||||
EXPECT_EQ(1u, outputs.size());
|
|
||||||
|
|
||||||
auto out_mat = cv::util::get<cv::Mat>(outputs[0]);
|
checkPullOverload(in_mat, has_output, args);
|
||||||
EXPECT_EQ(0., cv::norm(in_mat, out_mat, cv::NORM_INF));
|
|
||||||
|
ccomp.stop();
|
||||||
|
EXPECT_FALSE(ccomp.running());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GAPI_Streaming_Desync, Python_Pull_Overload)
|
||||||
|
{
|
||||||
|
cv::GMat in;
|
||||||
|
cv::GMat out = cv::gapi::streaming::desync(in);
|
||||||
|
cv::GComputation c(in, out);
|
||||||
|
|
||||||
|
cv::Size sz(3,3);
|
||||||
|
cv::Mat in_mat(sz, CV_8UC3);
|
||||||
|
cv::randu(in_mat, cv::Scalar::all(0), cv::Scalar(255));
|
||||||
|
|
||||||
|
auto ccomp = c.compileStreaming();
|
||||||
|
|
||||||
|
EXPECT_TRUE(ccomp);
|
||||||
|
EXPECT_FALSE(ccomp.running());
|
||||||
|
|
||||||
|
ccomp.setSource(cv::gin(in_mat));
|
||||||
|
|
||||||
|
ccomp.start();
|
||||||
|
EXPECT_TRUE(ccomp.running());
|
||||||
|
|
||||||
|
bool has_output;
|
||||||
|
cv::GRunArgs outputs;
|
||||||
|
using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
|
||||||
|
RunArgs args;
|
||||||
|
|
||||||
|
std::tie(has_output, args) = ccomp.pull();
|
||||||
|
|
||||||
|
checkPullOverload(in_mat, has_output, args);
|
||||||
|
|
||||||
ccomp.stop();
|
ccomp.stop();
|
||||||
EXPECT_FALSE(ccomp.running());
|
EXPECT_FALSE(ccomp.running());
|
||||||
@@ -2132,9 +2193,17 @@ TEST(GAPI_Streaming, TestPythonAPI)
|
|||||||
|
|
||||||
bool is_over = false;
|
bool is_over = false;
|
||||||
cv::GRunArgs out_args;
|
cv::GRunArgs out_args;
|
||||||
|
using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
|
||||||
|
RunArgs args;
|
||||||
|
|
||||||
// NB: Used by python bridge
|
// NB: Used by python bridge
|
||||||
std::tie(is_over, out_args) = cc.pull();
|
std::tie(is_over, args) = cc.pull();
|
||||||
|
|
||||||
|
switch (args.index()) {
|
||||||
|
case RunArgs::index_of<cv::GRunArgs>():
|
||||||
|
out_args = util::get<cv::GRunArgs>(args); break;
|
||||||
|
default: GAPI_Assert(false && "Incorrect type of return value");
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT_EQ(1u, out_args.size());
|
ASSERT_EQ(1u, out_args.size());
|
||||||
ASSERT_TRUE(cv::util::holds_alternative<cv::Mat>(out_args[0]));
|
ASSERT_TRUE(cv::util::holds_alternative<cv::Mat>(out_args[0]));
|
||||||
@@ -2145,4 +2214,69 @@ TEST(GAPI_Streaming, TestPythonAPI)
|
|||||||
cc.stop();
|
cc.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(GAPI_Streaming, TestDesyncRMat) {
|
||||||
|
cv::GMat in;
|
||||||
|
auto blurred = cv::gapi::blur(in, cv::Size{3,3});
|
||||||
|
auto desynced = cv::gapi::streaming::desync(blurred);
|
||||||
|
auto out = in - blurred;
|
||||||
|
auto pipe = cv::GComputation(cv::GIn(in), cv::GOut(desynced, out)).compileStreaming();
|
||||||
|
|
||||||
|
cv::Size sz(32,32);
|
||||||
|
cv::Mat in_mat(sz, CV_8UC3);
|
||||||
|
cv::randu(in_mat, cv::Scalar::all(0), cv::Scalar(255));
|
||||||
|
pipe.setSource(cv::gin(in_mat));
|
||||||
|
pipe.start();
|
||||||
|
|
||||||
|
cv::optional<cv::RMat> out_desync;
|
||||||
|
cv::optional<cv::RMat> out_rmat;
|
||||||
|
while (true) {
|
||||||
|
// Initially it throwed "bad variant access" since there was
|
||||||
|
// no RMat handling in wrap_opt_arg
|
||||||
|
EXPECT_NO_THROW(pipe.pull(cv::gout(out_desync, out_rmat)));
|
||||||
|
if (out_rmat) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
G_API_OP(GTestBlur, <GFrame(GFrame)>, "test.blur") {
|
||||||
|
static GFrameDesc outMeta(GFrameDesc d) { return d; }
|
||||||
|
};
|
||||||
|
GAPI_OCV_KERNEL(GOcvTestBlur, GTestBlur) {
|
||||||
|
static void run(const cv::MediaFrame& in, cv::MediaFrame& out) {
|
||||||
|
auto d = in.desc();
|
||||||
|
GAPI_Assert(d.fmt == cv::MediaFormat::BGR);
|
||||||
|
auto view = in.access(cv::MediaFrame::Access::R);
|
||||||
|
cv::Mat mat(d.size, CV_8UC3, view.ptr[0]);
|
||||||
|
cv::Mat blurred;
|
||||||
|
cv::blur(mat, blurred, cv::Size{3,3});
|
||||||
|
out = cv::MediaFrame::Create<TestMediaBGR>(blurred);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(GAPI_Streaming, TestDesyncMediaFrame) {
|
||||||
|
initTestDataPath();
|
||||||
|
cv::GFrame in;
|
||||||
|
auto blurred = GTestBlur::on(in);
|
||||||
|
auto desynced = cv::gapi::streaming::desync(blurred);
|
||||||
|
auto out = GTestBlur::on(blurred);
|
||||||
|
auto pipe = cv::GComputation(cv::GIn(in), cv::GOut(desynced, out))
|
||||||
|
.compileStreaming(cv::compile_args(cv::gapi::kernels<GOcvTestBlur>()));
|
||||||
|
|
||||||
|
std::string filepath = findDataFile("cv/video/768x576.avi");
|
||||||
|
try {
|
||||||
|
pipe.setSource<BGRSource>(filepath);
|
||||||
|
} catch(...) {
|
||||||
|
throw SkipTestException("Video file can not be opened");
|
||||||
|
}
|
||||||
|
pipe.start();
|
||||||
|
|
||||||
|
cv::optional<cv::MediaFrame> out_desync;
|
||||||
|
cv::optional<cv::MediaFrame> out_frame;
|
||||||
|
while (true) {
|
||||||
|
// Initially it throwed "bad variant access" since there was
|
||||||
|
// no MediaFrame handling in wrap_opt_arg
|
||||||
|
EXPECT_NO_THROW(pipe.pull(cv::gout(out_desync, out_frame)));
|
||||||
|
if (out_frame) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace opencv_test
|
} // namespace opencv_test
|
||||||
|
|||||||
@@ -2219,12 +2219,6 @@ static PyMethodDef special_methods[] = {
|
|||||||
#ifdef HAVE_OPENCV_DNN
|
#ifdef HAVE_OPENCV_DNN
|
||||||
{"dnn_registerLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_registerLayer), "registerLayer(type, class) -> None"},
|
{"dnn_registerLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_registerLayer), "registerLayer(type, class) -> None"},
|
||||||
{"dnn_unregisterLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_unregisterLayer), "unregisterLayer(type) -> None"},
|
{"dnn_unregisterLayer", CV_PY_FN_WITH_KW(pyopencv_cv_dnn_unregisterLayer), "unregisterLayer(type) -> None"},
|
||||||
#endif
|
|
||||||
#ifdef HAVE_OPENCV_GAPI
|
|
||||||
{"GIn", CV_PY_FN_WITH_KW(pyopencv_cv_GIn), "GIn(...) -> GInputProtoArgs"},
|
|
||||||
{"GOut", CV_PY_FN_WITH_KW(pyopencv_cv_GOut), "GOut(...) -> GOutputProtoArgs"},
|
|
||||||
{"gin", CV_PY_FN_WITH_KW(pyopencv_cv_gin), "gin(...) -> ExtractArgsCallback"},
|
|
||||||
{"descr_of", CV_PY_FN_WITH_KW(pyopencv_cv_descr_of), "descr_of(...) -> ExtractMetaCallback"},
|
|
||||||
#endif
|
#endif
|
||||||
{NULL, NULL},
|
{NULL, NULL},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -832,6 +832,7 @@ class CppHeaderParser(object):
|
|||||||
("GAPI_EXPORTS_W_SIMPLE","CV_EXPORTS_W_SIMPLE"),
|
("GAPI_EXPORTS_W_SIMPLE","CV_EXPORTS_W_SIMPLE"),
|
||||||
("GAPI_WRAP", "CV_WRAP"),
|
("GAPI_WRAP", "CV_WRAP"),
|
||||||
("GAPI_PROP", "CV_PROP"),
|
("GAPI_PROP", "CV_PROP"),
|
||||||
|
("GAPI_PROP_RW", "CV_PROP_RW"),
|
||||||
('defined(GAPI_STANDALONE)', '0'),
|
('defined(GAPI_STANDALONE)', '0'),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user