1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-25 21:33:04 +04:00

Compare commits

..

2 Commits

Author SHA1 Message Date
Vincent Rabaud fd2b5411e4 Fix potential NaN in cv::norm.
There can be an int overflow.
cv::norm( InputArray _src, int normType, InputArray _mask ) is fine,
not cv::norm( InputArray _src1, InputArray _src2, int normType, InputArray _mask ).
2021-06-15 21:21:21 +03:00
Alexander Alekhin dd66cccbbd OpenCV version '-openvino' 2021-06-10 16:51:21 +03:00
136 changed files with 3975 additions and 7747 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
/*************************************************
USAGE:
./model_diagnostics -m <model file location>
./model_diagnostics -m <onnx file location>
**************************************************/
#include <opencv2/dnn.hpp>
#include <opencv2/core/utils/filesystem.hpp>
@@ -32,7 +32,7 @@ static std::string checkFileExists(const std::string& fileName)
}
std::string diagnosticKeys =
"{ model m | | Path to the model file. }"
"{ model m | | Path to the model .onnx file. }"
"{ config c | | Path to the model configuration file. }"
"{ framework f | | [Optional] Name of the model framework. }";
@@ -41,7 +41,7 @@ std::string diagnosticKeys =
int main( int argc, const char** argv )
{
CommandLineParser argParser(argc, argv, diagnosticKeys);
argParser.about("Use this tool to run the diagnostics of provided ONNX/TF model"
argParser.about("Use this tool to run the diagnostics of provided ONNX model"
"to obtain the information about its support (supported layers).");
if (argc == 1)
+1 -7
View File
@@ -179,13 +179,7 @@ if(CV_GCC OR CV_CLANG)
endif()
# We need pthread's
if((UNIX
AND NOT ANDROID
AND NOT (APPLE AND CV_CLANG)
AND NOT EMSCRIPTEN
)
OR (EMSCRIPTEN AND WITH_PTHREADS_PF) # https://github.com/opencv/opencv/issues/20285
)
if(UNIX AND NOT ANDROID AND NOT (APPLE AND CV_CLANG)) # TODO
add_extra_compiler_option(-pthread)
endif()
+11 -13
View File
@@ -9,14 +9,9 @@ set(HALIDE_ROOT_DIR "${HALIDE_ROOT_DIR}" CACHE PATH "Halide root directory")
if(NOT HAVE_HALIDE)
find_package(Halide QUIET) # Try CMake-based config files
if(Halide_FOUND)
if(TARGET Halide::Halide) # modern Halide scripts defines imported target
set(HALIDE_INCLUDE_DIRS "")
set(HALIDE_LIBRARIES "Halide::Halide")
set(HAVE_HALIDE TRUE)
else()
# using HALIDE_INCLUDE_DIRS / Halide_LIBRARIES
set(HAVE_HALIDE TRUE)
endif()
set(HALIDE_INCLUDE_DIRS "${Halide_INCLUDE_DIRS}" CACHE PATH "Halide include directories" FORCE)
set(HALIDE_LIBRARIES "${Halide_LIBRARIES}" CACHE PATH "Halide libraries" FORCE)
set(HAVE_HALIDE TRUE)
endif()
endif()
@@ -33,15 +28,18 @@ if(NOT HAVE_HALIDE AND HALIDE_ROOT_DIR)
)
if(HALIDE_LIBRARY AND HALIDE_INCLUDE_DIR)
# TODO try_compile
set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}")
set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}")
set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}" CACHE PATH "Halide include directories" FORCE)
set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}" CACHE PATH "Halide libraries" FORCE)
set(HAVE_HALIDE TRUE)
endif()
if(NOT HAVE_HALIDE)
ocv_clear_vars(HALIDE_LIBRARIES HALIDE_INCLUDE_DIRS CACHE)
endif()
endif()
if(HAVE_HALIDE)
if(HALIDE_INCLUDE_DIRS)
include_directories(${HALIDE_INCLUDE_DIRS})
endif()
include_directories(${HALIDE_INCLUDE_DIRS})
list(APPEND OPENCV_LINKER_LIBS ${HALIDE_LIBRARIES})
else()
ocv_clear_vars(HALIDE_INCLUDE_DIRS HALIDE_LIBRARIES)
endif()
+7 -12
View File
@@ -134,21 +134,16 @@ endif()
# Add more features to the target
if(INF_ENGINE_TARGET)
if(DEFINED InferenceEngine_VERSION)
message(STATUS "InferenceEngine: ${InferenceEngine_VERSION}")
if(NOT INF_ENGINE_RELEASE AND NOT (InferenceEngine_VERSION VERSION_LESS "2021.4"))
math(EXPR INF_ENGINE_RELEASE_INIT "${InferenceEngine_VERSION_MAJOR} * 1000000 + ${InferenceEngine_VERSION_MINOR} * 10000 + ${InferenceEngine_VERSION_PATCH} * 100")
endif()
if(InferenceEngine_VERSION VERSION_GREATER_EQUAL "2021.4")
math(EXPR INF_ENGINE_RELEASE "${InferenceEngine_VERSION_MAJOR} * 1000000 + ${InferenceEngine_VERSION_MINOR} * 10000 + ${InferenceEngine_VERSION_PATCH} * 100")
endif()
if(NOT INF_ENGINE_RELEASE AND NOT INF_ENGINE_RELEASE_INIT)
message(WARNING "InferenceEngine version has not been set, 2021.4 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
set(INF_ENGINE_RELEASE_INIT "2021040000")
elseif(DEFINED INF_ENGINE_RELEASE)
set(INF_ENGINE_RELEASE_INIT "${INF_ENGINE_RELEASE}")
if(NOT INF_ENGINE_RELEASE)
message(WARNING "InferenceEngine version has not been set, 2021.3 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
set(INF_ENGINE_RELEASE "2021030000")
endif()
set(INF_ENGINE_RELEASE "${INF_ENGINE_RELEASE_INIT}" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
set(INF_ENGINE_RELEASE "${INF_ENGINE_RELEASE}" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
)
endif()
+9
View File
@@ -2,6 +2,15 @@
# Detect 3rd-party GUI libraries
# ----------------------------------------------------------------------------
#--- Win32 UI ---
ocv_clear_vars(HAVE_WIN32UI)
if(WITH_WIN32UI)
try_compile(HAVE_WIN32UI
"${OpenCV_BINARY_DIR}"
"${OpenCV_SOURCE_DIR}/cmake/checks/win32uitest.cpp"
CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32")
endif()
# --- QT4/5 ---
ocv_clear_vars(HAVE_QT HAVE_QT5)
if(WITH_QT)
+3
View File
@@ -121,6 +121,9 @@
/* TIFF codec */
#cmakedefine HAVE_TIFF
/* Win32 UI */
#cmakedefine HAVE_WIN32UI
/* Define if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#cmakedefine WORDS_BIGENDIAN
+1 -1
View File
@@ -106,7 +106,7 @@ RECURSIVE = YES
EXCLUDE = @CMAKE_DOXYGEN_EXCLUDE_LIST@
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = *.inl.hpp *.impl.hpp *_detail.hpp */cudev/**/detail/*.hpp *.m */opencl/runtime/* */legacy/* *_c.h @DOXYGEN_EXCLUDE_PATTERNS@
EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__* T __CV* cv::gapi::detail*
EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__* T __CV*
EXAMPLE_PATH = @CMAKE_DOXYGEN_EXAMPLE_PATH@
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = YES
+1 -1
View File
@@ -3924,7 +3924,7 @@ bool findChessboardCornersSB(cv::InputArray image_, cv::Size pattern_size,
{
meta_.create(int(board.rowCount()),int(board.colCount()),CV_8UC1);
cv::Mat meta = meta_.getMat();
meta.setTo(cv::Scalar::all(0));
meta = 0;
for(int row =0;row < meta.rows-1;++row)
{
for(int col=0;col< meta.cols-1;++col)
+4 -78
View File
@@ -897,7 +897,7 @@ void CV_InitInverseRectificationMapTest::prepare_to_validation(int/* test_case_i
Mat _new_cam0 = zero_new_cam ? test_mat[INPUT][0] : test_mat[INPUT][3];
Mat _mapx(img_size, CV_32F), _mapy(img_size, CV_32F);
double a[9], d[5]={0., 0., 0., 0. , 0.}, R[9]={1., 0., 0., 0., 1., 0., 0., 0., 1.}, a1[9];
double a[9], d[5]={0,0,0,0,0}, R[9]={1, 0, 0, 0, 1, 0, 0, 0, 1}, a1[9];
Mat _a(3, 3, CV_64F, a), _a1(3, 3, CV_64F, a1);
Mat _d(_d0.rows,_d0.cols, CV_MAKETYPE(CV_64F,_d0.channels()),d);
Mat _R(3, 3, CV_64F, R);
@@ -951,9 +951,9 @@ void CV_InitInverseRectificationMapTest::prepare_to_validation(int/* test_case_i
// Undistort
double x2 = x*x, y2 = y*y;
double r2 = x2 + y2;
double cdist = 1./(1. + (d[0] + (d[1] + d[4]*r2)*r2)*r2); // (1. + (d[5] + (d[6] + d[7]*r2)*r2)*r2) == 1 as d[5-7]=0;
double x_ = (x - (d[2]*2.*x*y + d[3]*(r2 + 2.*x2)))*cdist;
double y_ = (y - (d[3]*2.*x*y + d[2]*(r2 + 2.*y2)))*cdist;
double cdist = 1./(1 + (d[0] + (d[1] + d[4]*r2)*r2)*r2); // (1 + (d[5] + (d[6] + d[7]*r2)*r2)*r2) == 1 as d[5-7]=0;
double x_ = x*cdist - d[2]*2*x*y + d[3]*(r2 + 2*x2);
double y_ = y*cdist - d[3]*2*x*y + d[2]*(r2 + 2*y2);
// Rectify
double X = R[0]*x_ + R[1]*y_ + R[2];
@@ -1807,78 +1807,4 @@ TEST(Calib3d_initUndistortRectifyMap, regression_14467)
EXPECT_LE(cvtest::norm(dst, mesh_uv, NORM_INF), 1e-3);
}
TEST(Calib3d_initInverseRectificationMap, regression_20165)
{
Size size_w_h(1280, 800);
Mat dst(size_w_h, CV_32FC2); // Reference for validation
Mat mapxy; // Output of initInverseRectificationMap()
// Camera Matrix
double k[9]={
1.5393951443032472e+03, 0., 6.7491727003047140e+02,
0., 1.5400748240626747e+03, 5.1226968329123963e+02,
0., 0., 1.
};
Mat _K(3, 3, CV_64F, k);
// Distortion
// double d[5]={0,0,0,0,0}; // Zero Distortion
double d[5]={ // Non-zero distortion
-3.4134571357400023e-03, 2.9733267766101856e-03, // K1, K2
3.6653586399031184e-03, -3.1960714017365702e-03, // P1, P2
0. // K3
};
Mat _d(1, 5, CV_64F, d);
// Rotation
//double R[9]={1., 0., 0., 0., 1., 0., 0., 0., 1.}; // Identity transform (none)
double R[9]={ // Random transform
9.6625486010428052e-01, 1.6055789378989216e-02, 2.5708706103628531e-01,
-8.0300261706161002e-03, 9.9944797497929860e-01, -3.2237617614807819e-02,
-2.5746274294459848e-01, 2.9085338870243265e-02, 9.6585039165403186e-01
};
Mat _R(3, 3, CV_64F, R);
// --- Validation --- //
initInverseRectificationMap(_K, _d, _R, _K, size_w_h, CV_32FC2, mapxy, noArray());
// Copy camera matrix
double fx, fy, cx, cy, ifx, ify, cxn, cyn;
fx = k[0]; fy = k[4]; cx = k[2]; cy = k[5];
// Copy new camera matrix
ifx = k[0]; ify = k[4]; cxn = k[2]; cyn = k[5];
// Distort Points
for( int v = 0; v < size_w_h.height; v++ )
{
for( int u = 0; u < size_w_h.width; u++ )
{
// Convert from image to pin-hole coordinates
double x = (u - cx)/fx;
double y = (v - cy)/fy;
// Undistort
double x2 = x*x, y2 = y*y;
double r2 = x2 + y2;
double cdist = 1./(1. + (d[0] + (d[1] + d[4]*r2)*r2)*r2); // (1. + (d[5] + (d[6] + d[7]*r2)*r2)*r2) == 1 as d[5-7]=0;
double x_ = (x - (d[2]*2.*x*y + d[3]*(r2 + 2.*x2)))*cdist;
double y_ = (y - (d[3]*2.*x*y + d[2]*(r2 + 2.*y2)))*cdist;
// Rectify
double X = R[0]*x_ + R[1]*y_ + R[2];
double Y = R[3]*x_ + R[4]*y_ + R[5];
double Z = R[6]*x_ + R[7]*y_ + R[8];
double x__ = X/Z;
double y__ = Y/Z;
// Convert from pin-hole to image coordinates
dst.at<Vec2f>(v, u) = Vec2f((float)(x__*ifx + cxn), (float)(y__*ify + cyn));
}
}
// Check Result
EXPECT_LE(cvtest::norm(dst, mapxy, NORM_INF), 2e-1);
}
}} // namespace
+9 -18
View File
@@ -2451,8 +2451,7 @@ public:
//! <0 - a diagonal from the lower half)
UMat diag(int d=0) const;
//! constructs a square diagonal matrix which main diagonal is vector "d"
static UMat diag(const UMat& d, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat diag(const UMat& d) { return diag(d, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat diag(const UMat& d);
//! returns deep copy of the matrix, i.e. the data is copied
UMat clone() const CV_NODISCARD;
@@ -2486,22 +2485,14 @@ public:
double dot(InputArray m) const;
//! Matlab-style matrix initialization
static UMat zeros(int rows, int cols, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat zeros(Size size, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat zeros(int ndims, const int* sz, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat zeros(int rows, int cols, int type) { return zeros(rows, cols, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat zeros(Size size, int type) { return zeros(size, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat zeros(int ndims, const int* sz, int type) { return zeros(ndims, sz, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat ones(int rows, int cols, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat ones(Size size, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat ones(int ndims, const int* sz, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat ones(int rows, int cols, int type) { return ones(rows, cols, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat ones(Size size, int type) { return ones(size, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat ones(int ndims, const int* sz, int type) { return ones(ndims, sz, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat eye(int rows, int cols, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat eye(Size size, int type, UMatUsageFlags usageFlags /*= USAGE_DEFAULT*/);
static UMat eye(int rows, int cols, int type) { return eye(rows, cols, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat eye(Size size, int type) { return eye(size, type, USAGE_DEFAULT); } // OpenCV 5.0: remove abi compatibility overload
static UMat zeros(int rows, int cols, int type);
static UMat zeros(Size size, int type);
static UMat zeros(int ndims, const int* sz, int type);
static UMat ones(int rows, int cols, int type);
static UMat ones(Size size, int type);
static UMat ones(int ndims, const int* sz, int type);
static UMat eye(int rows, int cols, int type);
static UMat eye(Size size, int type);
//! allocates new matrix data unless the matrix already has specified size and type.
// previous data is unreferenced if needed.
@@ -144,10 +144,6 @@ static void dumpOpenCLInformation()
DUMP_MESSAGE_STDOUT(" Double support = " << doubleSupportStr);
DUMP_CONFIG_PROPERTY("cv_ocl_current_haveDoubleSupport", device.doubleFPConfig() > 0);
const char* halfSupportStr = device.halfFPConfig() > 0 ? "Yes" : "No";
DUMP_MESSAGE_STDOUT(" Half support = " << halfSupportStr);
DUMP_CONFIG_PROPERTY("cv_ocl_current_haveHalfSupport", device.halfFPConfig() > 0);
const char* isUnifiedMemoryStr = device.hostUnifiedMemory() ? "Yes" : "No";
DUMP_MESSAGE_STDOUT(" Host unified memory = " << isUnifiedMemoryStr);
DUMP_CONFIG_PROPERTY("cv_ocl_current_hostUnifiedMemory", device.hostUnifiedMemory());
@@ -195,9 +191,6 @@ static void dumpOpenCLInformation()
DUMP_MESSAGE_STDOUT(" Preferred vector width double = " << device.preferredVectorWidthDouble());
DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthDouble", device.preferredVectorWidthDouble());
DUMP_MESSAGE_STDOUT(" Preferred vector width half = " << device.preferredVectorWidthHalf());
DUMP_CONFIG_PROPERTY("cv_ocl_current_preferredVectorWidthHalf", device.preferredVectorWidthHalf());
}
catch (...)
{
@@ -16,8 +16,8 @@
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1
# elif defined(__APPLE__)
# include <TargetConditionals.h>
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS)
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX, iOS only
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (!defined(TARGET_OS_OSX) && !TARGET_OS_IPHONE)
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX only
# endif
# else
/* unknown */
@@ -8,7 +8,7 @@
#define CV_VERSION_MAJOR 4
#define CV_VERSION_MINOR 5
#define CV_VERSION_REVISION 3
#define CV_VERSION_STATUS ""
#define CV_VERSION_STATUS "-openvino"
#define CVAUX_STR_EXP(__A) #__A
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
+16 -77
View File
@@ -3,16 +3,6 @@ package org.opencv.core
import org.opencv.core.Mat.*
import java.lang.RuntimeException
fun Mat.get(row: Int, col: Int, data: UByteArray) = this.get(row, col, data.asByteArray())
fun Mat.get(indices: IntArray, data: UByteArray) = this.get(indices, data.asByteArray())
fun Mat.put(row: Int, col: Int, data: UByteArray) = this.put(row, col, data.asByteArray())
fun Mat.put(indices: IntArray, data: UByteArray) = this.put(indices, data.asByteArray())
fun Mat.get(row: Int, col: Int, data: UShortArray) = this.get(row, col, data.asShortArray())
fun Mat.get(indices: IntArray, data: UShortArray) = this.get(indices, data.asShortArray())
fun Mat.put(row: Int, col: Int, data: UShortArray) = this.put(row, col, data.asShortArray())
fun Mat.put(indices: IntArray, data: UShortArray) = this.put(indices, data.asShortArray())
/***
* Example use:
*
@@ -29,7 +19,6 @@ inline fun <reified T> Mat.at(row: Int, col: Int) : Atable<T> =
col
)
UByte::class -> AtableUByte(this, row, col) as Atable<T>
UShort::class -> AtableUShort(this, row, col) as Atable<T>
else -> throw RuntimeException("Unsupported class type")
}
@@ -41,7 +30,6 @@ inline fun <reified T> Mat.at(idx: IntArray) : Atable<T> =
idx
)
UByte::class -> AtableUByte(this, idx) as Atable<T>
UShort::class -> AtableUShort(this, idx) as Atable<T>
else -> throw RuntimeException("Unsupported class type")
}
@@ -50,95 +38,46 @@ class AtableUByte(val mat: Mat, val indices: IntArray): Atable<UByte> {
constructor(mat: Mat, row: Int, col: Int) : this(mat, intArrayOf(row, col))
override fun getV(): UByte {
val data = UByteArray(1)
mat.get(indices, data)
return data[0]
val data = ByteArray(1)
mat[indices, data]
return data[0].toUByte()
}
override fun setV(v: UByte) {
val data = ubyteArrayOf(v)
val data = byteArrayOf(v.toByte())
mat.put(indices, data)
}
override fun getV2c(): Tuple2<UByte> {
val data = UByteArray(2)
mat.get(indices, data)
return Tuple2(data[0], data[1])
val data = ByteArray(2)
mat[indices, data]
return Tuple2(data[0].toUByte(), data[1].toUByte())
}
override fun setV2c(v: Tuple2<UByte>) {
val data = ubyteArrayOf(v._0, v._1)
val data = byteArrayOf(v._0.toByte(), v._1.toByte())
mat.put(indices, data)
}
override fun getV3c(): Tuple3<UByte> {
val data = UByteArray(3)
mat.get(indices, data)
return Tuple3(data[0], data[1], data[2])
val data = ByteArray(3)
mat[indices, data]
return Tuple3(data[0].toUByte(), data[1].toUByte(), data[2].toUByte())
}
override fun setV3c(v: Tuple3<UByte>) {
val data = ubyteArrayOf(v._0, v._1, v._2)
val data = byteArrayOf(v._0.toByte(), v._1.toByte(), v._2.toByte())
mat.put(indices, data)
}
override fun getV4c(): Tuple4<UByte> {
val data = UByteArray(4)
mat.get(indices, data)
return Tuple4(data[0], data[1], data[2], data[3])
val data = ByteArray(4)
mat[indices, data]
return Tuple4(data[0].toUByte(), data[1].toUByte(), data[2].toUByte(), data[3].toUByte())
}
override fun setV4c(v: Tuple4<UByte>) {
val data = ubyteArrayOf(v._0, v._1, v._2, v._3)
mat.put(indices, data)
}
}
class AtableUShort(val mat: Mat, val indices: IntArray): Atable<UShort> {
constructor(mat: Mat, row: Int, col: Int) : this(mat, intArrayOf(row, col))
override fun getV(): UShort {
val data = UShortArray(1)
mat.get(indices, data)
return data[0]
}
override fun setV(v: UShort) {
val data = ushortArrayOf(v)
mat.put(indices, data)
}
override fun getV2c(): Tuple2<UShort> {
val data = UShortArray(2)
mat.get(indices, data)
return Tuple2(data[0], data[1])
}
override fun setV2c(v: Tuple2<UShort>) {
val data = ushortArrayOf(v._0, v._1)
mat.put(indices, data)
}
override fun getV3c(): Tuple3<UShort> {
val data = UShortArray(3)
mat.get(indices, data)
return Tuple3(data[0], data[1], data[2])
}
override fun setV3c(v: Tuple3<UShort>) {
val data = ushortArrayOf(v._0, v._1, v._2)
mat.put(indices, data)
}
override fun getV4c(): Tuple4<UShort> {
val data = UShortArray(4)
mat.get(indices, data)
return Tuple4(data[0], data[1], data[2], data[3])
}
override fun setV4c(v: Tuple4<UShort>) {
val data = ushortArrayOf(v._0, v._1, v._2, v._3)
val data = byteArrayOf(v._0.toByte(), v._1.toByte(), v._2.toByte(), v._3.toByte())
mat.put(indices, data)
}
}
+1 -1
View File
@@ -548,7 +548,7 @@ template<typename T> void putData(uchar* dataDest, int count, T (^readData)(int)
if (depth == CV_8U) {
putData(dest, count, ^uchar (int index) { return cv::saturate_cast<uchar>(data[offset + index].doubleValue);} );
} else if (depth == CV_8S) {
putData(dest, count, ^schar (int index) { return cv::saturate_cast<schar>(data[offset + index].doubleValue);} );
putData(dest, count, ^char (int index) { return cv::saturate_cast<char>(data[offset + index].doubleValue);} );
} else if (depth == CV_16U) {
putData(dest, count, ^ushort (int index) { return cv::saturate_cast<ushort>(data[offset + index].doubleValue);} );
} else if (depth == CV_16S) {
+12 -134
View File
@@ -62,21 +62,6 @@ public extension Mat {
}
}
@discardableResult func get(indices:[Int32], data:inout [UInt8]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_8U {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
body.withMemoryRebound(to: Int8.self) { reboundBody in
return __get(indices as [NSNumber], count: count, byteBuffer: reboundBody.baseAddress!)
}
}
}
@discardableResult func get(indices:[Int32], data:inout [Double]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
@@ -129,29 +114,10 @@ public extension Mat {
}
}
@discardableResult func get(indices:[Int32], data:inout [UInt16]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_16U {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeMutableBufferPointer { body in
body.withMemoryRebound(to: Int16.self) { reboundBody in
return __get(indices as [NSNumber], count: count, shortBuffer: reboundBody.baseAddress!)
}
}
}
@discardableResult func get(row: Int32, col: Int32, data:inout [Int8]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [UInt8]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [Double]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@@ -168,10 +134,6 @@ public extension Mat {
return try get(indices: [row, col], data: &data)
}
@discardableResult func get(row: Int32, col: Int32, data:inout [UInt16]) throws -> Int32 {
return try get(indices: [row, col], data: &data)
}
@discardableResult func put(indices:[Int32], data:[Int8]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
@@ -185,21 +147,6 @@ public extension Mat {
}
}
@discardableResult func put(indices:[Int32], data:[UInt8]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_8U {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
body.withMemoryRebound(to: Int8.self) { reboundBody in
return __put(indices as [NSNumber], count: count, byteBuffer: reboundBody.baseAddress!)
}
}
}
@discardableResult func put(indices:[Int32], data:[Int8], offset: Int, length: Int32) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
@@ -267,29 +214,10 @@ public extension Mat {
}
}
@discardableResult func put(indices:[Int32], data:[UInt16]) throws -> Int32 {
let channels = CvType.channels(Int32(type()))
if Int32(data.count) % channels != 0 {
try throwIncompatibleBufferSize(count: data.count, channels: channels)
} else if depth() != CvType.CV_16U {
try throwIncompatibleDataType(typeName: CvType.type(toString: type()))
}
let count = Int32(data.count)
return data.withUnsafeBufferPointer { body in
body.withMemoryRebound(to: Int16.self) { reboundBody in
return __put(indices as [NSNumber], count: count, shortBuffer: reboundBody.baseAddress!)
}
}
}
@discardableResult func put(row: Int32, col: Int32, data:[Int8]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data:[UInt8]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data: [Int8], offset: Int, length: Int32) throws -> Int32 {
return try put(indices: [row, col], data: data, offset: offset, length: length)
}
@@ -310,10 +238,6 @@ public extension Mat {
return try put(indices: [row, col], data: data)
}
@discardableResult func put(row: Int32, col: Int32, data: [UInt16]) throws -> Int32 {
return try put(indices: [row, col], data: data)
}
@discardableResult func get(row: Int32, col: Int32) -> [Double] {
return get(indices: [row, col])
}
@@ -379,46 +303,46 @@ public class MatAt<N: Atable> {
extension UInt8: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> UInt8 {
var tmp = [UInt8](repeating: 0, count: 1)
var tmp = [Int8](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
return UInt8(bitPattern: tmp[0])
}
public static func putAt(m: Mat, indices: [Int32], v: UInt8) {
let tmp = [v]
let tmp = [Int8(bitPattern: v)]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt8, UInt8) {
var tmp = [UInt8](repeating: 0, count: 2)
var tmp = [Int8](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]))
}
public static func putAt2c(m: Mat, indices: [Int32], v: (UInt8, UInt8)) {
let tmp = [v.0, v.1]
let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1)]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8) {
var tmp = [UInt8](repeating: 0, count: 3)
var tmp = [Int8](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]), UInt8(bitPattern: tmp[2]))
}
public static func putAt3c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8)) {
let tmp = [v.0, v.1, v.2]
let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1), Int8(bitPattern: v.2)]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8, UInt8) {
var tmp = [UInt8](repeating: 0, count: 4)
var tmp = [Int8](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]), UInt8(bitPattern: tmp[2]), UInt8(bitPattern: tmp[3]))
}
public static func putAt4c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8, UInt8)) {
let tmp = [v.0, v.1, v.2, v.3]
let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1), Int8(bitPattern: v.2), Int8(bitPattern: v.3)]
try! m.put(indices: indices, data: tmp)
}
}
@@ -607,52 +531,6 @@ extension Int32: Atable {
}
}
extension UInt16: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> UInt16 {
var tmp = [UInt16](repeating: 0, count: 1)
try! m.get(indices: indices, data: &tmp)
return tmp[0]
}
public static func putAt(m: Mat, indices: [Int32], v: UInt16) {
let tmp = [v]
try! m.put(indices: indices, data: tmp)
}
public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt16, UInt16) {
var tmp = [UInt16](repeating: 0, count: 2)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1])
}
public static func putAt2c(m: Mat, indices: [Int32], v: (UInt16, UInt16)) {
let tmp = [v.0, v.1]
try! m.put(indices: indices, data: tmp)
}
public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt16, UInt16, UInt16) {
var tmp = [UInt16](repeating: 0, count: 3)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2])
}
public static func putAt3c(m: Mat, indices: [Int32], v: (UInt16, UInt16, UInt16)) {
let tmp = [v.0, v.1, v.2]
try! m.put(indices: indices, data: tmp)
}
public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt16, UInt16, UInt16, UInt16) {
var tmp = [UInt16](repeating: 0, count: 4)
try! m.get(indices: indices, data: &tmp)
return (tmp[0], tmp[1], tmp[2], tmp[3])
}
public static func putAt4c(m: Mat, indices: [Int32], v: (UInt16, UInt16, UInt16, UInt16)) {
let tmp = [v.0, v.1, v.2, v.3]
try! m.put(indices: indices, data: tmp)
}
}
extension Int16: Atable {
public static func getAt(m: Mat, indices:[Int32]) -> Int16 {
var tmp = [Int16](repeating: 0, count: 1)
+18 -154
View File
@@ -308,15 +308,15 @@ class MatTests: OpenCVTestCase {
XCTAssert([340] == sm.get(row: 1, col: 1))
}
func testGetIntIntInt8Array() throws {
let m = try getTestMat(size: 5, type: CvType.CV_8SC3)
func testGetIntIntByteArray() throws {
let m = try getTestMat(size: 5, type: CvType.CV_8UC3)
var goodData = [Int8](repeating: 0, count: 9)
// whole Mat
var bytesNum = try m.get(row: 1, col: 1, data: &goodData)
XCTAssertEqual(9, bytesNum)
XCTAssert([110, 111, 112, 120, 121, 122, 127, 127, 127] == goodData)
XCTAssert([110, 111, 112, 120, 121, 122, -126, -125, -124] == goodData)
var badData = [Int8](repeating: 0, count: 7)
XCTAssertThrowsError(bytesNum = try m.get(row: 0, col: 0, data: &badData))
@@ -326,36 +326,11 @@ class MatTests: OpenCVTestCase {
var buff00 = [Int8](repeating: 0, count: 3)
bytesNum = try sm.get(row: 0, col: 0, data: &buff00)
XCTAssertEqual(3, bytesNum)
XCTAssert(buff00 == [127, 127, 127])
XCTAssert(buff00 == [-26, -25, -24])
var buff11 = [Int8](repeating: 0, count: 3)
bytesNum = try sm.get(row: 1, col: 1, data: &buff11)
XCTAssertEqual(3, bytesNum)
XCTAssert(buff11 == [127, 127, 127])
}
func testGetIntIntUInt8Array() throws {
let m = try getTestMat(size: 5, type: CvType.CV_8UC3)
var goodData = [UInt8](repeating: 0, count: 9)
// whole Mat
var bytesNum = try m.get(row: 1, col: 1, data: &goodData)
XCTAssertEqual(9, bytesNum)
XCTAssert([110, 111, 112, 120, 121, 122, 130, 131, 132] == goodData)
var badData = [UInt8](repeating: 0, count: 7)
XCTAssertThrowsError(bytesNum = try m.get(row: 0, col: 0, data: &badData))
// sub-Mat
let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
var buff00 = [UInt8](repeating: 0, count: 3)
bytesNum = try sm.get(row: 0, col: 0, data: &buff00)
XCTAssertEqual(3, bytesNum)
XCTAssert(buff00 == [230, 231, 232])
var buff11 = [UInt8](repeating: 0, count: 3)
bytesNum = try sm.get(row: 1, col: 1, data: &buff11)
XCTAssertEqual(3, bytesNum)
XCTAssert(buff11 == [255, 255, 255])
XCTAssert(buff11 == [-1, -1, -1])
}
func testGetIntIntDoubleArray() throws {
@@ -424,7 +399,7 @@ class MatTests: OpenCVTestCase {
XCTAssert(buff11 == [340, 341, 0, 0])
}
func testGetIntIntInt16Array() throws {
func testGetIntIntShortArray() throws {
let m = try getTestMat(size: 5, type: CvType.CV_16SC2)
var buff = [Int16](repeating: 0, count: 6)
@@ -446,28 +421,6 @@ class MatTests: OpenCVTestCase {
XCTAssert(buff11 == [340, 341, 0, 0])
}
func testGetIntIntUInt16Array() throws {
let m = try getTestMat(size: 5, type: CvType.CV_16UC2)
var buff = [UInt16](repeating: 0, count: 6)
// whole Mat
var bytesNum = try m.get(row: 1, col: 1, data: &buff)
XCTAssertEqual(12, bytesNum);
XCTAssert(buff == [110, 111, 120, 121, 130, 131])
// sub-Mat
let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
var buff00 = [UInt16](repeating: 0, count: 4)
bytesNum = try sm.get(row: 0, col: 0, data: &buff00)
XCTAssertEqual(8, bytesNum)
XCTAssert(buff00 == [230, 231, 240, 241])
var buff11 = [UInt16](repeating: 0, count: 4)
bytesNum = try sm.get(row: 1, col: 1, data: &buff11)
XCTAssertEqual(4, bytesNum);
XCTAssert(buff11 == [340, 341, 0, 0])
}
func testHeight() {
XCTAssertEqual(gray0.rows(), gray0.height())
XCTAssertEqual(rgbLena.rows(), rgbLena.height())
@@ -700,7 +653,7 @@ class MatTests: OpenCVTestCase {
try assertMatEqual(truth!, m1, OpenCVTestCase.EPS)
}
func testPutIntIntInt8Array() throws {
func testPutIntIntByteArray() throws {
let m = Mat(rows: 5, cols: 5, type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
var buff = [Int8](repeating: 0, count: 6)
@@ -730,37 +683,7 @@ class MatTests: OpenCVTestCase {
XCTAssert(buff == buff0)
}
func testPutIntIntUInt8Array() throws {
let m = Mat(rows: 5, cols: 5, type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3))
let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
var buff = [UInt8](repeating: 0, count: 6)
let buff0:[UInt8] = [10, 20, 30, 40, 50, 60]
let buff1:[UInt8] = [255, 254, 253, 252, 251, 250]
var bytesNum = try m.put(row:1, col:2, data:buff0)
XCTAssertEqual(6, bytesNum)
bytesNum = try m.get(row: 1, col: 2, data: &buff)
XCTAssertEqual(6, bytesNum)
XCTAssert(buff == buff0)
bytesNum = try sm.put(row:0, col:0, data:buff1)
XCTAssertEqual(6, bytesNum)
bytesNum = try sm.get(row: 0, col: 0, data: &buff)
XCTAssertEqual(6, bytesNum)
XCTAssert(buff == buff1)
bytesNum = try m.get(row: 2, col: 3, data: &buff)
XCTAssertEqual(6, bytesNum);
XCTAssert(buff == buff1)
let m1 = m.row(1)
bytesNum = try m1.get(row: 0, col: 2, data: &buff)
XCTAssertEqual(6, bytesNum)
XCTAssert(buff == buff0)
}
func testPutIntArrayInt8Array() throws {
func testPutIntArrayByteArray() throws {
let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)])
var buff = [Int8](repeating: 0, count: 6)
@@ -791,41 +714,10 @@ class MatTests: OpenCVTestCase {
XCTAssert(buff == buff0)
}
func testPutIntArrayUInt8Array() throws {
let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3))
let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)])
var buff = [UInt8](repeating: 0, count: 6)
let buff0:[UInt8] = [10, 20, 30, 40, 50, 60]
let buff1:[UInt8] = [255, 254, 253, 252, 251, 250]
var bytesNum = try m.put(indices:[1, 2, 0], data:buff0)
XCTAssertEqual(6, bytesNum)
bytesNum = try m.get(indices: [1, 2, 0], data: &buff)
XCTAssertEqual(6, bytesNum)
XCTAssert(buff == buff0)
bytesNum = try sm.put(indices: [0, 0, 0], data: buff1)
XCTAssertEqual(6, bytesNum)
bytesNum = try sm.get(indices: [0, 0, 0], data: &buff)
XCTAssertEqual(6, bytesNum)
XCTAssert(buff == buff1)
bytesNum = try m.get(indices: [0, 1, 2], data: &buff)
XCTAssertEqual(6, bytesNum)
XCTAssert(buff == buff1)
let m1 = m.submat(ranges: [Range(start: 1,end: 2), Range.all(), Range.all()])
bytesNum = try m1.get(indices: [0, 2, 0], data: &buff)
XCTAssertEqual(6, bytesNum)
XCTAssert(buff == buff0)
}
func testPutIntIntDoubleArray() throws {
let m = Mat(rows: 5, cols: 5, type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3))
let m = Mat(rows: 5, cols: 5, type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
let sm = m.submat(rowStart: 2, rowEnd: 4, colStart: 3, colEnd: 5)
var buff = [UInt8](repeating: 0, count: 6)
var buff = [Int8](repeating: 0, count: 6)
var bytesNum = try m.put(row: 1, col: 2, data: [10, 20, 30, 40, 50, 60] as [Double])
@@ -839,16 +731,16 @@ class MatTests: OpenCVTestCase {
XCTAssertEqual(6, bytesNum)
bytesNum = try sm.get(row: 0, col: 0, data: &buff)
XCTAssertEqual(6, bytesNum);
XCTAssert(buff == [255, 254, 253, 252, 251, 250])
XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
bytesNum = try m.get(row: 2, col: 3, data: &buff)
XCTAssertEqual(6, bytesNum);
XCTAssert(buff == [255, 254, 253, 252, 251, 250])
XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
}
func testPutIntArrayDoubleArray() throws {
let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8UC3, scalar: Scalar(1, 2, 3))
let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
let sm = m.submat(ranges: [Range(start: 0, end: 2), Range(start: 1, end: 3), Range(start: 2, end: 4)])
var buff = [UInt8](repeating: 0, count: 6)
var buff = [Int8](repeating: 0, count: 6)
var bytesNum = try m.put(indices: [1, 2, 0], data: [10, 20, 30, 40, 50, 60] as [Double])
@@ -862,10 +754,10 @@ class MatTests: OpenCVTestCase {
XCTAssertEqual(6, bytesNum);
bytesNum = try sm.get(indices: [0, 0, 0], data: &buff)
XCTAssertEqual(6, bytesNum);
XCTAssert(buff == [255, 254, 253, 252, 251, 250])
XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
bytesNum = try m.get(indices: [0, 1, 2], data: &buff)
XCTAssertEqual(6, bytesNum)
XCTAssert(buff == [255, 254, 253, 252, 251, 250])
XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
}
func testPutIntIntFloatArray() throws {
@@ -928,7 +820,7 @@ class MatTests: OpenCVTestCase {
XCTAssert([40, 50, 60] == m.get(indices: [0, 1, 0]))
}
func testPutIntIntInt16Array() throws {
func testPutIntIntShortArray() throws {
let m = Mat(rows: 5, cols: 5, type: CvType.CV_16SC3, scalar: Scalar(-1, -2, -3))
let elements: [Int16] = [ 10, 20, 30, 40, 50, 60]
@@ -942,21 +834,7 @@ class MatTests: OpenCVTestCase {
XCTAssert([40, 50, 60] == m.get(row: 2, col: 4))
}
func testPutIntIntUInt16Array() throws {
let m = Mat(rows: 5, cols: 5, type: CvType.CV_16UC3, scalar: Scalar(-1, -2, -3))
let elements: [UInt16] = [ 10, 20, 30, 40, 50, 60]
var bytesNum = try m.put(row: 2, col: 3, data: elements)
XCTAssertEqual(Int32(elements.count * 2), bytesNum)
let m1 = m.col(3)
var buff = [UInt16](repeating: 0, count: 3)
bytesNum = try m1.get(row: 2, col: 0, data: &buff)
XCTAssert(buff == [10, 20, 30])
XCTAssert([40, 50, 60] == m.get(row: 2, col: 4))
}
func testPutIntArrayInt16Array() throws {
func testPutIntArrayShortArray() throws {
let m = Mat(sizes: [5, 5, 5], type: CvType.CV_16SC3, scalar: Scalar(-1, -2, -3))
let elements: [Int16] = [ 10, 20, 30, 40, 50, 60]
@@ -970,20 +848,6 @@ class MatTests: OpenCVTestCase {
XCTAssert([40, 50, 60] == m.get(indices: [0, 2, 4]))
}
func testPutIntArrayUInt16Array() throws {
let m = Mat(sizes: [5, 5, 5], type: CvType.CV_16UC3, scalar: Scalar(-1, -2, -3))
let elements: [UInt16] = [ 10, 20, 30, 40, 50, 60]
var bytesNum = try m.put(indices: [0, 2, 3], data: elements)
XCTAssertEqual(Int32(elements.count * 2), bytesNum)
let m1 = m.submat(ranges: [Range.all(), Range.all(), Range(start: 3, end: 4)])
var buff = [UInt16](repeating: 0, count: 3)
bytesNum = try m1.get(indices: [0, 2, 0], data: &buff)
XCTAssert(buff == [10, 20, 30])
XCTAssert([40, 50, 60] == m.get(indices: [0, 2, 4]))
}
func testReshapeInt() throws {
let src = Mat(rows: 4, cols: 4, type: CvType.CV_8U, scalar: Scalar(0))
dst = src.reshape(channels: 4)
+9 -9
View File
@@ -80,15 +80,15 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
case DXGI_FORMAT_R32G32B32_UINT:
case DXGI_FORMAT_R32G32B32_SINT: return CV_32SC3;
//case DXGI_FORMAT_R16G16B16A16_TYPELESS:
case DXGI_FORMAT_R16G16B16A16_FLOAT: return CV_16FC4;
//case DXGI_FORMAT_R16G16B16A16_FLOAT:
case DXGI_FORMAT_R16G16B16A16_UNORM:
case DXGI_FORMAT_R16G16B16A16_UINT: return CV_16UC4;
case DXGI_FORMAT_R16G16B16A16_SNORM:
case DXGI_FORMAT_R16G16B16A16_SINT: return CV_16SC4;
//case DXGI_FORMAT_R32G32_TYPELESS:
case DXGI_FORMAT_R32G32_FLOAT: return CV_32FC2;
case DXGI_FORMAT_R32G32_UINT:
case DXGI_FORMAT_R32G32_SINT: return CV_32SC2;
//case DXGI_FORMAT_R32G32_FLOAT:
//case DXGI_FORMAT_R32G32_UINT:
//case DXGI_FORMAT_R32G32_SINT:
//case DXGI_FORMAT_R32G8X24_TYPELESS:
//case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
//case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
@@ -104,13 +104,13 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
case DXGI_FORMAT_R8G8B8A8_SNORM:
case DXGI_FORMAT_R8G8B8A8_SINT: return CV_8SC4;
//case DXGI_FORMAT_R16G16_TYPELESS:
case DXGI_FORMAT_R16G16_FLOAT: return CV_16FC2;
//case DXGI_FORMAT_R16G16_FLOAT:
case DXGI_FORMAT_R16G16_UNORM:
case DXGI_FORMAT_R16G16_UINT: return CV_16UC2;
case DXGI_FORMAT_R16G16_SNORM:
case DXGI_FORMAT_R16G16_SINT: return CV_16SC2;
//case DXGI_FORMAT_R32_TYPELESS:
case DXGI_FORMAT_D32_FLOAT:
//case DXGI_FORMAT_D32_FLOAT:
case DXGI_FORMAT_R32_FLOAT: return CV_32FC1;
case DXGI_FORMAT_R32_UINT:
case DXGI_FORMAT_R32_SINT: return CV_32SC1;
@@ -124,7 +124,7 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
case DXGI_FORMAT_R8G8_SNORM:
case DXGI_FORMAT_R8G8_SINT: return CV_8SC2;
//case DXGI_FORMAT_R16_TYPELESS:
case DXGI_FORMAT_R16_FLOAT: return CV_16FC1;
//case DXGI_FORMAT_R16_FLOAT:
case DXGI_FORMAT_D16_UNORM:
case DXGI_FORMAT_R16_UNORM:
case DXGI_FORMAT_R16_UINT: return CV_16UC1;
@@ -138,8 +138,8 @@ int getTypeFromDXGI_FORMAT(const int iDXGI_FORMAT)
case DXGI_FORMAT_A8_UNORM: return CV_8UC1;
//case DXGI_FORMAT_R1_UNORM:
//case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
case DXGI_FORMAT_R8G8_B8G8_UNORM:
case DXGI_FORMAT_G8R8_G8B8_UNORM: return CV_8UC4;
//case DXGI_FORMAT_R8G8_B8G8_UNORM:
//case DXGI_FORMAT_G8R8_G8B8_UNORM:
//case DXGI_FORMAT_BC1_TYPELESS:
//case DXGI_FORMAT_BC1_UNORM:
//case DXGI_FORMAT_BC1_UNORM_SRGB:
+4 -4
View File
@@ -229,14 +229,14 @@ void cv::setIdentity( InputOutputArray _m, const Scalar& s )
namespace cv {
UMat UMat::eye(int rows, int cols, int type, UMatUsageFlags usageFlags)
UMat UMat::eye(int rows, int cols, int type)
{
return UMat::eye(Size(cols, rows), type, usageFlags);
return UMat::eye(Size(cols, rows), type);
}
UMat UMat::eye(Size size, int type, UMatUsageFlags usageFlags)
UMat UMat::eye(Size size, int type)
{
UMat m(size, type, usageFlags);
UMat m(size, type);
setIdentity(m);
return m;
}
+10 -35
View File
@@ -1566,7 +1566,6 @@ struct Device::Impl
version_ = getStrProp(CL_DEVICE_VERSION);
extensions_ = getStrProp(CL_DEVICE_EXTENSIONS);
doubleFPConfig_ = getProp<cl_device_fp_config, int>(CL_DEVICE_DOUBLE_FP_CONFIG);
halfFPConfig_ = getProp<cl_device_fp_config, int>(CL_DEVICE_HALF_FP_CONFIG);
hostUnifiedMemory_ = getBoolProp(CL_DEVICE_HOST_UNIFIED_MEMORY);
maxComputeUnits_ = getProp<cl_uint, int>(CL_DEVICE_MAX_COMPUTE_UNITS);
maxWorkGroupSize_ = getProp<size_t, size_t>(CL_DEVICE_MAX_WORK_GROUP_SIZE);
@@ -1679,7 +1678,6 @@ struct Device::Impl
String version_;
std::string extensions_;
int doubleFPConfig_;
int halfFPConfig_;
bool hostUnifiedMemory_;
int maxComputeUnits_;
size_t maxWorkGroupSize_;
@@ -1829,7 +1827,11 @@ int Device::singleFPConfig() const
{ return p ? p->getProp<cl_device_fp_config, int>(CL_DEVICE_SINGLE_FP_CONFIG) : 0; }
int Device::halfFPConfig() const
{ return p ? p->halfFPConfig_ : 0; }
#ifdef CL_VERSION_1_2
{ return p ? p->getProp<cl_device_fp_config, int>(CL_DEVICE_HALF_FP_CONFIG) : 0; }
#else
{ CV_REQUIRE_OPENCL_1_2_ERROR; }
#endif
bool Device::endianLittle() const
{ return p ? p->getBoolProp(CL_DEVICE_ENDIAN_LITTLE) : false; }
@@ -6666,10 +6668,6 @@ void convertFromImage(void* cl_mem_image, UMat& dst)
depth = CV_32F;
break;
case CL_HALF_FLOAT:
depth = CV_16F;
break;
default:
CV_Error(cv::Error::OpenCLApiCallError, "Not supported image_channel_data_type");
}
@@ -6678,23 +6676,9 @@ void convertFromImage(void* cl_mem_image, UMat& dst)
switch (fmt.image_channel_order)
{
case CL_R:
case CL_A:
case CL_INTENSITY:
case CL_LUMINANCE:
type = CV_MAKE_TYPE(depth, 1);
break;
case CL_RG:
case CL_RA:
type = CV_MAKE_TYPE(depth, 2);
break;
// CL_RGB has no mappings to OpenCV types because CL_RGB can only be used with
// CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, or CL_UNORM_INT_101010.
/*case CL_RGB:
type = CV_MAKE_TYPE(depth, 3);
break;*/
case CL_RGBA:
case CL_BGRA:
case CL_ARGB:
@@ -7084,13 +7068,6 @@ static std::string kerToStr(const Mat & k)
stream << "DIG(" << data[i] << "f)";
stream << "DIG(" << data[width] << "f)";
}
else if (depth == CV_16F)
{
stream.setf(std::ios_base::showpoint);
for (int i = 0; i < width; ++i)
stream << "DIG(" << (float)data[i] << "h)";
stream << "DIG(" << (float)data[width] << "h)";
}
else
{
for (int i = 0; i < width; ++i)
@@ -7114,7 +7091,7 @@ String kernelToStr(InputArray _kernel, int ddepth, const char * name)
typedef std::string (* func_t)(const Mat &);
static const func_t funcs[] = { kerToStr<uchar>, kerToStr<char>, kerToStr<ushort>, kerToStr<short>,
kerToStr<int>, kerToStr<float>, kerToStr<double>, kerToStr<float16_t> };
kerToStr<int>, kerToStr<float>, kerToStr<double>, 0 };
const func_t func = funcs[ddepth];
CV_Assert(func != 0);
@@ -7153,14 +7130,14 @@ int predictOptimalVectorWidth(InputArray src1, InputArray src2, InputArray src3,
int vectorWidths[] = { d.preferredVectorWidthChar(), d.preferredVectorWidthChar(),
d.preferredVectorWidthShort(), d.preferredVectorWidthShort(),
d.preferredVectorWidthInt(), d.preferredVectorWidthFloat(),
d.preferredVectorWidthDouble(), d.preferredVectorWidthHalf() };
d.preferredVectorWidthDouble(), -1 };
// if the device says don't use vectors
if (vectorWidths[0] == 1)
{
// it's heuristic
vectorWidths[CV_8U] = vectorWidths[CV_8S] = 4;
vectorWidths[CV_16U] = vectorWidths[CV_16S] = vectorWidths[CV_16F] = 2;
vectorWidths[CV_16U] = vectorWidths[CV_16S] = 2;
vectorWidths[CV_32S] = vectorWidths[CV_32F] = vectorWidths[CV_64F] = 1;
}
@@ -7248,12 +7225,10 @@ struct Image2D::Impl
{
cl_image_format format;
static const int channelTypes[] = { CL_UNSIGNED_INT8, CL_SIGNED_INT8, CL_UNSIGNED_INT16,
CL_SIGNED_INT16, CL_SIGNED_INT32, CL_FLOAT, -1, CL_HALF_FLOAT };
CL_SIGNED_INT16, CL_SIGNED_INT32, CL_FLOAT, -1, -1 };
static const int channelTypesNorm[] = { CL_UNORM_INT8, CL_SNORM_INT8, CL_UNORM_INT16,
CL_SNORM_INT16, -1, -1, -1, -1 };
// CL_RGB has no mappings to OpenCV types because CL_RGB can only be used with
// CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, or CL_UNORM_INT_101010.
static const int channelOrders[] = { -1, CL_R, CL_RG, /*CL_RGB*/ -1, CL_RGBA };
static const int channelOrders[] = { -1, CL_R, CL_RG, -1, CL_RGBA };
int channelType = norm ? channelTypesNorm[depth] : channelTypes[depth];
int channelOrder = channelOrders[cn];
+6 -13
View File
@@ -143,17 +143,17 @@ static const char symbols[9] = "ucwsifdh";
static char typeSymbol(int depth)
{
CV_StaticAssert(CV_64F == 6, "");
CV_CheckDepth(depth, depth >=0 && depth <= CV_16F, "");
CV_Assert(depth >=0 && depth <= CV_64F);
return symbols[depth];
}
static int symbolToType(char c)
{
if (c == 'r')
return CV_SEQ_ELTYPE_PTR;
const char* pos = strchr( symbols, c );
if( !pos )
CV_Error( CV_StsBadArg, "Invalid data type specification" );
if (c == 'r')
return CV_SEQ_ELTYPE_PTR;
return static_cast<int>(pos - symbols);
}
@@ -245,12 +245,8 @@ int calcStructSize( const char* dt, int initial_size )
{
int size = calcElemSize( dt, initial_size );
size_t elem_max_size = 0;
for ( const char * type = dt; *type != '\0'; type++ )
{
char v = *type;
if (v >= '0' && v <= '9')
continue; // skip vector size
switch (v)
for ( const char * type = dt; *type != '\0'; type++ ) {
switch ( *type )
{
case 'u': { elem_max_size = std::max( elem_max_size, sizeof(uchar ) ); break; }
case 'c': { elem_max_size = std::max( elem_max_size, sizeof(schar ) ); break; }
@@ -259,9 +255,7 @@ int calcStructSize( const char* dt, int initial_size )
case 'i': { elem_max_size = std::max( elem_max_size, sizeof(int ) ); break; }
case 'f': { elem_max_size = std::max( elem_max_size, sizeof(float ) ); break; }
case 'd': { elem_max_size = std::max( elem_max_size, sizeof(double) ); break; }
case 'h': { elem_max_size = std::max(elem_max_size, sizeof(float16_t)); break; }
default:
CV_Error_(Error::StsNotImplemented, ("Unknown type identifier: '%c' in '%s'", (char)(*type), dt));
default: break;
}
}
size = cvAlign( size, static_cast<int>(elem_max_size) );
@@ -1060,7 +1054,6 @@ public:
CV_Assert(write_mode);
size_t elemSize = fs::calcStructSize(dt.c_str(), 0);
CV_Assert(elemSize);
CV_Assert( len % elemSize == 0 );
len /= elemSize;
+1 -9
View File
@@ -1835,15 +1835,7 @@ void* TLSDataContainer::getData() const
{
// Create new data instance and save it to TLS storage
pData = createDataInstance();
try
{
getTlsStorage().setData(key_, pData);
}
catch (...)
{
deleteDataInstance(pData);
throw;
}
getTlsStorage().setData(key_, pData);
}
return pData;
}
+14 -14
View File
@@ -951,11 +951,11 @@ UMat UMat::reshape(int new_cn, int new_rows) const
return hdr;
}
UMat UMat::diag(const UMat& d, UMatUsageFlags usageFlags)
UMat UMat::diag(const UMat& d)
{
CV_Assert( d.cols == 1 || d.rows == 1 );
int len = d.rows + d.cols - 1;
UMat m(len, len, d.type(), Scalar(0), usageFlags);
UMat m(len, len, d.type(), Scalar(0));
UMat md = m.diag();
if( d.cols == 1 )
d.copyTo(md);
@@ -1323,34 +1323,34 @@ UMat UMat::t() const
return m;
}
UMat UMat::zeros(int rows, int cols, int type, UMatUsageFlags usageFlags)
UMat UMat::zeros(int rows, int cols, int type)
{
return UMat(rows, cols, type, Scalar::all(0), usageFlags);
return UMat(rows, cols, type, Scalar::all(0));
}
UMat UMat::zeros(Size size, int type, UMatUsageFlags usageFlags)
UMat UMat::zeros(Size size, int type)
{
return UMat(size, type, Scalar::all(0), usageFlags);
return UMat(size, type, Scalar::all(0));
}
UMat UMat::zeros(int ndims, const int* sz, int type, UMatUsageFlags usageFlags)
UMat UMat::zeros(int ndims, const int* sz, int type)
{
return UMat(ndims, sz, type, Scalar::all(0), usageFlags);
return UMat(ndims, sz, type, Scalar::all(0));
}
UMat UMat::ones(int rows, int cols, int type, UMatUsageFlags usageFlags)
UMat UMat::ones(int rows, int cols, int type)
{
return UMat(rows, cols, type, Scalar(1), usageFlags);
return UMat::ones(Size(cols, rows), type);
}
UMat UMat::ones(Size size, int type, UMatUsageFlags usageFlags)
UMat UMat::ones(Size size, int type)
{
return UMat(size, type, Scalar(1), usageFlags);
return UMat(size, type, Scalar(1));
}
UMat UMat::ones(int ndims, const int* sz, int type, UMatUsageFlags usageFlags)
UMat UMat::ones(int ndims, const int* sz, int type)
{
return UMat(ndims, sz, type, Scalar(1), usageFlags);
return UMat(ndims, sz, type, Scalar(1));
}
}
@@ -76,24 +76,6 @@ OCL_TEST_P(UMatExpr, Ones)
}
}
//////////////////////////////// with usageFlags /////////////////////////////////////////////////
OCL_TEST_P(UMatExpr, WithUsageFlags)
{
for (int j = 0; j < test_loop_times; j++)
{
generateTestData();
UMat u0 = UMat::zeros(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
UMat u1 = UMat::ones(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
UMat u8 = UMat::eye(size, type, cv::USAGE_ALLOCATE_HOST_MEMORY);
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u0.usageFlags);
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u1.usageFlags);
EXPECT_EQ(cv::USAGE_ALLOCATE_HOST_MEMORY, u8.usageFlags);
}
}
//////////////////////////////// Instantiation /////////////////////////////////////////////////
OCL_INSTANTIATE_TEST_CASE_P(MatrixOperation, UMatExpr, Combine(OCL_ALL_DEPTHS_16F, OCL_ALL_CHANNELS));
-65
View File
@@ -1837,69 +1837,4 @@ TEST(Core_InputOutput, FileStorage_copy_constructor_17412_heap)
EXPECT_EQ(0, remove(fname.c_str()));
}
static void test_20279(FileStorage& fs)
{
Mat m32fc1(5, 10, CV_32FC1, Scalar::all(0));
for (size_t i = 0; i < m32fc1.total(); i++)
{
float v = (float)i;
m32fc1.at<float>((int)i) = v * 0.5f;
}
Mat m16fc1;
// produces CV_16S output: convertFp16(m32fc1, m16fc1);
m32fc1.convertTo(m16fc1, CV_16FC1);
EXPECT_EQ(CV_16FC1, m16fc1.type()) << typeToString(m16fc1.type());
//std::cout << m16fc1 << std::endl;
Mat m32fc3(4, 3, CV_32FC3, Scalar::all(0));
for (size_t i = 0; i < m32fc3.total(); i++)
{
float v = (float)i;
m32fc3.at<Vec3f>((int)i) = Vec3f(v, v * 0.2f, -v);
}
Mat m16fc3;
m32fc3.convertTo(m16fc3, CV_16FC3);
EXPECT_EQ(CV_16FC3, m16fc3.type()) << typeToString(m16fc3.type());
//std::cout << m16fc3 << std::endl;
fs << "m16fc1" << m16fc1;
fs << "m16fc3" << m16fc3;
string content = fs.releaseAndGetString();
if (cvtest::debugLevel > 0) std::cout << content << std::endl;
FileStorage fs_read(content, FileStorage::READ + FileStorage::MEMORY);
Mat m16fc1_result;
Mat m16fc3_result;
fs_read["m16fc1"] >> m16fc1_result;
ASSERT_FALSE(m16fc1_result.empty());
EXPECT_EQ(CV_16FC1, m16fc1_result.type()) << typeToString(m16fc1_result.type());
EXPECT_LE(cvtest::norm(m16fc1_result, m16fc1, NORM_INF), 1e-2);
fs_read["m16fc3"] >> m16fc3_result;
ASSERT_FALSE(m16fc3_result.empty());
EXPECT_EQ(CV_16FC3, m16fc3_result.type()) << typeToString(m16fc3_result.type());
EXPECT_LE(cvtest::norm(m16fc3_result, m16fc3, NORM_INF), 1e-2);
}
TEST(Core_InputOutput, FileStorage_16F_xml)
{
FileStorage fs("test.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
test_20279(fs);
}
TEST(Core_InputOutput, FileStorage_16F_yml)
{
FileStorage fs("test.yml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
test_20279(fs);
}
TEST(Core_InputOutput, FileStorage_16F_json)
{
FileStorage fs("test.json", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
test_20279(fs);
}
}} // namespace
+1 -1
View File
@@ -54,7 +54,7 @@
]
],
"jni_name": "(*(*(Ptr<cv::dnn::DictValue>*)%(n)s_nativeObj))",
"jni_name": "(*(cv::dnn::DictValue*)%(n)s_nativeObj)",
"jni_type": "jlong",
"suffix": "J",
"j_import": "org.opencv.dnn.DictValue"
+14 -37
View File
@@ -657,11 +657,7 @@ void InfEngineNgraphNet::initPlugin(InferenceEngine::CNNNetwork& net)
try
{
InferenceEngine::IExtensionPtr extension =
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4)
std::make_shared<InferenceEngine::Extension>(libName);
#else
InferenceEngine::make_so_pointer<InferenceEngine::IExtension>(libName);
#endif
ie.AddExtension(extension, "CPU");
CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << libName);
@@ -1009,54 +1005,35 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
reqWrapper->req.SetInput(inpBlobs);
reqWrapper->req.SetOutput(outBlobs);
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4)
InferenceEngine::InferRequest infRequest = reqWrapper->req;
NgraphReqWrapper* wrapperPtr = reqWrapper.get();
CV_Assert(wrapperPtr && "Internal error");
#else
InferenceEngine::IInferRequest::Ptr infRequestPtr = reqWrapper->req;
CV_Assert(infRequestPtr);
InferenceEngine::IInferRequest& infRequest = *infRequestPtr.get();
infRequest.SetUserData(reqWrapper.get(), 0);
#endif
infRequestPtr->SetUserData(reqWrapper.get(), 0);
#if INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4)
// do NOT capture 'reqWrapper' (smart ptr) in the lambda callback
infRequest.SetCompletionCallback<std::function<void(InferenceEngine::InferRequest, InferenceEngine::StatusCode)>>(
[wrapperPtr](InferenceEngine::InferRequest /*request*/, InferenceEngine::StatusCode status)
#else
infRequest.SetCompletionCallback(
[](InferenceEngine::IInferRequest::Ptr requestPtr, InferenceEngine::StatusCode status)
#endif
infRequestPtr->SetCompletionCallback(
[](InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode status)
{
CV_LOG_DEBUG(NULL, "DNN(nGraph): completionCallback(" << (int)status << ")");
#if !INF_ENGINE_VER_MAJOR_GE(INF_ENGINE_RELEASE_2021_4)
CV_Assert(requestPtr);
InferenceEngine::IInferRequest& request = *requestPtr.get();
NgraphReqWrapper* wrapperPtr;
request.GetUserData((void**)&wrapperPtr, 0);
CV_Assert(wrapperPtr && "Internal error");
#endif
NgraphReqWrapper& wrapper = *wrapperPtr;
NgraphReqWrapper* wrapper;
request->GetUserData((void**)&wrapper, 0);
CV_Assert(wrapper && "Internal error");
size_t processedOutputs = 0;
try
{
for (; processedOutputs < wrapper.outProms.size(); ++processedOutputs)
for (; processedOutputs < wrapper->outProms.size(); ++processedOutputs)
{
const std::string& name = wrapper.outsNames[processedOutputs];
Mat m = ngraphBlobToMat(wrapper.req.GetBlob(name));
const std::string& name = wrapper->outsNames[processedOutputs];
Mat m = ngraphBlobToMat(wrapper->req.GetBlob(name));
try
{
CV_Assert(status == InferenceEngine::StatusCode::OK);
wrapper.outProms[processedOutputs].setValue(m.clone());
wrapper->outProms[processedOutputs].setValue(m.clone());
}
catch (...)
{
try {
wrapper.outProms[processedOutputs].setException(std::current_exception());
wrapper->outProms[processedOutputs].setException(std::current_exception());
} catch(...) {
CV_LOG_ERROR(NULL, "DNN: Exception occurred during async inference exception propagation");
}
@@ -1066,16 +1043,16 @@ void InfEngineNgraphNet::forward(const std::vector<Ptr<BackendWrapper> >& outBlo
catch (...)
{
std::exception_ptr e = std::current_exception();
for (; processedOutputs < wrapper.outProms.size(); ++processedOutputs)
for (; processedOutputs < wrapper->outProms.size(); ++processedOutputs)
{
try {
wrapper.outProms[processedOutputs].setException(e);
wrapper->outProms[processedOutputs].setException(e);
} catch(...) {
CV_LOG_ERROR(NULL, "DNN: Exception occurred during async inference exception propagation");
}
}
}
wrapper.isReady = true;
wrapper->isReady = true;
}
);
}
+9 -7
View File
@@ -35,7 +35,6 @@ namespace dnn
class BatchNormLayerImpl CV_FINAL : public BatchNormLayer
{
public:
Mat origin_weights, origin_bias;
Mat weights_, bias_;
UMat umat_weight, umat_bias;
mutable int dims;
@@ -89,11 +88,11 @@ public:
const float* weightsData = hasWeights ? blobs[weightsBlobIndex].ptr<float>() : 0;
const float* biasData = hasBias ? blobs[biasBlobIndex].ptr<float>() : 0;
origin_weights.create(1, (int)n, CV_32F);
origin_bias.create(1, (int)n, CV_32F);
weights_.create(1, (int)n, CV_32F);
bias_.create(1, (int)n, CV_32F);
float* dstWeightsData = origin_weights.ptr<float>();
float* dstBiasData = origin_bias.ptr<float>();
float* dstWeightsData = weights_.ptr<float>();
float* dstBiasData = bias_.ptr<float>();
for (size_t i = 0; i < n; ++i)
{
@@ -101,12 +100,15 @@ public:
dstWeightsData[i] = w;
dstBiasData[i] = (hasBias ? biasData[i] : 0.0f) - w * meanData[i] * varMeanScale;
}
// We will use blobs to store origin weights and bias to restore them in case of reinitialization.
weights_.copyTo(blobs[0].reshape(1, 1));
bias_.copyTo(blobs[1].reshape(1, 1));
}
virtual void finalize(InputArrayOfArrays, OutputArrayOfArrays) CV_OVERRIDE
{
origin_weights.reshape(1, 1).copyTo(weights_);
origin_bias.reshape(1, 1).copyTo(bias_);
blobs[0].reshape(1, 1).copyTo(weights_);
blobs[1].reshape(1, 1).copyTo(bias_);
}
void getScaleShift(Mat& scale, Mat& shift) const CV_OVERRIDE
@@ -338,7 +338,7 @@ public:
std::iota(axes_data.begin(), axes_data.end(), 1);
}
auto axes = std::make_shared<ngraph::op::Constant>(ngraph::element::i64, ngraph::Shape{axes_data.size()}, axes_data);
auto norm = std::make_shared<ngraph::op::v0::NormalizeL2>(ieInpNode, axes, epsilon, ngraph::op::EpsMode::ADD);
auto norm = std::make_shared<ngraph::op::NormalizeL2>(ieInpNode, axes, epsilon, ngraph::op::EpsMode::ADD);
CV_Assert(blobs.empty() || numChannels == blobs[0].total());
std::vector<size_t> shape(ieInpNode->get_shape().size(), 1);
-17
View File
@@ -1954,23 +1954,6 @@ void ONNXImporter::handleNode(const opencv_onnx::NodeProto& node_proto_)
addConstant(layerParams.name, concatenated[0]);
return;
}
else
{
for (int i = 0; i < node_proto.input_size(); ++i)
{
if (constBlobs.find(node_proto.input(i)) != constBlobs.end())
{
LayerParams constParams;
constParams.name = node_proto.input(i);
constParams.type = "Const";
constParams.blobs.push_back(getBlob(node_proto, i));
opencv_onnx::NodeProto proto;
proto.add_output(constParams.name);
addLayer(constParams, proto);
}
}
}
}
else if (layer_type == "Resize")
{
+2 -3
View File
@@ -30,11 +30,10 @@
#define INF_ENGINE_RELEASE_2021_1 2021010000
#define INF_ENGINE_RELEASE_2021_2 2021020000
#define INF_ENGINE_RELEASE_2021_3 2021030000
#define INF_ENGINE_RELEASE_2021_4 2021040000
#ifndef INF_ENGINE_RELEASE
#warning("IE version have not been provided via command-line. Using 2021.4 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2021_4
#warning("IE version have not been provided via command-line. Using 2021.3 by default")
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2021_3
#endif
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -204,7 +204,7 @@ TEST_P(DNNTestNetwork, MobileNet_SSD_Caffe)
Mat inp = blobFromImage(sample, 1.0f / 127.5, Size(300, 300), Scalar(127.5, 127.5, 127.5), false);
float scoreDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 1.5e-2 : 0.0;
float iouDiff = (target == DNN_TARGET_MYRIAD) ? 0.063 : 0.0;
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.262 : FLT_MIN;
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.252 : FLT_MIN;
processNet("dnn/MobileNetSSD_deploy.caffemodel", "dnn/MobileNetSSD_deploy.prototxt",
inp, "detection_out", "", scoreDiff, iouDiff, detectionConfThresh);
expectNoFallbacksFromIE(net);
@@ -359,8 +359,8 @@ TEST_P(DNNTestNetwork, OpenPose_pose_coco)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD_X, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.009 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.09 : 0.0;
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.0056 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.072 : 0.0;
processNet("dnn/openpose_pose_coco.caffemodel", "dnn/openpose_pose_coco.prototxt",
Size(46, 46), "", "", l1, lInf);
expectNoFallbacksFromIE(net);
@@ -380,8 +380,8 @@ TEST_P(DNNTestNetwork, OpenPose_pose_mpi)
#endif
// output range: [-0.001, 0.97]
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.02 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.2 : 0.0;
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.012 : 0.0;
const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.16 : 0.0;
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt",
Size(46, 46), "", "", l1, lInf);
expectNoFallbacksFromIE(net);
-9
View File
@@ -307,15 +307,6 @@ TEST_P(DNNTestOpenVINO, models)
ASSERT_FALSE(backendId != DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && backendId != DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) <<
"Inference Engine backend is required";
#if INF_ENGINE_VER_MAJOR_EQ(2021040000)
if (targetId == DNN_TARGET_MYRIAD && (
modelName == "person-detection-retail-0013" || // ncDeviceOpen:1013 Failed to find booted device after boot
modelName == "age-gender-recognition-retail-0013" // ncDeviceOpen:1013 Failed to find booted device after boot
)
)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#if INF_ENGINE_VER_MAJOR_GE(2020020000)
if (targetId == DNN_TARGET_MYRIAD && backendId == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019)
{
-1
View File
@@ -349,7 +349,6 @@ TEST_P(Test_ONNX_layers, Concatenation)
if (target == DNN_TARGET_MYRIAD) applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NN_BUILDER);
}
testONNXModels("concatenation");
testONNXModels("concat_const_blobs");
}
TEST_P(Test_ONNX_layers, Eltwise3D)
+2 -7
View File
@@ -290,14 +290,9 @@ TEST_P(Test_Torch_layers, net_padding)
TEST_P(Test_Torch_layers, net_non_spatial)
{
#if defined(INF_ENGINE_RELEASE) && ( \
INF_ENGINE_VER_MAJOR_EQ(2021030000) || \
INF_ENGINE_VER_MAJOR_EQ(2021040000) \
)
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_EQ(2021030000)
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
// 2021.3: crash
// 2021.4: [ GENERAL_ERROR ] AssertionFailed: !out.networkInputs.empty()
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH);
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // crash
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // exception
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL_FP16)
@@ -1337,13 +1337,6 @@ CV_EXPORTS_W void drawMatches( InputArray img1, const std::vector<KeyPoint>& key
const std::vector<char>& matchesMask=std::vector<char>(), DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT );
/** @overload */
CV_EXPORTS_W void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
InputArray img2, const std::vector<KeyPoint>& keypoints2,
const std::vector<DMatch>& matches1to2, InputOutputArray outImg,
const int matchesThickness, const Scalar& matchColor=Scalar::all(-1),
const Scalar& singlePointColor=Scalar::all(-1), const std::vector<char>& matchesMask=std::vector<char>(),
DrawMatchesFlags flags=DrawMatchesFlags::DEFAULT );
CV_EXPORTS_AS(drawMatchesKnn) void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
InputArray img2, const std::vector<KeyPoint>& keypoints2,
const std::vector<std::vector<DMatch> >& matches1to2, InputOutputArray outImg,
+4 -21
View File
@@ -183,8 +183,7 @@ static void _prepareImgAndDrawKeypoints( InputArray img1, const std::vector<KeyP
}
static inline void _drawMatch( InputOutputArray outImg, InputOutputArray outImg1, InputOutputArray outImg2 ,
const KeyPoint& kp1, const KeyPoint& kp2, const Scalar& matchColor, DrawMatchesFlags flags,
const int matchesThickness )
const KeyPoint& kp1, const KeyPoint& kp2, const Scalar& matchColor, DrawMatchesFlags flags )
{
RNG& rng = theRNG();
bool isRandMatchColor = matchColor == Scalar::all(-1);
@@ -200,7 +199,7 @@ static inline void _drawMatch( InputOutputArray outImg, InputOutputArray outImg1
line( outImg,
Point(cvRound(pt1.x*draw_multiplier), cvRound(pt1.y*draw_multiplier)),
Point(cvRound(dpt2.x*draw_multiplier), cvRound(dpt2.y*draw_multiplier)),
color, matchesThickness, LINE_AA, draw_shift_bits );
color, 1, LINE_AA, draw_shift_bits );
}
void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
@@ -208,21 +207,6 @@ void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
const std::vector<DMatch>& matches1to2, InputOutputArray outImg,
const Scalar& matchColor, const Scalar& singlePointColor,
const std::vector<char>& matchesMask, DrawMatchesFlags flags )
{
drawMatches( img1, keypoints1,
img2, keypoints2,
matches1to2, outImg,
1, matchColor,
singlePointColor, matchesMask,
flags);
}
void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
InputArray img2, const std::vector<KeyPoint>& keypoints2,
const std::vector<DMatch>& matches1to2, InputOutputArray outImg,
const int matchesThickness, const Scalar& matchColor,
const Scalar& singlePointColor, const std::vector<char>& matchesMask,
DrawMatchesFlags flags )
{
if( !matchesMask.empty() && matchesMask.size() != matches1to2.size() )
CV_Error( Error::StsBadSize, "matchesMask must have the same size as matches1to2" );
@@ -242,12 +226,11 @@ void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
CV_Assert(i2 >= 0 && i2 < static_cast<int>(keypoints2.size()));
const KeyPoint &kp1 = keypoints1[i1], &kp2 = keypoints2[i2];
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags, matchesThickness );
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags );
}
}
}
void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
InputArray img2, const std::vector<KeyPoint>& keypoints2,
const std::vector<std::vector<DMatch> >& matches1to2, InputOutputArray outImg,
@@ -271,7 +254,7 @@ void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
if( matchesMask.empty() || matchesMask[i][j] )
{
const KeyPoint &kp1 = keypoints1[i1], &kp2 = keypoints2[i2];
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags, 1 );
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags );
}
}
}
+21 -174
View File
@@ -450,184 +450,31 @@ public:
const sift_wt* currptr = img.ptr<sift_wt>(r);
const sift_wt* prevptr = prev.ptr<sift_wt>(r);
const sift_wt* nextptr = next.ptr<sift_wt>(r);
int c = SIFT_IMG_BORDER;
#if CV_SIMD && !(DoG_TYPE_SHORT)
const int vecsize = v_float32::nlanes;
for( ; c <= cols-SIFT_IMG_BORDER - vecsize; c += vecsize)
{
v_float32 val = vx_load(&currptr[c]);
v_float32 _00,_01,_02;
v_float32 _10, _12;
v_float32 _20,_21,_22;
v_float32 vmin,vmax;
v_float32 cond = v_abs(val) > vx_setall_f32((float)threshold);
if (!v_check_any(cond))
{
continue;
}
_00 = vx_load(&currptr[c-step-1]); _01 = vx_load(&currptr[c-step]); _02 = vx_load(&currptr[c-step+1]);
_10 = vx_load(&currptr[c -1]); _12 = vx_load(&currptr[c +1]);
_20 = vx_load(&currptr[c+step-1]); _21 = vx_load(&currptr[c+step]); _22 = vx_load(&currptr[c+step+1]);
vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22)));
vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22)));
v_float32 condp = cond & (val > vx_setall_f32(0)) & (val >= vmax);
v_float32 condm = cond & (val < vx_setall_f32(0)) & (val <= vmin);
cond = condp | condm;
if (!v_check_any(cond))
{
continue;
}
_00 = vx_load(&prevptr[c-step-1]); _01 = vx_load(&prevptr[c-step]); _02 = vx_load(&prevptr[c-step+1]);
_10 = vx_load(&prevptr[c -1]); _12 = vx_load(&prevptr[c +1]);
_20 = vx_load(&prevptr[c+step-1]); _21 = vx_load(&prevptr[c+step]); _22 = vx_load(&prevptr[c+step+1]);
vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22)));
vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22)));
condp &= (val >= vmax);
condm &= (val <= vmin);
cond = condp | condm;
if (!v_check_any(cond))
{
continue;
}
v_float32 _11p = vx_load(&prevptr[c]);
v_float32 _11n = vx_load(&nextptr[c]);
v_float32 max_middle = v_max(_11n,_11p);
v_float32 min_middle = v_min(_11n,_11p);
_00 = vx_load(&nextptr[c-step-1]); _01 = vx_load(&nextptr[c-step]); _02 = vx_load(&nextptr[c-step+1]);
_10 = vx_load(&nextptr[c -1]); _12 = vx_load(&nextptr[c +1]);
_20 = vx_load(&nextptr[c+step-1]); _21 = vx_load(&nextptr[c+step]); _22 = vx_load(&nextptr[c+step+1]);
vmax = v_max(v_max(v_max(_00,_01),v_max(_02,_10)),v_max(v_max(_12,_20),v_max(_21,_22)));
vmin = v_min(v_min(v_min(_00,_01),v_min(_02,_10)),v_min(v_min(_12,_20),v_min(_21,_22)));
condp &= (val >= v_max(vmax,max_middle));
condm &= (val <= v_min(vmin,min_middle));
cond = condp | condm;
if (!v_check_any(cond))
{
continue;
}
int mask = v_signmask(cond);
for (int k = 0; k<vecsize;k++)
{
if ((mask & (1<<k)) == 0)
continue;
CV_TRACE_REGION("pixel_candidate_simd");
KeyPoint kpt;
int r1 = r, c1 = c+k, layer = i;
if( !adjustLocalExtrema(dog_pyr, kpt, o, layer, r1, c1,
nOctaveLayers, (float)contrastThreshold,
(float)edgeThreshold, (float)sigma) )
continue;
float scl_octv = kpt.size*0.5f/(1 << o);
float omax = calcOrientationHist(gauss_pyr[o*(nOctaveLayers+3) + layer],
Point(c1, r1),
cvRound(SIFT_ORI_RADIUS * scl_octv),
SIFT_ORI_SIG_FCTR * scl_octv,
hist, n);
float mag_thr = (float)(omax * SIFT_ORI_PEAK_RATIO);
for( int j = 0; j < n; j++ )
{
int l = j > 0 ? j - 1 : n - 1;
int r2 = j < n-1 ? j + 1 : 0;
if( hist[j] > hist[l] && hist[j] > hist[r2] && hist[j] >= mag_thr )
{
float bin = j + 0.5f * (hist[l]-hist[r2]) / (hist[l] - 2*hist[j] + hist[r2]);
bin = bin < 0 ? n + bin : bin >= n ? bin - n : bin;
kpt.angle = 360.f - (float)((360.f/n) * bin);
if(std::abs(kpt.angle - 360.f) < FLT_EPSILON)
kpt.angle = 0.f;
kpts_.push_back(kpt);
}
}
}
}
#endif //CV_SIMD && !(DoG_TYPE_SHORT)
// vector loop reminder, better predictibility and less branch density
for( ; c < cols-SIFT_IMG_BORDER; c++)
for( int c = SIFT_IMG_BORDER; c < cols-SIFT_IMG_BORDER; c++)
{
sift_wt val = currptr[c];
if (std::abs(val) <= threshold)
continue;
sift_wt _00,_01,_02;
sift_wt _10, _12;
sift_wt _20,_21,_22;
_00 = currptr[c-step-1]; _01 = currptr[c-step]; _02 = currptr[c-step+1];
_10 = currptr[c -1]; _12 = currptr[c +1];
_20 = currptr[c+step-1]; _21 = currptr[c+step]; _22 = currptr[c+step+1];
bool calculate = false;
if (val > 0)
{
sift_wt vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22)));
if (val >= vmax)
{
_00 = prevptr[c-step-1]; _01 = prevptr[c-step]; _02 = prevptr[c-step+1];
_10 = prevptr[c -1]; _12 = prevptr[c +1];
_20 = prevptr[c+step-1]; _21 = prevptr[c+step]; _22 = prevptr[c+step+1];
vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22)));
if (val >= vmax)
{
_00 = nextptr[c-step-1]; _01 = nextptr[c-step]; _02 = nextptr[c-step+1];
_10 = nextptr[c -1]; _12 = nextptr[c +1];
_20 = nextptr[c+step-1]; _21 = nextptr[c+step]; _22 = nextptr[c+step+1];
vmax = std::max(std::max(std::max(_00,_01),std::max(_02,_10)),std::max(std::max(_12,_20),std::max(_21,_22)));
if (val >= vmax)
{
sift_wt _11p = prevptr[c], _11n = nextptr[c];
calculate = (val >= std::max(_11p,_11n));
}
}
}
} else { // val cant be zero here (first abs took care of zero), must be negative
sift_wt vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22)));
if (val <= vmin)
{
_00 = prevptr[c-step-1]; _01 = prevptr[c-step]; _02 = prevptr[c-step+1];
_10 = prevptr[c -1]; _12 = prevptr[c +1];
_20 = prevptr[c+step-1]; _21 = prevptr[c+step]; _22 = prevptr[c+step+1];
vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22)));
if (val <= vmin)
{
_00 = nextptr[c-step-1]; _01 = nextptr[c-step]; _02 = nextptr[c-step+1];
_10 = nextptr[c -1]; _12 = nextptr[c +1];
_20 = nextptr[c+step-1]; _21 = nextptr[c+step]; _22 = nextptr[c+step+1];
vmin = std::min(std::min(std::min(_00,_01),std::min(_02,_10)),std::min(std::min(_12,_20),std::min(_21,_22)));
if (val <= vmin)
{
sift_wt _11p = prevptr[c], _11n = nextptr[c];
calculate = (val <= std::min(_11p,_11n));
}
}
}
}
if (calculate)
// find local extrema with pixel accuracy
if( std::abs(val) > threshold &&
((val > 0 && val >= currptr[c-1] && val >= currptr[c+1] &&
val >= currptr[c-step-1] && val >= currptr[c-step] && val >= currptr[c-step+1] &&
val >= currptr[c+step-1] && val >= currptr[c+step] && val >= currptr[c+step+1] &&
val >= nextptr[c] && val >= nextptr[c-1] && val >= nextptr[c+1] &&
val >= nextptr[c-step-1] && val >= nextptr[c-step] && val >= nextptr[c-step+1] &&
val >= nextptr[c+step-1] && val >= nextptr[c+step] && val >= nextptr[c+step+1] &&
val >= prevptr[c] && val >= prevptr[c-1] && val >= prevptr[c+1] &&
val >= prevptr[c-step-1] && val >= prevptr[c-step] && val >= prevptr[c-step+1] &&
val >= prevptr[c+step-1] && val >= prevptr[c+step] && val >= prevptr[c+step+1]) ||
(val < 0 && val <= currptr[c-1] && val <= currptr[c+1] &&
val <= currptr[c-step-1] && val <= currptr[c-step] && val <= currptr[c-step+1] &&
val <= currptr[c+step-1] && val <= currptr[c+step] && val <= currptr[c+step+1] &&
val <= nextptr[c] && val <= nextptr[c-1] && val <= nextptr[c+1] &&
val <= nextptr[c-step-1] && val <= nextptr[c-step] && val <= nextptr[c-step+1] &&
val <= nextptr[c+step-1] && val <= nextptr[c+step] && val <= nextptr[c+step+1] &&
val <= prevptr[c] && val <= prevptr[c-1] && val <= prevptr[c+1] &&
val <= prevptr[c-step-1] && val <= prevptr[c-step] && val <= prevptr[c-step+1] &&
val <= prevptr[c+step-1] && val <= prevptr[c+step] && val <= prevptr[c+step+1])))
{
CV_TRACE_REGION("pixel_candidate");
@@ -29,10 +29,6 @@
*/
namespace cv { namespace gapi {
/**
* @brief This namespace contains G-API Operation Types for OpenCV
* Core module functionality.
*/
namespace core {
using GMat2 = std::tuple<GMat,GMat>;
using GMat3 = std::tuple<GMat,GMat,GMat>; // FIXME: how to avoid this?
@@ -40,10 +40,6 @@ namespace gimpl
namespace gapi
{
/**
* @brief This namespace contains G-API CPU backend functions,
* structures, and symbols.
*/
namespace cpu
{
/**
@@ -496,7 +492,7 @@ public:
#define GAPI_OCV_KERNEL_ST(Name, API, State) \
struct Name: public cv::GCPUStKernelImpl<Name, API, State> \
/// @private
class gapi::cpu::GOCVFunctor : public gapi::GFunctor
{
public:
@@ -25,9 +25,6 @@ namespace cv {
namespace gapi
{
/**
* @brief This namespace contains G-API Fluid backend functions, structures, and symbols.
*/
namespace fluid
{
/**
+4 -62
View File
@@ -340,79 +340,21 @@ namespace detail
/** \addtogroup gapi_data_objects
* @{
*/
/**
* @brief `cv::GArray<T>` template class represents a list of objects
* of class `T` in the graph.
*
* `cv::GArray<T>` describes a functional relationship between
* operations consuming and producing arrays of objects of class
* `T`. The primary purpose of `cv::GArray<T>` is to represent a
* dynamic list of objects -- where the size of the list is not known
* at the graph construction or compile time. Examples include: corner
* and feature detectors (`cv::GArray<cv::Point>`), object detection
* and tracking results (`cv::GArray<cv::Rect>`). Programmers can use
* their own types with `cv::GArray<T>` in the custom operations.
*
* Similar to `cv::GScalar`, `cv::GArray<T>` may be value-initialized
* -- in this case a graph-constant value is associated with the object.
*
* `GArray<T>` is a virtual counterpart of `std::vector<T>`, which is
* usually used to represent the `GArray<T>` data in G-API during the
* execution.
*
* @sa `cv::GOpaque<T>`
*/
template<typename T> class GArray
{
public:
// Host type (or Flat type) - the type this GArray is actually
// specified to.
/// @private
using HT = typename detail::flatten_g<typename std::decay<T>::type>::type;
/**
* @brief Constructs a value-initialized `cv::GArray<T>`
*
* `cv::GArray<T>` objects may have their values
* be associated at graph construction time. It is useful when
* some operation has a `cv::GArray<T>` input which doesn't change during
* the program execution, and is set only once. In this case,
* there is no need to declare such `cv::GArray<T>` as a graph input.
*
* @note The value of `cv::GArray<T>` may be overwritten by assigning some
* other `cv::GArray<T>` to the object using `operator=` -- on the
* assigment, the old association or value is discarded.
*
* @param v a std::vector<T> to associate with this
* `cv::GArray<T>` object. Vector data is copied into the
* `cv::GArray<T>` (no reference to the passed data is held).
*/
explicit GArray(const std::vector<HT>& v) // Constant value constructor
: m_ref(detail::GArrayU(detail::VectorRef(v))) { putDetails(); }
/**
* @overload
* @brief Constructs a value-initialized `cv::GArray<T>`
*
* @param v a std::vector<T> to associate with this
* `cv::GArray<T>` object. Vector data is moved into the `cv::GArray<T>`.
*/
explicit GArray(std::vector<HT>&& v) // Move-constructor
: m_ref(detail::GArrayU(detail::VectorRef(std::move(v)))) { putDetails(); }
/**
* @brief Constructs an empty `cv::GArray<T>`
*
* Normally, empty G-API data objects denote a starting point of
* the graph. When an empty `cv::GArray<T>` is assigned to a result
* of some operation, it obtains a functional link to this
* operation (and is not empty anymore).
*/
GArray() { putDetails(); } // Empty constructor
/// @private
explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor
: m_ref(ref) { putDetails(); } // (used by GCall, not for users)
GArray() { putDetails(); } // Empty constructor
explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor
: m_ref(ref) { putDetails(); } // (used by GCall, not for users)
/// @private
detail::GArrayU strip() const {
@@ -17,13 +17,6 @@
namespace cv {
namespace gapi{
/**
* @brief This namespace contains experimental G-API functionality,
* functions or structures in this namespace are subjects to change or
* removal in the future releases. This namespace also contains
* functions which API is not stabilized yet.
*/
namespace wip {
/**
@@ -44,7 +44,6 @@ namespace detail
CV_UNKNOWN, // Unknown, generic, opaque-to-GAPI data type unsupported in graph seriallization
CV_BOOL, // bool 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_FLOAT, // float user G-API data
CV_UINT64, // uint64_t user G-API data
@@ -62,7 +61,6 @@ namespace detail
template<typename T> struct GOpaqueTraits;
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<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<float> { static constexpr const OpaqueKind kind = OpaqueKind::CV_FLOAT; };
template<> struct GOpaqueTraits<uint64_t> { static constexpr const OpaqueKind kind = OpaqueKind::CV_UINT64; };
+4 -44
View File
@@ -28,54 +28,14 @@ struct GOrigin;
/** \addtogroup gapi_data_objects
* @{
*/
/**
* @brief GFrame class represents an image or media frame in the graph.
*
* GFrame doesn't store any data itself, instead it describes a
* functional relationship between operations consuming and producing
* GFrame objects.
*
* GFrame is introduced to handle various media formats (e.g., NV12 or
* I420) under the same type. Various image formats may differ in the
* number of planes (e.g. two for NV12, three for I420) and the pixel
* layout inside. GFrame type allows to handle these media formats in
* the graph uniformly -- the graph structure will not change if the
* media format changes, e.g. a different camera or decoder is used
* with the same graph. G-API provides a number of operations which
* operate directly on GFrame, like `infer<>()` or
* renderFrame(); these operations are expected to handle different
* media formats inside. There is also a number of accessor
* operations like BGR(), Y(), UV() -- these operations provide
* access to frame's data in the familiar cv::GMat form, which can be
* used with the majority of the existing G-API operations. These
* accessor functions may perform color space converion on the fly if
* the image format of the GFrame they are applied to differs from the
* operation's semantic (e.g. the BGR() accessor is called on an NV12
* image frame).
*
* GFrame is a virtual counterpart of cv::MediaFrame.
*
* @sa cv::MediaFrame, cv::GFrameDesc, BGR(), Y(), UV(), infer<>().
*/
class GAPI_EXPORTS_W_SIMPLE GFrame
{
public:
/**
* @brief Constructs an empty GFrame
*
* Normally, empty G-API data objects denote a starting point of
* the graph. When an empty GFrame is assigned to a result of some
* operation, it obtains a functional link to this operation (and
* is not empty anymore).
*/
GAPI_WRAP GFrame(); // Empty constructor
GAPI_WRAP GFrame(); // Empty constructor
GFrame(const GNode &n, std::size_t out); // Operation result constructor
/// @private
GFrame(const GNode &n, std::size_t out); // Operation result constructor
/// @private
GOrigin& priv(); // Internal use only
/// @private
const GOrigin& priv() const; // Internal use only
GOrigin& priv(); // Internal use only
const GOrigin& priv() const; // Internal use only
private:
std::shared_ptr<GOrigin> m_priv;
@@ -372,7 +372,6 @@ namespace gapi
{
// Prework: model "Device" API before it gets to G-API headers.
// FIXME: Don't mix with internal Backends class!
/// @private
class GAPI_EXPORTS GBackend
{
public:
@@ -413,7 +412,6 @@ namespace std
namespace cv {
namespace gapi {
/// @private
class GFunctor
{
public:
+5 -33
View File
@@ -30,57 +30,29 @@ struct GOrigin;
* @brief G-API data objects used to build G-API expressions.
*
* These objects do not own any particular data (except compile-time
* associated values like with cv::GScalar or `cv::GArray<T>`) and are
* used only to construct graphs.
* associated values like with cv::GScalar) and are used to construct
* graphs.
*
* Every graph in G-API starts and ends with data objects.
*
* Once constructed and compiled, G-API operates with regular host-side
* data instead. Refer to the below table to find the mapping between
* G-API and regular data types when passing input and output data
* structures to G-API:
* G-API and regular data types.
*
* G-API data type | I/O data type
* ------------------ | -------------
* cv::GMat | cv::Mat, cv::UMat, cv::RMat
* cv::GMat | cv::Mat
* cv::GScalar | cv::Scalar
* `cv::GArray<T>` | std::vector<T>
* `cv::GOpaque<T>` | T
* cv::GFrame | cv::MediaFrame
*/
/**
* @brief GMat class represents image or tensor data in the
* graph.
*
* GMat doesn't store any data itself, instead it describes a
* functional relationship between operations consuming and producing
* GMat objects.
*
* GMat is a virtual counterpart of Mat and UMat, but it
* doesn't mean G-API use Mat or UMat objects internally to represent
* GMat objects -- the internal data representation may be
* backend-specific or optimized out at all.
*
* @sa Mat, GMatDesc
*/
class GAPI_EXPORTS_W_SIMPLE GMat
{
public:
/**
* @brief Constructs an empty GMat
*
* Normally, empty G-API data objects denote a starting point of
* the graph. When an empty GMat is assigned to a result of some
* operation, it obtains a functional link to this operation (and
* is not empty anymore).
*/
GAPI_WRAP GMat(); // Empty constructor
/// @private
GMat(const GNode &n, std::size_t out); // Operation result constructor
/// @private
GOrigin& priv(); // Internal use only
/// @private
const GOrigin& priv() const; // Internal use only
private:
+1 -26
View File
@@ -307,40 +307,15 @@ namespace detail
/** \addtogroup gapi_data_objects
* @{
*/
/**
* @brief `cv::GOpaque<T>` template class represents an object of
* class `T` in the graph.
*
* `cv::GOpaque<T>` describes a functional relationship between operations
* consuming and producing object of class `T`. `cv::GOpaque<T>` is
* designed to extend G-API with user-defined data types, which are
* often required with user-defined operations. G-API can't apply any
* optimizations to user-defined types since these types are opaque to
* the framework. However, there is a number of G-API operations
* declared with `cv::GOpaque<T>` as a return type,
* e.g. cv::gapi::streaming::timestamp() or cv::gapi::streaming::size().
*
* @sa `cv::GArray<T>`
*/
template<typename T> class GOpaque
{
public:
// Host type (or Flat type) - the type this GOpaque is actually
// specified to.
/// @private
using HT = typename detail::flatten_g<util::decay_t<T>>::type;
/**
* @brief Constructs an empty `cv::GOpaque<T>`
*
* Normally, empty G-API data objects denote a starting point of
* the graph. When an empty `cv::GOpaque<T>` is assigned to a result
* of some operation, it obtains a functional link to this
* operation (and is not empty anymore).
*/
GOpaque() { putDetails(); } // Empty constructor
/// @private
explicit GOpaque(detail::GOpaqueU &&ref) // GOpaqueU-based constructor
: m_ref(ref) { putDetails(); } // (used by GCall, not for users)
+4 -69
View File
@@ -25,83 +25,18 @@ struct GOrigin;
/** \addtogroup gapi_data_objects
* @{
*/
/**
* @brief GScalar class represents cv::Scalar data in the graph.
*
* GScalar may be associated with a cv::Scalar value, which becomes
* its constant value bound in graph compile time. cv::GScalar describes a
* functional relationship between operations consuming and producing
* GScalar objects.
*
* GScalar is a virtual counterpart of cv::Scalar, which is usually used
* to represent the GScalar data in G-API during the execution.
*
* @sa Scalar
*/
class GAPI_EXPORTS_W_SIMPLE GScalar
{
public:
/**
* @brief Constructs an empty GScalar
*
* Normally, empty G-API data objects denote a starting point of
* the graph. When an empty GScalar is assigned to a result of some
* operation, it obtains a functional link to this operation (and
* is not empty anymore).
*/
GAPI_WRAP GScalar();
/**
* @brief Constructs a value-initialized GScalar
*
* In contrast with GMat (which can be either an explicit graph input
* or a result of some operation), GScalars may have their values
* be associated at graph construction time. It is useful when
* some operation has a GScalar input which doesn't change during
* the program execution, and is set only once. In this case,
* there is no need to declare such GScalar as a graph input.
*
* @note The value of GScalar may be overwritten by assigning some
* other GScalar to the object using `operator=` -- on the
* assigment, the old GScalar value is discarded.
*
* @param s a cv::Scalar value to associate with this GScalar object.
*/
explicit GScalar(const cv::Scalar& s);
/**
* @overload
* @brief Constructs a value-initialized GScalar
*
* @param s a cv::Scalar value to associate with this GScalar object.
*/
GAPI_WRAP GScalar(); // Empty constructor
explicit GScalar(const cv::Scalar& s); // Constant value constructor from cv::Scalar
explicit GScalar(cv::Scalar&& s); // Constant value move-constructor from cv::Scalar
/**
* @overload
* @brief Constructs a value-initialized GScalar
*
* @param v0 A `double` value to associate with this GScalar. Note
* that only the first component of a four-component cv::Scalar is
* set to this value, with others remain zeros.
*
* This constructor overload is not marked `explicit` and can be
* used in G-API expression code like this:
*
* @snippet modules/gapi/samples/api_ref_snippets.cpp gscalar_implicit
*
* Here operator+(GMat,GScalar) is used to wrap cv::gapi::addC()
* and a value-initialized GScalar is created on the fly.
*
* @overload
*/
GScalar(double v0); // Constant value constructor from double
/// @private
GScalar(const GNode &n, std::size_t out); // Operation result constructor
/// @private
GOrigin& priv(); // Internal use only
/// @private
const GOrigin& priv() const; // Internal use only
private:
@@ -71,15 +71,6 @@ using GOptRunArgP = util::variant<
>;
using GOptRunArgsP = std::vector<GOptRunArgP>;
using GOptRunArg = util::variant<
optional<cv::Mat>,
optional<cv::RMat>,
optional<cv::Scalar>,
optional<cv::detail::VectorRef>,
optional<cv::detail::OpaqueRef>
>;
using GOptRunArgs = std::vector<GOptRunArg>;
namespace detail {
template<typename T> inline GOptRunArgP wrap_opt_arg(optional<T>& arg) {
@@ -205,7 +196,7 @@ public:
* @param s a shared pointer to IStreamSource representing the
* input video stream.
*/
void setSource(const gapi::wip::IStreamSource::Ptr& s);
GAPI_WRAP void setSource(const gapi::wip::IStreamSource::Ptr& s);
/**
* @brief Constructs and specifies an input video stream for a
@@ -264,7 +255,7 @@ public:
// NB: Used from python
/// @private -- Exclude this function from OpenCV documentation
GAPI_WRAP std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> pull();
GAPI_WRAP std::tuple<bool, cv::GRunArgs> pull();
/**
* @brief Get some next available data from the pipeline.
@@ -381,14 +372,6 @@ protected:
/** @} */
namespace gapi {
/**
* @brief This namespace contains G-API functions, structures, and
* symbols related to the Streaming execution mode.
*
* Some of the operations defined in this namespace (e.g. size(),
* BGR(), etc.) can be used in the traditional execution mode too.
*/
namespace streaming {
/**
* @brief Specify queue capacity for streaming execution.
@@ -47,10 +47,6 @@ void validateFindingContoursMeta(const int depth, const int chan, const int mode
namespace cv { namespace gapi {
/**
* @brief This namespace contains G-API Operation Types for OpenCV
* ImgProc module functionality.
*/
namespace imgproc {
using GMat2 = std::tuple<GMat,GMat>;
using GMat3 = std::tuple<GMat,GMat,GMat>; // FIXME: how to avoid this?
+3 -6
View File
@@ -136,12 +136,11 @@ public:
}
template <typename U>
GInferInputsTyped<Ts...>& setInput(const std::string& name, U in)
void setInput(const std::string& name, U in)
{
m_priv->blobs.emplace(std::piecewise_construct,
std::forward_as_tuple(name),
std::forward_as_tuple(in));
return *this;
}
using StorageT = cv::util::variant<Ts...>;
@@ -654,8 +653,7 @@ namespace gapi {
// A type-erased form of network parameters.
// Similar to how a type-erased GKernel is represented and used.
/// @private
struct GAPI_EXPORTS_W_SIMPLE GNetParam {
struct GAPI_EXPORTS GNetParam {
std::string tag; // FIXME: const?
GBackend backend; // Specifies the execution model
util::any params; // Backend-interpreted parameter structure
@@ -666,13 +664,12 @@ struct GAPI_EXPORTS_W_SIMPLE GNetParam {
*/
/**
* @brief A container class for network configurations. Similar to
* GKernelPackage. Use cv::gapi::networks() to construct this object.
* GKernelPackage.Use cv::gapi::networks() to construct this object.
*
* @sa cv::gapi::networks
*/
struct GAPI_EXPORTS_W_SIMPLE GNetPackage {
GAPI_WRAP GNetPackage() = default;
GAPI_WRAP explicit GNetPackage(std::vector<GNetParam> nets);
explicit GNetPackage(std::initializer_list<GNetParam> ii);
std::vector<GBackend> backends() const;
std::vector<GNetParam> networks;
+4 -45
View File
@@ -24,11 +24,6 @@
namespace cv {
namespace gapi {
// FIXME: introduce a new sub-namespace for NN?
/**
* @brief This namespace contains G-API OpenVINO backend functions,
* structures, and symbols.
*/
namespace ie {
GAPI_EXPORTS cv::gapi::GBackend backend();
@@ -74,11 +69,7 @@ struct ParamDesc {
std::map<std::string, std::vector<std::size_t>> reshape_table;
std::unordered_set<std::string> layer_names_to_reshape;
// NB: Number of asyncrhonious infer requests
size_t nireq;
// NB: An optional config to setup RemoteContext for IE
cv::util::any context_config;
};
} // namespace detail
@@ -119,8 +110,7 @@ public:
, {}
, {}
, {}
, 1u
, {}} {
, 1u} {
};
/** @overload
@@ -140,8 +130,7 @@ public:
, {}
, {}
, {}
, 1u
, {}} {
, 1u} {
};
/** @brief Specifies sequence of network input layers names for inference.
@@ -223,30 +212,6 @@ public:
return *this;
}
/** @brief Specifies configuration for RemoteContext in InferenceEngine.
When RemoteContext is configured the backend imports the networks using the context.
It also expects cv::MediaFrames to be actually remote, to operate with blobs via the context.
@param ctx_cfg cv::util::any value which holds InferenceEngine::ParamMap.
@return reference to this parameter structure.
*/
Params& cfgContextParams(const cv::util::any& ctx_cfg) {
desc.context_config = ctx_cfg;
return *this;
}
/** @overload
Function with an rvalue parameter.
@param ctx_cfg cv::util::any value which holds InferenceEngine::ParamMap.
@return reference to this parameter structure.
*/
Params& cfgContextParams(cv::util::any&& ctx_cfg) {
desc.context_config = std::move(ctx_cfg);
return *this;
}
/** @brief Specifies number of asynchronous inference requests.
@param nireq Number of inference asynchronous requests.
@@ -348,10 +313,7 @@ public:
const std::string &model,
const std::string &weights,
const std::string &device)
: desc{ model, weights, device, {}, {}, {}, 0u, 0u,
detail::ParamDesc::Kind::Load, true, {}, {}, {}, 1u,
{}},
m_tag(tag) {
: desc{ model, weights, device, {}, {}, {}, 0u, 0u, detail::ParamDesc::Kind::Load, true, {}, {}, {}, 1u}, m_tag(tag) {
};
/** @overload
@@ -366,10 +328,7 @@ public:
Params(const std::string &tag,
const std::string &model,
const std::string &device)
: desc{ model, {}, device, {}, {}, {}, 0u, 0u,
detail::ParamDesc::Kind::Import, true, {}, {}, {}, 1u,
{}},
m_tag(tag) {
: desc{ model, {}, device, {}, {}, {}, 0u, 0u, detail::ParamDesc::Kind::Import, true, {}, {}, {}, 1u}, m_tag(tag) {
};
/** @see ie::Params::pluginConfig. */
@@ -20,10 +20,6 @@
namespace cv {
namespace gapi {
/**
* @brief This namespace contains G-API ONNX Runtime backend functions, structures, and symbols.
*/
namespace onnx {
GAPI_EXPORTS cv::gapi::GBackend backend();
@@ -64,13 +64,12 @@ detection is smaller than confidence threshold, detection is rejected.
given label will get to the output.
@return a tuple with a vector of detected boxes and a vector of appropriate labels.
*/
GAPI_EXPORTS_W std::tuple<GArray<Rect>, GArray<int>> parseSSD(const GMat& in,
const GOpaque<Size>& inSz,
const float confidenceThreshold = 0.5f,
const int filterLabel = -1);
/** @brief Parses output of SSD network.
GAPI_EXPORTS std::tuple<GArray<Rect>, GArray<int>> parseSSD(const GMat& in,
const GOpaque<Size>& inSz,
const float confidenceThreshold = 0.5f,
const int filterLabel = -1);
/** @overload
Extracts detection information (box, confidence) from SSD output and
filters it by given confidence and by going out of bounds.
@@ -88,9 +87,9 @@ the larger side of the rectangle.
*/
GAPI_EXPORTS_W GArray<Rect> parseSSD(const GMat& in,
const GOpaque<Size>& inSz,
const float confidenceThreshold,
const bool alignmentToSquare,
const bool filterOutOfBounds);
const float confidenceThreshold = 0.5f,
const bool alignmentToSquare = false,
const bool filterOutOfBounds = false);
/** @brief Parses output of Yolo network.
@@ -113,12 +112,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>.
@return a tuple with a vector of detected boxes and a vector of appropriate labels.
*/
GAPI_EXPORTS_W std::tuple<GArray<Rect>, GArray<int>> parseYolo(const GMat& in,
const GOpaque<Size>& inSz,
const float confidenceThreshold = 0.5f,
const float nmsThreshold = 0.5f,
const std::vector<float>& anchors
= nn::parsers::GParseYolo::defaultAnchors());
GAPI_EXPORTS std::tuple<GArray<Rect>, GArray<int>> parseYolo(const GMat& in,
const GOpaque<Size>& inSz,
const float confidenceThreshold = 0.5f,
const float nmsThreshold = 0.5f,
const std::vector<float>& anchors
= nn::parsers::GParseYolo::defaultAnchors());
} // namespace gapi
} // namespace cv
+10 -146
View File
@@ -17,107 +17,28 @@
namespace cv {
/** \addtogroup gapi_data_structures
* @{
*
* @brief Extra G-API data structures used to pass input/output data
* to the graph for processing.
*/
/**
* @brief cv::MediaFrame class represents an image/media frame
* obtained from an external source.
*
* cv::MediaFrame represents image data as specified in
* cv::MediaFormat. cv::MediaFrame is designed to be a thin wrapper over some
* external memory of buffer; the class itself provides an uniform
* interface over such types of memory. cv::MediaFrame wraps data from
* a camera driver or from a media codec and provides an abstraction
* layer over this memory to G-API. MediaFrame defines a compact interface
* to access and manage the underlying data; the implementation is
* fully defined by the associated Adapter (which is usually
* user-defined).
*
* @sa cv::RMat
*/
class GAPI_EXPORTS MediaFrame {
public:
/// This enum defines different types of cv::MediaFrame provided
/// access to the underlying data. Note that different flags can't
/// be combined in this version.
enum class Access {
R, ///< Access data for reading
W, ///< Access data for writing
};
enum class Access { R, W };
class IAdapter;
class View;
using AdapterPtr = std::unique_ptr<IAdapter>;
/**
* @brief Constructs an empty MediaFrame
*
* The constructed object has no any data associated with it.
*/
MediaFrame();
explicit MediaFrame(AdapterPtr &&);
template<class T, class... Args> static cv::MediaFrame Create(Args&&...);
/**
* @brief Constructs a MediaFrame with the given
* Adapter. MediaFrame takes ownership over the passed adapter.
*
* @param p an unique pointer to instance of IAdapter derived class.
*/
explicit MediaFrame(AdapterPtr &&p);
/**
* @overload
* @brief Constructs a MediaFrame with the given parameters for
* the Adapter. The adapter of type `T` is costructed on the fly.
*
* @param args list of arguments to construct an adapter of type
* `T`.
*/
template<class T, class... Args> static cv::MediaFrame Create(Args&&... args);
/**
* @brief Obtain access to the underlying data with the given
* mode.
*
* Depending on the associated Adapter and the data wrapped, this
* method may be cheap (e.g., the underlying memory is local) or
* costly (if the underlying memory is external or device
* memory).
*
* @param mode an access mode flag
* @return a MediaFrame::View object. The views should be handled
* carefully, refer to the MediaFrame::View documentation for details.
*/
View access(Access mode) const;
/**
* @brief Returns a media frame descriptor -- the information
* about the media format, dimensions, etc.
* @return a cv::GFrameDesc
*/
View access(Access) const;
cv::GFrameDesc desc() const;
// FIXME: design a better solution
// Should be used only if the actual adapter provides implementation
/// @private -- exclude from the OpenCV documentation for now.
cv::util::any blobParams() const;
/**
* @brief Casts and returns the associated MediaFrame adapter to
* the particular adapter type `T`, returns nullptr if the type is
* different.
*
* This method may be useful if the adapter type is known by the
* caller, and some lower level access to the memory is required.
* Depending on the memory type, it may be more efficient than
* access().
*
* @return a pointer to the adapter object, nullptr if the adapter
* type is different.
*/
template<typename T> T* get() const {
// Cast underlying MediaFrame adapter to the particular adapter type,
// return nullptr if underlying type is different
template<typename T> T* get() const
{
static_assert(std::is_base_of<IAdapter, T>::value,
"T is not derived from cv::MediaFrame::IAdapter!");
auto* adapter = getAdapter();
@@ -137,43 +58,6 @@ inline cv::MediaFrame cv::MediaFrame::Create(Args&&... args) {
return cv::MediaFrame(std::move(ptr));
}
/**
* @brief Provides access to the MediaFrame's underlying data.
*
* This object contains the necessary information to access the pixel
* data of the associated MediaFrame: arrays of pointers and strides
* (distance between every plane row, in bytes) for every image
* plane, as defined in cv::MediaFormat.
* There may be up to four image planes in MediaFrame.
*
* Depending on the MediaFrame::Access flag passed in
* MediaFrame::access(), a MediaFrame::View may be read- or
* write-only.
*
* Depending on the MediaFrame::IAdapter implementation associated
* with the parent MediaFrame, writing to memory with
* MediaFrame::Access::R flag may have no effect or lead to
* undefined behavior. Same applies to reading the memory with
* MediaFrame::Access::W flag -- again, depending on the IAdapter
* implementation, the host-side buffer the view provides access to
* may have no current data stored in (so in-place editing of the
* buffer contents may not be possible).
*
* MediaFrame::View objects must be handled carefully, as an external
* resource associated with MediaFrame may be locked for the time the
* MediaFrame::View object exists. Obtaining MediaFrame::View should
* be seen as "map" and destroying it as "unmap" in the "map/unmap"
* idiom (applicable to OpenCL, device memory, remote
* memory).
*
* When a MediaFrame buffer is accessed for writing, and the memory
* under MediaFrame::View::Ptrs is altered, the data synchronization
* of a host-side and device/remote buffer is not guaranteed until the
* MediaFrame::View is destroyed. In other words, the real data on the
* device or in a remote target may be updated at the MediaFrame::View
* destruction only -- but it depends on the associated
* MediaFrame::IAdapter implementation.
*/
class GAPI_EXPORTS MediaFrame::View final {
public:
static constexpr const size_t MAX_PLANES = 4;
@@ -181,38 +65,19 @@ public:
using Strides = std::array<std::size_t, MAX_PLANES>; // in bytes
using Callback = std::function<void()>;
/// @private
View(Ptrs&& ptrs, Strides&& strs, Callback &&cb = [](){});
/// @private
View(const View&) = delete;
/// @private
View(View&&) = default;
/// @private
View& operator = (const View&) = delete;
~View();
Ptrs ptr; ///< Array of image plane pointers
Strides stride; ///< Array of image plane strides, in bytes.
Ptrs ptr;
Strides stride;
private:
Callback m_cb;
};
/**
* @brief An interface class for MediaFrame data adapters.
*
* Implement this interface to wrap media data in the MediaFrame. It
* makes sense to implement this class if there is a custom
* cv::gapi::wip::IStreamSource defined -- in this case, a stream
* source can produce MediaFrame objects with this adapter and the
* media data may be passed to graph without any copy. For example, a
* GStreamer-based stream source can implement an adapter over
* `GstBuffer` and G-API will transparently use it in the graph.
*/
class GAPI_EXPORTS MediaFrame::IAdapter {
public:
virtual ~IAdapter() = 0;
@@ -222,7 +87,6 @@ public:
// The default implementation does nothing
virtual cv::util::any blobParams() const;
};
/** @} */
} //namespace cv
@@ -29,9 +29,6 @@ namespace gimpl
namespace gapi
{
/**
* @brief This namespace contains G-API OpenCL backend functions, structures, and symbols.
*/
namespace ocl
{
/**
@@ -13,13 +13,11 @@
# define GAPI_EXPORTS CV_EXPORTS
/* special informative macros for wrapper generators */
# define GAPI_PROP CV_PROP
# define GAPI_PROP_RW CV_PROP_RW
# define GAPI_WRAP CV_WRAP
# define GAPI_EXPORTS_W_SIMPLE CV_EXPORTS_W_SIMPLE
# define GAPI_EXPORTS_W CV_EXPORTS_W
# else
# define GAPI_PROP
# define GAPI_PROP_RW
# define GAPI_WRAP
# define GAPI_EXPORTS
# define GAPI_EXPORTS_W_SIMPLE
@@ -15,11 +15,6 @@ namespace cv
{
namespace gapi
{
/**
* @brief This namespace contains G-API own data structures used in
* its standalone mode build.
*/
namespace own
{
@@ -15,11 +15,6 @@ namespace cv
{
namespace gapi
{
/**
* @brief This namespace contains G-API PlaidML backend functions,
* structures, and symbols.
*/
namespace plaidml
{
@@ -13,15 +13,6 @@
namespace cv {
namespace gapi {
/**
* @brief This namespace contains G-API Python backend functions,
* structures, and symbols.
*
* This functionality is required to enable G-API custom operations
* and kernels when using G-API from Python, no need to use it in the
* C++ form.
*/
namespace python {
GAPI_EXPORTS cv::gapi::GBackend backend();
@@ -81,9 +81,9 @@ using GMatDesc2 = std::tuple<cv::GMatDesc,cv::GMatDesc>;
@param prims vector of drawing primitivies
@param args graph compile time parameters
*/
void GAPI_EXPORTS_W render(cv::Mat& bgr,
const Prims& prims,
cv::GCompileArgs&& args = {});
void GAPI_EXPORTS render(cv::Mat& bgr,
const Prims& prims,
cv::GCompileArgs&& args = {});
/** @brief The function renders on two NV12 planes passed drawing primitivies
@@ -92,10 +92,10 @@ void GAPI_EXPORTS_W render(cv::Mat& bgr,
@param prims vector of drawing primitivies
@param args graph compile time parameters
*/
void GAPI_EXPORTS_W render(cv::Mat& y_plane,
cv::Mat& uv_plane,
const Prims& prims,
cv::GCompileArgs&& args = {});
void GAPI_EXPORTS render(cv::Mat& y_plane,
cv::Mat& uv_plane,
const Prims& prims,
cv::GCompileArgs&& args = {});
/** @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 prims draw primitives
*/
GAPI_EXPORTS_W GMat render3ch(const GMat& src, const GArray<Prim>& prims);
GAPI_EXPORTS GMat render3ch(const GMat& src, const GArray<Prim>& prims);
/** @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 prims draw primitives
*/
GAPI_EXPORTS_W GMat2 renderNV12(const GMat& y,
const GMat& uv,
const GArray<Prim>& prims);
GAPI_EXPORTS GMat2 renderNV12(const GMat& y,
const GMat& uv,
const GArray<Prim>& prims);
/** @brief Renders Media Frame
@@ -169,15 +169,11 @@ GAPI_EXPORTS GFrame renderFrame(const GFrame& m_frame,
} // namespace draw
} // namespace wip
/**
* @brief This namespace contains G-API CPU rendering backend functions,
* structures, and symbols. See @ref gapi_draw for details.
*/
namespace render
{
namespace ocv
{
GAPI_EXPORTS_W cv::gapi::GKernelPackage kernels();
GAPI_EXPORTS cv::gapi::GKernelPackage kernels();
} // namespace ocv
} // namespace render
@@ -41,7 +41,7 @@ struct freetype_font
*
* Parameters match cv::putText().
*/
struct GAPI_EXPORTS_W_SIMPLE Text
struct Text
{
/**
* @brief Text constructor
@@ -55,7 +55,6 @@ struct GAPI_EXPORTS_W_SIMPLE Text
* @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
*/
GAPI_WRAP
Text(const std::string& text_,
const cv::Point& org_,
int ff_,
@@ -69,18 +68,17 @@ struct GAPI_EXPORTS_W_SIMPLE Text
{
}
GAPI_WRAP
Text() = default;
/*@{*/
GAPI_PROP_RW std::string text; //!< The text string to be drawn
GAPI_PROP_RW cv::Point org; //!< The bottom-left corner of the text string in the image
GAPI_PROP_RW int ff; //!< The font type, see #HersheyFonts
GAPI_PROP_RW double fs; //!< The font scale factor that is multiplied by the font-specific base size
GAPI_PROP_RW cv::Scalar color; //!< The text color
GAPI_PROP_RW int thick; //!< The thickness of the lines used to draw a text
GAPI_PROP_RW int lt; //!< The line type. See #LineTypes
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
std::string text; //!< The text string to be drawn
cv::Point org; //!< The bottom-left corner of the text string in the image
int ff; //!< The font type, see #HersheyFonts
double fs; //!< The font scale factor that is multiplied by the font-specific base size
cv::Scalar color; //!< The text color
int thick; //!< The thickness of the lines used to draw a text
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
/*@{*/
};
@@ -124,7 +122,7 @@ struct FText
*
* Parameters match cv::rectangle().
*/
struct GAPI_EXPORTS_W_SIMPLE Rect
struct Rect
{
/**
* @brief Rect constructor
@@ -144,15 +142,14 @@ struct GAPI_EXPORTS_W_SIMPLE Rect
{
}
GAPI_WRAP
Rect() = default;
/*@{*/
GAPI_PROP_RW cv::Rect rect; //!< Coordinates of the rectangle
GAPI_PROP_RW cv::Scalar color; //!< The rectangle color or brightness (grayscale image)
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
GAPI_PROP_RW int lt; //!< The type of the line. See #LineTypes
GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinates
cv::Rect rect; //!< Coordinates of the rectangle
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
int lt; //!< The type of the line. See #LineTypes
int shift; //!< The number of fractional bits in the point coordinates
/*@{*/
};
@@ -161,7 +158,7 @@ struct GAPI_EXPORTS_W_SIMPLE Rect
*
* Parameters match cv::circle().
*/
struct GAPI_EXPORTS_W_SIMPLE Circle
struct Circle
{
/**
* @brief Circle constructor
@@ -173,7 +170,6 @@ struct GAPI_EXPORTS_W_SIMPLE Circle
* @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
*/
GAPI_WRAP
Circle(const cv::Point& center_,
int radius_,
const cv::Scalar& color_,
@@ -184,16 +180,15 @@ struct GAPI_EXPORTS_W_SIMPLE Circle
{
}
GAPI_WRAP
Circle() = default;
/*@{*/
GAPI_PROP_RW cv::Point center; //!< The center of the circle
GAPI_PROP_RW int radius; //!< The radius of the circle
GAPI_PROP_RW cv::Scalar color; //!< The color of the circle
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
GAPI_PROP_RW int lt; //!< The Type of the circle boundary. See #LineTypes
GAPI_PROP_RW int shift; //!< The Number of fractional bits in the coordinates of the center and in the radius value
cv::Point center; //!< The center of the circle
int radius; //!< The radius of the circle
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
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
/*@{*/
};
@@ -202,7 +197,7 @@ struct GAPI_EXPORTS_W_SIMPLE Circle
*
* Parameters match cv::line().
*/
struct GAPI_EXPORTS_W_SIMPLE Line
struct Line
{
/**
* @brief Line constructor
@@ -214,7 +209,6 @@ struct GAPI_EXPORTS_W_SIMPLE Line
* @param lt_ The Type of the line. See #LineTypes
* @param shift_ The number of fractional bits in the point coordinates
*/
GAPI_WRAP
Line(const cv::Point& pt1_,
const cv::Point& pt2_,
const cv::Scalar& color_,
@@ -225,16 +219,15 @@ struct GAPI_EXPORTS_W_SIMPLE Line
{
}
GAPI_WRAP
Line() = default;
/*@{*/
GAPI_PROP_RW cv::Point pt1; //!< The first point of the line segment
GAPI_PROP_RW cv::Point pt2; //!< The second point of the line segment
GAPI_PROP_RW cv::Scalar color; //!< The line color
GAPI_PROP_RW int thick; //!< The thickness of line
GAPI_PROP_RW int lt; //!< The Type of the line. See #LineTypes
GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinates
cv::Point pt1; //!< The first point of the line segment
cv::Point pt2; //!< The second point of the line segment
cv::Scalar color; //!< The line color
int thick; //!< The thickness of line
int lt; //!< The Type of the line. See #LineTypes
int shift; //!< The number of fractional bits in the point coordinates
/*@{*/
};
@@ -243,7 +236,7 @@ struct GAPI_EXPORTS_W_SIMPLE Line
*
* Mosaicing is a very basic method to obfuscate regions in the image.
*/
struct GAPI_EXPORTS_W_SIMPLE Mosaic
struct Mosaic
{
/**
* @brief Mosaic constructor
@@ -259,13 +252,12 @@ struct GAPI_EXPORTS_W_SIMPLE Mosaic
{
}
GAPI_WRAP
Mosaic() : cellSz(0), decim(0) {}
/*@{*/
GAPI_PROP_RW cv::Rect mos; //!< Coordinates of the mosaic
GAPI_PROP_RW int cellSz; //!< Cell size (same for X, Y)
GAPI_PROP_RW int decim; //!< Decimation (0 stands for no decimation)
cv::Rect mos; //!< Coordinates of the mosaic
int cellSz; //!< Cell size (same for X, Y)
int decim; //!< Decimation (0 stands for no decimation)
/*@{*/
};
@@ -274,7 +266,7 @@ struct GAPI_EXPORTS_W_SIMPLE Mosaic
*
* Image is blended on a frame using the specified mask.
*/
struct GAPI_EXPORTS_W_SIMPLE Image
struct Image
{
/**
* @brief Mosaic constructor
@@ -283,7 +275,6 @@ struct GAPI_EXPORTS_W_SIMPLE Image
* @param img_ Image to draw
* @param alpha_ Alpha channel for image to draw (same size and number of channels)
*/
GAPI_WRAP
Image(const cv::Point& org_,
const cv::Mat& img_,
const cv::Mat& alpha_) :
@@ -291,20 +282,19 @@ struct GAPI_EXPORTS_W_SIMPLE Image
{
}
GAPI_WRAP
Image() = default;
/*@{*/
GAPI_PROP_RW cv::Point org; //!< The bottom-left corner of the image
GAPI_PROP_RW cv::Mat img; //!< Image to draw
GAPI_PROP_RW cv::Mat alpha; //!< Alpha channel for image to draw (same size and number of channels)
cv::Point org; //!< The bottom-left corner of the image
cv::Mat img; //!< Image to draw
cv::Mat alpha; //!< Alpha channel for image to draw (same size and number of channels)
/*@{*/
};
/**
* @brief This structure represents a polygon to draw.
*/
struct GAPI_EXPORTS_W_SIMPLE Poly
struct Poly
{
/**
* @brief Mosaic constructor
@@ -315,7 +305,6 @@ struct GAPI_EXPORTS_W_SIMPLE Poly
* @param lt_ The Type of the line. See #LineTypes
* @param shift_ The number of fractional bits in the point coordinate
*/
GAPI_WRAP
Poly(const std::vector<cv::Point>& points_,
const cv::Scalar& color_,
int thick_ = 1,
@@ -325,15 +314,14 @@ struct GAPI_EXPORTS_W_SIMPLE Poly
{
}
GAPI_WRAP
Poly() = default;
/*@{*/
GAPI_PROP_RW std::vector<cv::Point> points; //!< Points to connect
GAPI_PROP_RW cv::Scalar color; //!< The line color
GAPI_PROP_RW int thick; //!< The thickness of line
GAPI_PROP_RW int lt; //!< The Type of the line. See #LineTypes
GAPI_PROP_RW int shift; //!< The number of fractional bits in the point coordinate
std::vector<cv::Point> points; //!< Points to connect
cv::Scalar color; //!< The line color
int thick; //!< The thickness of line
int lt; //!< The Type of the line. See #LineTypes
int shift; //!< The number of fractional bits in the point coordinate
/*@{*/
};
@@ -348,7 +336,7 @@ using Prim = util::variant
, Poly
>;
using Prims = std::vector<Prim>;
using Prims = std::vector<Prim>;
//! @} gapi_draw_prims
} // namespace draw
@@ -42,9 +42,6 @@ namespace cv {
// performCalculations(in_view, out_view);
// // data from out_view is transferred to the device when out_view is destroyed
// }
/** \addtogroup gapi_data_structures
* @{
*/
class GAPI_EXPORTS RMat
{
public:
@@ -149,7 +146,6 @@ private:
template<typename T, typename... Ts>
RMat make_rmat(Ts&&... args) { return { std::make_shared<T>(std::forward<Ts>(args)...) }; }
/** @} */
} //namespace cv
@@ -12,11 +12,6 @@
namespace cv {
namespace gapi {
/**
* @brief This namespace contains G-API serialization and
* deserialization functions and data structures.
*/
namespace s11n {
struct IOStream;
struct IIStream;
@@ -38,11 +38,6 @@ enum class StereoOutputFormat {
DISPARITY_16Q_11_4 = DISPARITY_FIXED16_12_4 ///< Same as DISPARITY_FIXED16_12_4
};
/**
* @brief This namespace contains G-API Operation Types for Stereo and
* related functionality.
*/
namespace calib3d {
G_TYPED_KERNEL(GStereo, <GMat(GMat, GMat, const StereoOutputFormat)>, "org.opencv.stereo") {
@@ -74,7 +74,7 @@ e.g when graph's input needs to be passed directly to output, like in Streaming
@param in Input image
@return Copy of the input
*/
GAPI_EXPORTS_W GMat copy(const GMat& in);
GAPI_EXPORTS GMat copy(const GMat& in);
/** @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,
@@ -42,10 +42,6 @@ struct GAPI_EXPORTS KalmanParams
Mat controlMatrix;
};
/**
* @brief This namespace contains G-API Operations and functions for
* video-oriented algorithms, like optical flow and background subtraction.
*/
namespace video
{
using GBuildPyrOutput = std::tuple<GArray<GMat>, GScalar>;
@@ -11,36 +11,6 @@ def register(mname):
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')
class GOpaque():
# NB: Inheritance from c++ class cause segfault.
@@ -84,10 +54,6 @@ class GOpaque():
def __new__(self):
return cv.GOpaqueT(cv.gapi.CV_RECT)
class Prim():
def __new__(self):
return cv.GOpaqueT(cv.gapi.CV_DRAW_PRIM)
class Any():
def __new__(self):
return cv.GOpaqueT(cv.gapi.CV_ANY)
@@ -147,10 +113,6 @@ class GArray():
def __new__(self):
return cv.GArrayT(cv.gapi.CV_GMAT)
class Prim():
def __new__(self):
return cv.GArray(cv.gapi.CV_DRAW_PRIM)
class Any():
def __new__(self):
return cv.GArray(cv.gapi.CV_ANY)
@@ -172,7 +134,6 @@ def op(op_id, in_types, out_types):
cv.GArray.Scalar: cv.gapi.CV_SCALAR,
cv.GArray.Mat: cv.gapi.CV_MAT,
cv.GArray.GMat: cv.gapi.CV_GMAT,
cv.GArray.Prim: cv.gapi.CV_DRAW_PRIM,
cv.GArray.Any: cv.gapi.CV_ANY
}
@@ -188,24 +149,22 @@ def op(op_id, in_types, out_types):
cv.GOpaque.Point2f: cv.gapi.CV_POINT2F,
cv.GOpaque.Size: cv.gapi.CV_SIZE,
cv.GOpaque.Rect: cv.gapi.CV_RECT,
cv.GOpaque.Prim: cv.gapi.CV_DRAW_PRIM,
cv.GOpaque.Any: cv.gapi.CV_ANY
}
type2str = {
cv.gapi.CV_BOOL: 'cv.gapi.CV_BOOL' ,
cv.gapi.CV_INT: 'cv.gapi.CV_INT' ,
cv.gapi.CV_DOUBLE: 'cv.gapi.CV_DOUBLE' ,
cv.gapi.CV_FLOAT: 'cv.gapi.CV_FLOAT' ,
cv.gapi.CV_STRING: 'cv.gapi.CV_STRING' ,
cv.gapi.CV_POINT: 'cv.gapi.CV_POINT' ,
cv.gapi.CV_POINT2F: 'cv.gapi.CV_POINT2F' ,
cv.gapi.CV_SIZE: 'cv.gapi.CV_SIZE',
cv.gapi.CV_RECT: 'cv.gapi.CV_RECT',
cv.gapi.CV_SCALAR: 'cv.gapi.CV_SCALAR',
cv.gapi.CV_MAT: 'cv.gapi.CV_MAT',
cv.gapi.CV_GMAT: 'cv.gapi.CV_GMAT',
cv.gapi.CV_DRAW_PRIM: 'cv.gapi.CV_DRAW_PRIM'
cv.gapi.CV_BOOL: 'cv.gapi.CV_BOOL' ,
cv.gapi.CV_INT: 'cv.gapi.CV_INT' ,
cv.gapi.CV_DOUBLE: 'cv.gapi.CV_DOUBLE' ,
cv.gapi.CV_FLOAT: 'cv.gapi.CV_FLOAT' ,
cv.gapi.CV_STRING: 'cv.gapi.CV_STRING' ,
cv.gapi.CV_POINT: 'cv.gapi.CV_POINT' ,
cv.gapi.CV_POINT2F: 'cv.gapi.CV_POINT2F' ,
cv.gapi.CV_SIZE: 'cv.gapi.CV_SIZE',
cv.gapi.CV_RECT: 'cv.gapi.CV_RECT',
cv.gapi.CV_SCALAR: 'cv.gapi.CV_SCALAR',
cv.gapi.CV_MAT: 'cv.gapi.CV_MAT',
cv.gapi.CV_GMAT: 'cv.gapi.CV_GMAT'
}
# NB: Second lvl decorator takes class to decorate
@@ -285,13 +244,3 @@ def kernel(op_cls):
return cls
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
+161 -287
View File
@@ -17,7 +17,6 @@ using gapi_ie_PyParams = cv::gapi::ie::PyParams;
using gapi_wip_IStreamSource_Ptr = cv::Ptr<cv::gapi::wip::IStreamSource>;
using detail_ExtractArgsCallback = cv::detail::ExtractArgsCallback;
using detail_ExtractMetaCallback = cv::detail::ExtractMetaCallback;
using vector_GNetParam = std::vector<cv::gapi::GNetParam>;
// NB: Python wrapper generate T_U for T<U>
// This behavior is only observed for inputs
@@ -43,7 +42,6 @@ using GArray_Rect = cv::GArray<cv::Rect>;
using GArray_Scalar = cv::GArray<cv::Scalar>;
using GArray_Mat = cv::GArray<cv::Mat>;
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,
// so it cause error: "string wasn't declared"
@@ -126,66 +124,6 @@ PyObject* pyopencv_from(const cv::detail::PyObjectHolder& v)
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& info)
{
#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)
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<>
PyObject* pyopencv_from(const cv::GArg& value)
{
@@ -198,21 +136,20 @@ PyObject* pyopencv_from(const cv::GArg& value)
#define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break
switch (value.opaque_kind)
{
HANDLE_CASE(BOOL, bool);
HANDLE_CASE(INT, int);
HANDLE_CASE(INT64, int64_t);
HANDLE_CASE(DOUBLE, double);
HANDLE_CASE(FLOAT, float);
HANDLE_CASE(STRING, std::string);
HANDLE_CASE(POINT, cv::Point);
HANDLE_CASE(POINT2F, cv::Point2f);
HANDLE_CASE(SIZE, cv::Size);
HANDLE_CASE(RECT, cv::Rect);
HANDLE_CASE(SCALAR, cv::Scalar);
HANDLE_CASE(MAT, cv::Mat);
HANDLE_CASE(UNKNOWN, cv::detail::PyObjectHolder);
HANDLE_CASE(DRAW_PRIM, cv::gapi::wip::draw::Prim);
HANDLE_CASE(BOOL, bool);
HANDLE_CASE(INT, int);
HANDLE_CASE(DOUBLE, double);
HANDLE_CASE(FLOAT, float);
HANDLE_CASE(STRING, std::string);
HANDLE_CASE(POINT, cv::Point);
HANDLE_CASE(POINT2F, cv::Point2f);
HANDLE_CASE(SIZE, cv::Size);
HANDLE_CASE(RECT, cv::Rect);
HANDLE_CASE(SCALAR, cv::Scalar);
HANDLE_CASE(MAT, cv::Mat);
HANDLE_CASE(UNKNOWN, cv::detail::PyObjectHolder);
UNSUPPORTED(UINT64);
UNSUPPORTED(DRAW_PRIM);
#undef HANDLE_CASE
#undef UNSUPPORTED
}
@@ -226,18 +163,6 @@ bool pyopencv_to(PyObject* obj, cv::GArg& value, const ArgInfo& info)
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 <>
bool pyopencv_to(PyObject* obj, std::vector<GCompileArg>& value, const ArgInfo& info)
{
@@ -250,6 +175,12 @@ PyObject* pyopencv_from(const std::vector<GCompileArg>& 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<>
PyObject* pyopencv_from(const cv::detail::OpaqueRef& o)
{
@@ -257,7 +188,6 @@ 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_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_FLOAT : return pyopencv_from(o.rref<float>());
case cv::detail::OpaqueKind::CV_STRING : return pyopencv_from(o.rref<std::string>());
@@ -266,10 +196,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_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_DRAW_PRIM : return pyopencv_from(o.rref<cv::gapi::wip::draw::Prim>());
case cv::detail::OpaqueKind::CV_UINT64 : break;
case cv::detail::OpaqueKind::CV_SCALAR : break;
case cv::detail::OpaqueKind::CV_MAT : break;
case cv::detail::OpaqueKind::CV_DRAW_PRIM : break;
}
PyErr_SetString(PyExc_TypeError, "Unsupported GOpaque type");
@@ -283,7 +213,6 @@ 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_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_FLOAT : return pyopencv_from_generic_vec(v.rref<float>());
case cv::detail::OpaqueKind::CV_STRING : return pyopencv_from_generic_vec(v.rref<std::string>());
@@ -294,8 +223,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_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_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_DRAW_PRIM : break;
}
PyErr_SetString(PyExc_TypeError, "Unsupported GArray type");
@@ -320,69 +249,52 @@ PyObject* pyopencv_from(const GRunArg& v)
return pyopencv_from(util::get<cv::detail::OpaqueRef>(v));
}
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");
PyErr_SetString(PyExc_TypeError, "Failed to unpack GRunArgs");
return NULL;
}
template<>
PyObject* pyopencv_from(const GRunArgs& value)
{
return value.size() == 1 ? pyopencv_from(value[0]) : pyopencv_from_generic_vec(value);
size_t i, n = value.size();
// 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<>
PyObject* pyopencv_from(const GOptRunArgs& value)
bool pyopencv_to(PyObject* obj, GMetaArgs& value, const ArgInfo& info)
{
return value.size() == 1 ? pyopencv_from(value[0]) : pyopencv_from_generic_vec(value);
return pyopencv_to_generic_vec(obj, value, info);
}
// FIXME: cv::variant should be wrapped once for all types.
template <>
PyObject* pyopencv_from(const cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>& v)
template<>
PyObject* pyopencv_from(const GMetaArgs& 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;
return pyopencv_from_generic_vec(value);
}
template <typename T>
@@ -406,16 +318,16 @@ void pyopencv_to_generic_vec_with_check(PyObject* from,
}
template <typename T>
static T extract_proto_args(PyObject* py_args)
static PyObject* extract_proto_args(PyObject* py_args, PyObject* kw)
{
using namespace cv;
GProtoArgs args;
Py_ssize_t size = PyList_Size(py_args);
Py_ssize_t size = PyTuple_Size(py_args);
args.reserve(size);
for (int i = 0; i < size; ++i)
{
PyObject* item = PyList_GetItem(py_args, i);
PyObject* item = PyTuple_GetItem(py_args, i);
if (PyObject_TypeCheck(item, reinterpret_cast<PyTypeObject*>(pyopencv_GScalar_TypePtr)))
{
args.emplace_back(reinterpret_cast<pyopencv_GScalar_t*>(item)->v);
@@ -434,11 +346,22 @@ static T extract_proto_args(PyObject* py_args)
}
else
{
util::throw_error(std::logic_error("Unsupported type for GProtoArgs"));
PyErr_SetString(PyExc_TypeError, "Unsupported type for cv.GIn()/cv.GOut()");
return NULL;
}
}
return T(std::move(args));
return pyopencv_from<T>(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)
@@ -463,7 +386,6 @@ static cv::detail::OpaqueRef extract_opaque_ref(PyObject* from, cv::detail::Opaq
HANDLE_CASE(RECT, cv::Rect);
HANDLE_CASE(UNKNOWN, cv::GArg);
UNSUPPORTED(UINT64);
UNSUPPORTED(INT64);
UNSUPPORTED(SCALAR);
UNSUPPORTED(MAT);
UNSUPPORTED(DRAW_PRIM);
@@ -484,21 +406,20 @@ static cv::detail::VectorRef extract_vector_ref(PyObject* from, cv::detail::Opaq
#define UNSUPPORTED(T) case cv::detail::OpaqueKind::CV_##T: break
switch (kind)
{
HANDLE_CASE(BOOL, bool);
HANDLE_CASE(INT, int);
HANDLE_CASE(DOUBLE, double);
HANDLE_CASE(FLOAT, float);
HANDLE_CASE(STRING, std::string);
HANDLE_CASE(POINT, cv::Point);
HANDLE_CASE(POINT2F, cv::Point2f);
HANDLE_CASE(SIZE, cv::Size);
HANDLE_CASE(RECT, cv::Rect);
HANDLE_CASE(SCALAR, cv::Scalar);
HANDLE_CASE(MAT, cv::Mat);
HANDLE_CASE(UNKNOWN, cv::GArg);
HANDLE_CASE(DRAW_PRIM, cv::gapi::wip::draw::Prim);
HANDLE_CASE(BOOL, bool);
HANDLE_CASE(INT, int);
HANDLE_CASE(DOUBLE, double);
HANDLE_CASE(FLOAT, float);
HANDLE_CASE(STRING, std::string);
HANDLE_CASE(POINT, cv::Point);
HANDLE_CASE(POINT2F, cv::Point2f);
HANDLE_CASE(SIZE, cv::Size);
HANDLE_CASE(RECT, cv::Rect);
HANDLE_CASE(SCALAR, cv::Scalar);
HANDLE_CASE(MAT, cv::Mat);
HANDLE_CASE(UNKNOWN, cv::GArg);
UNSUPPORTED(UINT64);
UNSUPPORTED(INT64);
UNSUPPORTED(DRAW_PRIM);
#undef HANDLE_CASE
#undef UNSUPPORTED
}
@@ -549,15 +470,13 @@ 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)
{
GAPI_Assert(PyList_Check(py_args));
cv::GRunArgs args;
Py_ssize_t list_size = PyList_Size(py_args);
args.reserve(list_size);
Py_ssize_t tuple_size = PyTuple_Size(py_args);
args.reserve(tuple_size);
for (int i = 0; i < list_size; ++i)
for (int i = 0; i < tuple_size; ++i)
{
args.push_back(extract_run_arg(info[i], PyList_GetItem(py_args, i)));
args.push_back(extract_run_arg(info[i], PyTuple_GetItem(py_args, i)));
}
return args;
@@ -598,15 +517,13 @@ 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)
{
GAPI_Assert(PyList_Check(py_args));
cv::GMetaArgs metas;
Py_ssize_t list_size = PyList_Size(py_args);
metas.reserve(list_size);
Py_ssize_t tuple_size = PyTuple_Size(py_args);
metas.reserve(tuple_size);
for (int i = 0; i < list_size; ++i)
for (int i = 0; i < tuple_size; ++i)
{
metas.push_back(extract_meta_arg(info[i], PyList_GetItem(py_args, i)));
metas.push_back(extract_meta_arg(info[i], PyTuple_GetItem(py_args, i)));
}
return metas;
@@ -664,8 +581,7 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel,
cv::detail::PyObjectHolder result(
PyObject_CallObject(kernel.get(), args.get()), false);
if (PyErr_Occurred())
{
if (PyErr_Occurred()) {
PyErr_PrintEx(0);
PyErr_Clear();
throw std::logic_error("Python kernel failed with error!");
@@ -673,27 +589,8 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel,
// NB: In fact it's impossible situation, becase errors were handled above.
GAPI_Assert(result.get() && "Python kernel returned NULL!");
if (out_info.size() == 1)
{
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);
}
outs = out_info.size() == 1 ? cv::GRunArgs{extract_run_arg(out_info[0], result.get())}
: extract_run_args(out_info, result.get());
}
catch (...)
{
@@ -748,9 +645,8 @@ static cv::GMetaArgs get_meta_args(PyObject* tuple)
}
static GMetaArgs run_py_meta(cv::detail::PyObjectHolder out_meta,
const cv::GMetaArgs &meta,
const cv::GArgs &gargs)
{
const cv::GMetaArgs &meta,
const cv::GArgs &gargs) {
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
@@ -792,8 +688,7 @@ static GMetaArgs run_py_meta(cv::detail::PyObjectHolder out_meta,
cv::detail::PyObjectHolder result(
PyObject_CallObject(out_meta.get(), args.get()), false);
if (PyErr_Occurred())
{
if (PyErr_Occurred()) {
PyErr_PrintEx(0);
PyErr_Clear();
throw std::logic_error("Python outMeta failed with error!");
@@ -825,24 +720,21 @@ static PyObject* pyopencv_cv_gapi_kernels(PyObject* , PyObject* py_args, PyObjec
PyObject* user_kernel = PyTuple_GetItem(py_args, i);
PyObject* id_obj = PyObject_GetAttrString(user_kernel, "id");
if (!id_obj)
{
if (!id_obj) {
PyErr_SetString(PyExc_TypeError,
"Python kernel should contain id, please use cv.gapi.kernel to define kernel");
return NULL;
}
PyObject* out_meta = PyObject_GetAttrString(user_kernel, "outMeta");
if (!out_meta)
{
if (!out_meta) {
PyErr_SetString(PyExc_TypeError,
"Python kernel should contain outMeta, please use cv.gapi.kernel to define kernel");
return NULL;
}
PyObject* run = PyObject_GetAttrString(user_kernel, "run");
if (!run)
{
if (!run) {
PyErr_SetString(PyExc_TypeError,
"Python kernel should contain run, please use cv.gapi.kernel to define kernel");
return NULL;
@@ -864,6 +756,23 @@ static PyObject* pyopencv_cv_gapi_kernels(PyObject* , PyObject* py_args, PyObjec
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*)
{
using namespace cv;
@@ -925,54 +834,53 @@ static PyObject* pyopencv_cv_gapi_op(PyObject* , PyObject* py_args, PyObject*)
return pyopencv_from(cv::gapi::wip::op(id, outMetaWrapper, std::move(args)));
}
template<>
bool pyopencv_to(PyObject* obj, cv::detail::ExtractArgsCallback& value, const ArgInfo&)
static PyObject* pyopencv_cv_gin(PyObject*, PyObject* py_args, PyObject*)
{
cv::detail::PyObjectHolder holder{obj};
value = cv::detail::ExtractArgsCallback{[=](const cv::GTypesInfo& info)
{
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
cv::detail::PyObjectHolder holder{py_args};
auto callback = 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 (...)
{
cv::GRunArgs args;
try
{
args = extract_run_args(info, holder.get());
}
catch (...)
{
PyGILState_Release(gstate);
throw;
}
PyGILState_Release(gstate);
throw;
}
PyGILState_Release(gstate);
return args;
}};
return true;
return args;
}};
return pyopencv_from(callback);
}
template<>
bool pyopencv_to(PyObject* obj, cv::detail::ExtractMetaCallback& value, const ArgInfo&)
static PyObject* pyopencv_cv_descr_of(PyObject*, PyObject* py_args, PyObject*)
{
cv::detail::PyObjectHolder holder{obj};
value = cv::detail::ExtractMetaCallback{[=](const cv::GTypesInfo& info)
{
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
Py_INCREF(py_args);
auto callback = cv::detail::ExtractMetaCallback{[=](const cv::GTypesInfo& info)
{
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
cv::GMetaArgs args;
try
{
args = extract_meta_args(info, holder.get());
}
catch (...)
{
cv::GMetaArgs args;
try
{
args = extract_meta_args(info, py_args);
}
catch (...)
{
PyGILState_Release(gstate);
throw;
}
PyGILState_Release(gstate);
throw;
}
PyGILState_Release(gstate);
return args;
}};
return true;
return args;
}};
return pyopencv_from(callback);
}
template<typename T>
@@ -987,12 +895,9 @@ struct PyOpenCV_Converter<cv::GArray<T>>
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_GArrayT_TypePtr)))
{
auto& array = reinterpret_cast<pyopencv_GArrayT_t*>(obj)->v;
try
{
try {
value = cv::util::get<cv::GArray<T>>(array.arg());
}
catch (...)
{
} catch (...) {
return false;
}
return true;
@@ -1013,12 +918,9 @@ struct PyOpenCV_Converter<cv::GOpaque<T>>
if (PyObject_TypeCheck(obj, reinterpret_cast<PyTypeObject*>(pyopencv_GOpaqueT_TypePtr)))
{
auto& opaque = reinterpret_cast<pyopencv_GOpaqueT_t*>(obj)->v;
try
{
try {
value = cv::util::get<cv::GOpaque<T>>(opaque.arg());
}
catch (...)
{
} catch (...) {
return false;
}
return true;
@@ -1027,39 +929,11 @@ 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
#define PYOPENCV_EXTRA_METHODS_GAPI \
{"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"},
+13 -21
View File
@@ -10,7 +10,6 @@
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/garg.hpp>
#include <opencv2/gapi/gopaque.hpp>
#include <opencv2/gapi/render/render_types.hpp> // Prim
#define ID(T, E) T
#define ID_(T, E) ID(T, E),
@@ -25,29 +24,24 @@
GAPI_Assert(false && "Unsupported type"); \
}
using cv::gapi::wip::draw::Prim;
#define GARRAY_TYPE_LIST_G(G, G2) \
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, 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(float , cv::gapi::ArgType::CV_FLOAT, G) \
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
WRAP_ARGS(cv::Point , cv::gapi::ArgType::CV_POINT, G) \
WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G) \
WRAP_ARGS(cv::Size , cv::gapi::ArgType::CV_SIZE, G) \
WRAP_ARGS(cv::Rect , cv::gapi::ArgType::CV_RECT, G) \
WRAP_ARGS(cv::Scalar , cv::gapi::ArgType::CV_SCALAR, G) \
WRAP_ARGS(cv::Mat , cv::gapi::ArgType::CV_MAT, G) \
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) \
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \
WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \
WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \
WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
WRAP_ARGS(cv::Point , cv::gapi::ArgType::CV_POINT, G) \
WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G) \
WRAP_ARGS(cv::Size , cv::gapi::ArgType::CV_SIZE, G) \
WRAP_ARGS(cv::Rect , cv::gapi::ArgType::CV_RECT, G) \
WRAP_ARGS(cv::Scalar , cv::gapi::ArgType::CV_SCALAR, G) \
WRAP_ARGS(cv::Mat , cv::gapi::ArgType::CV_MAT, 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) \
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, 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(float , cv::gapi::ArgType::CV_FLOAT, G) \
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
@@ -64,7 +58,6 @@ namespace gapi {
enum ArgType {
CV_BOOL,
CV_INT,
CV_INT64,
CV_DOUBLE,
CV_FLOAT,
CV_STRING,
@@ -75,7 +68,6 @@ enum ArgType {
CV_SCALAR,
CV_MAT,
CV_GMAT,
CV_DRAW_PRIM,
CV_ANY,
};
@@ -1,467 +0,0 @@
import argparse
import time
import numpy as np
import cv2 as cv
# ------------------------Service operations------------------------
def weight_path(model_path):
""" Get path of weights based on path to IR
Params:
model_path: the string contains path to IR file
Return:
Path to weights file
"""
assert model_path.endswith('.xml'), "Wrong topology path was provided"
return model_path[:-3] + 'bin'
def build_argparser():
""" Parse arguments from command line
Return:
Pack of arguments from command line
"""
parser = argparse.ArgumentParser(description='This is an OpenCV-based version of Gaze Estimation example')
parser.add_argument('--input',
help='Path to the input video file')
parser.add_argument('--out',
help='Path to the output video file')
parser.add_argument('--facem',
default='face-detection-retail-0005.xml',
help='Path to OpenVINO face detection model (.xml)')
parser.add_argument('--faced',
default='CPU',
help='Target device for the face detection' +
'(e.g. CPU, GPU, VPU, ...)')
parser.add_argument('--headm',
default='head-pose-estimation-adas-0001.xml',
help='Path to OpenVINO head pose estimation model (.xml)')
parser.add_argument('--headd',
default='CPU',
help='Target device for the head pose estimation inference ' +
'(e.g. CPU, GPU, VPU, ...)')
parser.add_argument('--landm',
default='facial-landmarks-35-adas-0002.xml',
help='Path to OpenVINO landmarks detector model (.xml)')
parser.add_argument('--landd',
default='CPU',
help='Target device for the landmarks detector (e.g. CPU, GPU, VPU, ...)')
parser.add_argument('--gazem',
default='gaze-estimation-adas-0002.xml',
help='Path to OpenVINO gaze vector estimaiton model (.xml)')
parser.add_argument('--gazed',
default='CPU',
help='Target device for the gaze vector estimation inference ' +
'(e.g. CPU, GPU, VPU, ...)')
parser.add_argument('--eyem',
default='open-closed-eye-0001.xml',
help='Path to OpenVINO open closed eye model (.xml)')
parser.add_argument('--eyed',
default='CPU',
help='Target device for the eyes state inference (e.g. CPU, GPU, VPU, ...)')
return parser
# ------------------------Support functions for custom kernels------------------------
def intersection(surface, rect):
""" Remove zone of out of bound from ROI
Params:
surface: image bounds is rect representation (top left coordinates and width and height)
rect: region of interest is also has rect representation
Return:
Modified ROI with correct bounds
"""
l_x = max(surface[0], rect[0])
l_y = max(surface[1], rect[1])
width = min(surface[0] + surface[2], rect[0] + rect[2]) - l_x
height = min(surface[1] + surface[3], rect[1] + rect[3]) - l_y
if width < 0 or height < 0:
return (0, 0, 0, 0)
return (l_x, l_y, width, height)
def process_landmarks(r_x, r_y, r_w, r_h, landmarks):
""" Create points from result of inference of facial-landmarks network and size of input image
Params:
r_x: x coordinate of top left corner of input image
r_y: y coordinate of top left corner of input image
r_w: width of input image
r_h: height of input image
landmarks: result of inference of facial-landmarks network
Return:
Array of landmarks points for one face
"""
lmrks = landmarks[0]
raw_x = lmrks[::2] * r_w + r_x
raw_y = lmrks[1::2] * r_h + r_y
return np.array([[int(x), int(y)] for x, y in zip(raw_x, raw_y)])
def eye_box(p_1, p_2, scale=1.8):
""" Get bounding box of eye
Params:
p_1: point of left edge of eye
p_2: point of right edge of eye
scale: change size of box with this value
Return:
Bounding box of eye and its midpoint
"""
size = np.linalg.norm(p_1 - p_2)
midpoint = (p_1 + p_2) / 2
width = scale * size
height = width
p_x = midpoint[0] - (width / 2)
p_y = midpoint[1] - (height / 2)
return (int(p_x), int(p_y), int(width), int(height)), list(map(int, midpoint))
# ------------------------Custom graph operations------------------------
@cv.gapi.op('custom.GProcessPoses',
in_types=[cv.GArray.GMat, cv.GArray.GMat, cv.GArray.GMat],
out_types=[cv.GArray.GMat])
class GProcessPoses:
@staticmethod
def outMeta(arr_desc0, arr_desc1, arr_desc2):
return cv.empty_array_desc()
@cv.gapi.op('custom.GParseEyes',
in_types=[cv.GArray.GMat, cv.GArray.Rect, cv.GOpaque.Size],
out_types=[cv.GArray.Rect, cv.GArray.Rect, cv.GArray.Point, cv.GArray.Point])
class GParseEyes:
@staticmethod
def outMeta(arr_desc0, arr_desc1, arr_desc2):
return cv.empty_array_desc(), cv.empty_array_desc(), \
cv.empty_array_desc(), cv.empty_array_desc()
@cv.gapi.op('custom.GGetStates',
in_types=[cv.GArray.GMat, cv.GArray.GMat],
out_types=[cv.GArray.Int, cv.GArray.Int])
class GGetStates:
@staticmethod
def outMeta(arr_desc0, arr_desc1):
return cv.empty_array_desc(), cv.empty_array_desc()
# ------------------------Custom kernels------------------------
@cv.gapi.kernel(GProcessPoses)
class GProcessPosesImpl:
""" Custom kernel. Processed poses of heads
"""
@staticmethod
def run(in_ys, in_ps, in_rs):
""" Сustom kernel executable code
Params:
in_ys: yaw angle of head
in_ps: pitch angle of head
in_rs: roll angle of head
Return:
Arrays with heads poses
"""
out_poses = []
size = len(in_ys)
for i in range(size):
out_poses.append(np.array([in_ys[i][0], in_ps[i][0], in_rs[i][0]]).T)
return out_poses
@cv.gapi.kernel(GParseEyes)
class GParseEyesImpl:
""" Custom kernel. Get information about eyes
"""
@staticmethod
def run(in_landm_per_face, in_face_rcs, frame_size):
""" Сustom kernel executable code
Params:
in_landm_per_face: landmarks from inference of facial-landmarks network for each face
in_face_rcs: bounding boxes for each face
frame_size: size of input image
Return:
Arrays of ROI for left and right eyes, array of midpoints and
array of landmarks points
"""
left_eyes = []
right_eyes = []
midpoints = []
lmarks = []
num_faces = len(in_landm_per_face)
surface = (0, 0, *frame_size)
for i in range(num_faces):
rect = in_face_rcs[i]
points = process_landmarks(*rect, in_landm_per_face[i])
for p in points:
lmarks.append(p)
size = int(len(in_landm_per_face[i][0]) / 2)
rect, midpoint_l = eye_box(lmarks[0 + i * size], lmarks[1 + i * size])
left_eyes.append(intersection(surface, rect))
rect, midpoint_r = eye_box(lmarks[2 + i * size], lmarks[3 + i * size])
right_eyes.append(intersection(surface, rect))
midpoints += [midpoint_l, midpoint_r]
return left_eyes, right_eyes, midpoints, lmarks
@cv.gapi.kernel(GGetStates)
class GGetStatesImpl:
""" Custom kernel. Get state of eye - open or closed
"""
@staticmethod
def run(eyesl, eyesr):
""" Сustom kernel executable code
Params:
eyesl: result of inference of open-closed-eye network for left eye
eyesr: result of inference of open-closed-eye network for right eye
Return:
States of left eyes and states of right eyes
"""
size = len(eyesl)
out_l_st = []
out_r_st = []
for i in range(size):
for st in eyesl[i]:
out_l_st += [1 if st[0] < st[1] else 0]
for st in eyesr[i]:
out_r_st += [1 if st[0] < st[1] else 0]
return out_l_st, out_r_st
if __name__ == '__main__':
ARGUMENTS = build_argparser().parse_args()
# ------------------------Demo's graph------------------------
g_in = cv.GMat()
# Detect faces
face_inputs = cv.GInferInputs()
face_inputs.setInput('data', g_in)
face_outputs = cv.gapi.infer('face-detection', face_inputs)
faces = face_outputs.at('detection_out')
# Parse faces
sz = cv.gapi.streaming.size(g_in)
faces_rc = cv.gapi.parseSSD(faces, sz, 0.5, False, False)
# Detect poses
head_inputs = cv.GInferInputs()
head_inputs.setInput('data', g_in)
face_outputs = cv.gapi.infer('head-pose', faces_rc, head_inputs)
angles_y = face_outputs.at('angle_y_fc')
angles_p = face_outputs.at('angle_p_fc')
angles_r = face_outputs.at('angle_r_fc')
# Parse poses
heads_pos = GProcessPoses.on(angles_y, angles_p, angles_r)
# Detect landmarks
landmark_inputs = cv.GInferInputs()
landmark_inputs.setInput('data', g_in)
landmark_outputs = cv.gapi.infer('facial-landmarks', faces_rc,
landmark_inputs)
landmark = landmark_outputs.at('align_fc3')
# Parse landmarks
left_eyes, right_eyes, mids, lmarks = GParseEyes.on(landmark, faces_rc, sz)
# Detect eyes
eyes_inputs = cv.GInferInputs()
eyes_inputs.setInput('input.1', g_in)
eyesl_outputs = cv.gapi.infer('open-closed-eye', left_eyes, eyes_inputs)
eyesr_outputs = cv.gapi.infer('open-closed-eye', right_eyes, eyes_inputs)
eyesl = eyesl_outputs.at('19')
eyesr = eyesr_outputs.at('19')
# Process eyes states
l_eye_st, r_eye_st = GGetStates.on(eyesl, eyesr)
# Gaze estimation
gaze_inputs = cv.GInferListInputs()
gaze_inputs.setInput('left_eye_image', left_eyes)
gaze_inputs.setInput('right_eye_image', right_eyes)
gaze_inputs.setInput('head_pose_angles', heads_pos)
gaze_outputs = cv.gapi.infer2('gaze-estimation', g_in, gaze_inputs)
gaze_vectors = gaze_outputs.at('gaze_vector')
out = cv.gapi.copy(g_in)
# ------------------------End of graph------------------------
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(out,
faces_rc,
left_eyes,
right_eyes,
gaze_vectors,
angles_y,
angles_p,
angles_r,
l_eye_st,
r_eye_st,
mids,
lmarks))
# Networks
face_net = cv.gapi.ie.params('face-detection', ARGUMENTS.facem,
weight_path(ARGUMENTS.facem), ARGUMENTS.faced)
head_pose_net = cv.gapi.ie.params('head-pose', ARGUMENTS.headm,
weight_path(ARGUMENTS.headm), ARGUMENTS.headd)
landmarks_net = cv.gapi.ie.params('facial-landmarks', ARGUMENTS.landm,
weight_path(ARGUMENTS.landm), ARGUMENTS.landd)
gaze_net = cv.gapi.ie.params('gaze-estimation', ARGUMENTS.gazem,
weight_path(ARGUMENTS.gazem), ARGUMENTS.gazed)
eye_net = cv.gapi.ie.params('open-closed-eye', ARGUMENTS.eyem,
weight_path(ARGUMENTS.eyem), ARGUMENTS.eyed)
nets = cv.gapi.networks(face_net, head_pose_net, landmarks_net, gaze_net, eye_net)
# Kernels pack
kernels = cv.gapi.kernels(GParseEyesImpl, GProcessPosesImpl, GGetStatesImpl)
# ------------------------Execution part------------------------
ccomp = comp.compileStreaming(args=cv.gapi.compile_args(kernels, nets))
source = cv.gapi.wip.make_capture_src(ARGUMENTS.input)
ccomp.setSource(cv.gin(source))
ccomp.start()
frames = 0
fps = 0
print('Processing')
START_TIME = time.time()
while True:
start_time_cycle = time.time()
has_frame, (oimg,
outr,
l_eyes,
r_eyes,
outg,
out_y,
out_p,
out_r,
out_st_l,
out_st_r,
out_mids,
outl) = ccomp.pull()
if not has_frame:
break
# Draw
GREEN = (0, 255, 0)
RED = (0, 0, 255)
WHITE = (255, 255, 255)
BLUE = (255, 0, 0)
PINK = (255, 0, 255)
YELLOW = (0, 255, 255)
M_PI_180 = np.pi / 180
M_PI_2 = np.pi / 2
M_PI = np.pi
FACES_SIZE = len(outr)
for i, out_rect in enumerate(outr):
# Face box
cv.rectangle(oimg, out_rect, WHITE, 1)
rx, ry, rwidth, rheight = out_rect
# Landmarks
lm_radius = int(0.01 * rwidth + 1)
lmsize = int(len(outl) / FACES_SIZE)
for j in range(lmsize):
cv.circle(oimg, outl[j + i * lmsize], lm_radius, YELLOW, -1)
# Headposes
yaw = out_y[i]
pitch = out_p[i]
roll = out_r[i]
sin_y = np.sin(yaw[:] * M_PI_180)
sin_p = np.sin(pitch[:] * M_PI_180)
sin_r = np.sin(roll[:] * M_PI_180)
cos_y = np.cos(yaw[:] * M_PI_180)
cos_p = np.cos(pitch[:] * M_PI_180)
cos_r = np.cos(roll[:] * M_PI_180)
axis_length = 0.4 * rwidth
x_center = int(rx + rwidth / 2)
y_center = int(ry + rheight / 2)
# center to right
cv.line(oimg, [x_center, y_center],
[int(x_center + axis_length * (cos_r * cos_y + sin_y * sin_p * sin_r)),
int(y_center + axis_length * cos_p * sin_r)],
RED, 2)
# center to top
cv.line(oimg, [x_center, y_center],
[int(x_center + axis_length * (cos_r * sin_y * sin_p + cos_y * sin_r)),
int(y_center - axis_length * cos_p * cos_r)],
GREEN, 2)
# center to forward
cv.line(oimg, [x_center, y_center],
[int(x_center + axis_length * sin_y * cos_p),
int(y_center + axis_length * sin_p)],
PINK, 2)
scale_box = 0.002 * rwidth
cv.putText(oimg, "head pose: (y=%0.0f, p=%0.0f, r=%0.0f)" %
(np.round(yaw), np.round(pitch), np.round(roll)),
[int(rx), int(ry + rheight + 5 * rwidth / 100)],
cv.FONT_HERSHEY_PLAIN, scale_box * 2, WHITE, 1)
# Eyes boxes
color_l = GREEN if out_st_l[i] else RED
cv.rectangle(oimg, l_eyes[i], color_l, 1)
color_r = GREEN if out_st_r[i] else RED
cv.rectangle(oimg, r_eyes[i], color_r, 1)
# Gaze vectors
norm_gazes = np.linalg.norm(outg[i][0])
gaze_vector = outg[i][0] / norm_gazes
arrow_length = 0.4 * rwidth
gaze_arrow = [arrow_length * gaze_vector[0], -arrow_length * gaze_vector[1]]
left_arrow = [int(a+b) for a, b in zip(out_mids[0 + i * 2], gaze_arrow)]
right_arrow = [int(a+b) for a, b in zip(out_mids[1 + i * 2], gaze_arrow)]
if out_st_l[i]:
cv.arrowedLine(oimg, out_mids[0 + i * 2], left_arrow, BLUE, 2)
if out_st_r[i]:
cv.arrowedLine(oimg, out_mids[1 + i * 2], right_arrow, BLUE, 2)
v0, v1, v2 = outg[i][0]
gaze_angles = [180 / M_PI * (M_PI_2 + np.arctan2(v2, v0)),
180 / M_PI * (M_PI_2 - np.arccos(v1 / norm_gazes))]
cv.putText(oimg, "gaze angles: (h=%0.0f, v=%0.0f)" %
(np.round(gaze_angles[0]), np.round(gaze_angles[1])),
[int(rx), int(ry + rheight + 12 * rwidth / 100)],
cv.FONT_HERSHEY_PLAIN, scale_box * 2, WHITE, 1)
# Add FPS value to frame
cv.putText(oimg, "FPS: %0i" % (fps), [int(20), int(40)],
cv.FONT_HERSHEY_PLAIN, 2, RED, 2)
# Show result
cv.imshow('Gaze Estimation', oimg)
fps = int(1. / (time.time() - start_time_cycle))
frames += 1
EXECUTION_TIME = time.time() - START_TIME
print('Execution successful')
print('Mean FPS is ', int(frames / EXECUTION_TIME))
+52 -68
View File
@@ -3,80 +3,64 @@
namespace cv
{
struct GAPI_EXPORTS_W_SIMPLE GCompileArg
{
GAPI_WRAP GCompileArg(gapi::GKernelPackage pkg);
GAPI_WRAP GCompileArg(gapi::GNetPackage pkg);
};
struct GAPI_EXPORTS_W_SIMPLE GCompileArg { };
class GAPI_EXPORTS_W_SIMPLE GInferInputs
{
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);
};
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage pkg);
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GNetPackage pkg);
GAPI_EXPORTS_W GCompileArgs compile_args(gapi::GKernelPackage kernels, gapi::GNetPackage nets);
class GAPI_EXPORTS_W_SIMPLE GInferListInputs
{
public:
GAPI_WRAP GInferListInputs();
GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray<cv::GMat>& value);
GAPI_WRAP GInferListInputs setInput(const std::string& name, const cv::GArray<cv::Rect>& value);
};
// NB: This classes doesn't exist in *.so
// HACK: Mark them as a class to force python wrapper generate code for this entities
class GAPI_EXPORTS_W_SIMPLE GProtoArg { };
class GAPI_EXPORTS_W_SIMPLE GProtoInputArgs { };
class GAPI_EXPORTS_W_SIMPLE GProtoOutputArgs { };
class GAPI_EXPORTS_W_SIMPLE GRunArg { };
class GAPI_EXPORTS_W_SIMPLE GMetaArg { GAPI_WRAP GMetaArg(); };
class GAPI_EXPORTS_W_SIMPLE GInferOutputs
{
public:
GAPI_WRAP GInferOutputs();
GAPI_WRAP cv::GMat at(const std::string& name);
};
using GProtoInputArgs = GIOProtoArgs<In_Tag>;
using GProtoOutputArgs = GIOProtoArgs<Out_Tag>;
class GAPI_EXPORTS_W_SIMPLE GInferListOutputs
{
public:
GAPI_WRAP GInferListOutputs();
GAPI_WRAP cv::GArray<cv::GMat> at(const std::string& name);
};
class GAPI_EXPORTS_W_SIMPLE GInferInputs
{
public:
GAPI_WRAP GInferInputs();
GAPI_WRAP void setInput(const std::string& name, const cv::GMat& value);
GAPI_WRAP void setInput(const std::string& name, const cv::GFrame& value);
};
namespace gapi
{
namespace wip
{
class GAPI_EXPORTS_W IStreamSource { };
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 GInferListInputs
{
public:
GAPI_WRAP GInferListInputs();
GAPI_WRAP void setInput(const std::string& name, const cv::GArray<cv::GMat>& value);
GAPI_WRAP void setInput(const std::string& name, const cv::GArray<cv::Rect>& value);
};
struct Mosaic
{
GAPI_WRAP Mosaic(const cv::Rect2i& mos_, int cellSz_, int decim_);
};
} // 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 GInferOutputs
{
public:
GAPI_WRAP GInferOutputs();
GAPI_WRAP cv::GMat at(const std::string& name);
};
GAPI_EXPORTS_W cv::GMat desync(const cv::GMat &g);
} // namespace streaming
} // namespace gapi
class GAPI_EXPORTS_W_SIMPLE GInferListOutputs
{
public:
GAPI_WRAP GInferListOutputs();
GAPI_WRAP cv::GArray<cv::GMat> at(const std::string& name);
};
namespace detail
{
gapi::GNetParam GAPI_EXPORTS_W strip(gapi::ie::PyParams params);
} // namespace detail
namespace detail
{
struct GAPI_EXPORTS_W_SIMPLE ExtractArgsCallback { };
struct GAPI_EXPORTS_W_SIMPLE ExtractMetaCallback { };
} // namespace detail
namespace gapi
{
namespace wip
{
class GAPI_EXPORTS_W IStreamSource { };
} // namespace wip
} // namespace gapi
} // namespace cv
+157 -179
View File
@@ -3,209 +3,187 @@
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')
# 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())
]
# 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):
# TODO: Extend to use any type and size here
sz = (720, 1280)
in1 = np.full(sz, 100)
in2 = np.full(sz, 50)
def test_add(self):
# TODO: Extend to use any type and size here
sz = (720, 1280)
in1 = np.full(sz, 100)
in2 = np.full(sz, 50)
# OpenCV
expected = cv.add(in1, in2)
# 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))
# 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.gapi.compile_args(pkg))
# Comparison
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
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_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')
self.assertEqual(expected.dtype, actual.dtype, 'Failed on ' + pkg_name + ' backend')
self.assertEqual(e.dtype, a.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)
def test_threshold(self):
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
in_mat = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
maxv = (30, 30)
# OpenCV
expected = cv.add(in1, in2)
# OpenCV
expected_thresh, expected_mat = cv.threshold(in_mat, maxv[0], maxv[0], cv.THRESH_TRIANGLE)
# 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))
# 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 = comp.apply(cv.gin(in1, in2), args=cv.gapi.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')
for pkg_name, pkg in pkgs:
actual_mat, actual_thresh = comp.apply(cv.gin(in_mat, maxv), args=cv.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 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.gapi.compile_args(pkg))
# Comparison
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
'Failed on ' + pkg_name + ' backend')
def generate_random_points(self, sz):
arr = np.random.random(sz).astype(np.float32).T
return list(zip(arr[0], arr[1]))
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)
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 = []
# OpenCV
expected = cv.split(in_mat)
# G-API
data = cv.GArrayT(cv.gapi.CV_POINT2F)
best_labels = cv.GArrayT(cv.gapi.CV_INT)
# 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))
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));
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')
compact, labels, centers = comp.apply(cv.gin(in_vector, in_labels));
def test_threshold(self):
img_path = self.find_file('cv/face/david2.jpg', [os.environ.get('OPENCV_TEST_DATA_PATH')])
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
# Assert
self.assertTrue(compact >= 0)
self.assertEqual(amount, len(labels))
self.assertEqual(K, len(centers))
if __name__ == '__main__':
@@ -3,124 +3,103 @@
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')
# 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())
]
# 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):
# 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')])
in1 = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
def test_good_features_to_track(self):
# 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')])
in1 = cv.cvtColor(cv.imread(img_path), cv.COLOR_RGB2GRAY)
# 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
# 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
expected = cv.goodFeaturesToTrack(in1, max_corners, quality_lvl,
min_distance, mask=mask,
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
# OpenCV
expected = cv.goodFeaturesToTrack(in1, max_corners, quality_lvl,
min_distance, mask=mask,
blockSize=block_sz, useHarrisDetector=use_harris_detector, k=k)
# G-API
g_in = cv.GMat()
g_out = cv.gapi.goodFeaturesToTrack(g_in, max_corners, quality_lvl,
min_distance, mask, block_sz, use_harris_detector, k)
# G-API
g_in = cv.GMat()
g_out = cv.gapi.goodFeaturesToTrack(g_in, max_corners, quality_lvl,
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:
actual = comp.apply(cv.gin(in1), args=cv.gapi.compile_args(pkg))
# NB: OpenCV & G-API have different output shapes:
# OpenCV - (num_points, 1, 2)
# G-API - (num_points, 2)
# Comparison
self.assertEqual(0.0, cv.norm(expected.flatten(),
np.array(actual, dtype=np.float32).flatten(),
cv.NORM_INF),
'Failed on ' + pkg_name + ' backend')
for pkg_name, pkg in pkgs:
actual = comp.apply(cv.gin(in1), args=cv.compile_args(pkg))
# NB: OpenCV & G-API have different output shapes:
# OpenCV - (num_points, 1, 2)
# G-API - (num_points, 2)
# Comparison
self.assertEqual(0.0, cv.norm(expected.flatten(),
np.array(actual, dtype=np.float32).flatten(),
cv.NORM_INF),
'Failed on ' + pkg_name + ' backend')
def test_rgb2gray(self):
# 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')])
in1 = cv.imread(img_path)
def test_rgb2gray(self):
# 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')])
in1 = cv.imread(img_path)
# OpenCV
expected = cv.cvtColor(in1, cv.COLOR_RGB2GRAY)
# OpenCV
expected = cv.cvtColor(in1, cv.COLOR_RGB2GRAY)
# G-API
g_in = cv.GMat()
g_out = cv.gapi.RGB2Gray(g_in)
# G-API
g_in = cv.GMat()
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:
actual = comp.apply(cv.gin(in1), args=cv.gapi.compile_args(pkg))
# Comparison
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
'Failed on ' + pkg_name + ' backend')
for pkg_name, pkg in pkgs:
actual = comp.apply(cv.gin(in1), args=cv.compile_args(pkg))
# Comparison
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
'Failed on ' + pkg_name + ' backend')
def test_bounding_rect(self):
sz = 1280
fscale = 256
def test_bounding_rect(self):
sz = 1280
fscale = 256
def sample_value(fscale):
return np.random.uniform(0, 255 * fscale) / fscale
def sample_value(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
expected = cv.boundingRect(points)
# OpenCV
expected = cv.boundingRect(points)
# G-API
g_in = cv.GMat()
g_out = cv.gapi.boundingRect(g_in)
# G-API
g_in = cv.GMat()
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:
actual = comp.apply(cv.gin(points), args=cv.gapi.compile_args(pkg))
# Comparison
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
'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
for pkg_name, pkg in pkgs:
actual = comp.apply(cv.gin(points), args=cv.compile_args(pkg))
# Comparison
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF),
'Failed on ' + pkg_name + ' backend')
if __name__ == '__main__':
+256 -276
View File
@@ -3,338 +3,318 @@
import numpy as np
import cv2 as cv
import os
import sys
import unittest
from tests_common import NewOpenCVTests
try:
class test_gapi_infer(NewOpenCVTests):
if sys.version_info[:2] < (3, 0):
raise unittest.SkipTest('Python 2.x is not supported')
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())
class test_gapi_infer(NewOpenCVTests):
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 make_roi(self, img, roi):
return img[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2], ...]
def make_roi(self, img, roi):
return img[roi[1]:roi[1] + roi[3], roi[0]:roi[0] + roi[2], ...]
def test_age_gender_infer(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.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(self):
# NB: Check IE
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
return
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'
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))
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, img)
# 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()
inputs = cv.GInferInputs()
inputs.setInput('data', g_in)
# 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", inputs)
age_g = outputs.at("age_conv3")
gender_g = outputs.at("prob")
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), cv.GOut(age_g, gender_g))
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
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), args=cv.gapi.compile_args(cv.gapi.networks(pp)))
gapi_age, gapi_gender = comp.apply(cv.gin(img, roi), args=cv.compile_args(cv.gapi.networks(pp)))
# Check
# 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,
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.GInferInputs()
inputs.setInput('data', g_in)
outputs = cv.gapi.infer("net", g_rois, 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_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
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'
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)
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, dnn_gender = self.infer_reference_network(model_path,
weights_path,
self.make_roi(img, roi))
# 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_roi = cv.GOpaqueT(cv.gapi.CV_RECT)
inputs = cv.GInferInputs()
inputs.setInput('data', g_in)
# 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.infer("net", g_roi, inputs)
age_g = outputs.at("age_conv3")
gender_g = outputs.at("prob")
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_roi), cv.GOut(age_g, gender_g))
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
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, gapi_gender = comp.apply(cv.gin(img, roi), args=cv.gapi.compile_args(cv.gapi.networks(pp)))
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
args=cv.compile_args(cv.gapi.networks(pp)))
# Check
# 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_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'
def test_person_detection_retail_0013(self):
# NB: Check IE
if not cv.dnn.DNN_TARGET_CPU in cv.dnn.getAvailableTargets(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE):
return
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)
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')])
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')])
device_id = 'CPU'
img = cv.resize(cv.imread(img_path), (544, 320))
# 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 DNN
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
# OpenCV G-API
g_in = cv.GMat()
g_rois = cv.GArrayT(cv.gapi.CV_RECT)
inputs = cv.GInferInputs()
inputs.setInput('data', g_in)
blob = cv.dnn.blobFromImage(img)
outputs = cv.gapi.infer("net", g_rois, inputs)
age_g = outputs.at("age_conv3")
gender_g = outputs.at("prob")
def parseSSD(detections, size):
h, w = size
bboxes = []
detections = detections.reshape(-1, 7)
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
if confidence >= 0.5:
x = int(xmin * w)
y = int(ymin * h)
width = int(xmax * w - x)
height = int(ymax * h - y)
bboxes.append((x, y, width, height))
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)
return bboxes
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
net.setInput(blob)
dnn_detections = net.forward()
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
# 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))
# OpenCV G-API
g_in = cv.GMat()
inputs = cv.GInferInputs()
inputs.setInput('data', g_in)
g_sz = cv.gapi.streaming.size(g_in)
outputs = cv.gapi.infer("net", inputs)
detections = outputs.at("detection_out")
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
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.compile_args(cv.gapi.networks(pp)))
# Comparison
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
np.array(gapi_boxes).flatten(),
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
def test_person_detection_retail_0013(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'
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')])
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')])
device_id = 'CPU'
img = cv.resize(cv.imread(img_path), (544, 320))
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
net = cv.dnn.readNetFromModelOptimizer(model_path, weights_path)
net.setPreferableBackend(cv.dnn.DNN_BACKEND_INFERENCE_ENGINE)
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
# 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)
blob = cv.dnn.blobFromImage(img)
# OpenCV G-API
g_in = cv.GMat()
g_rois = cv.GArrayT(cv.gapi.CV_RECT)
inputs = cv.GInferListInputs()
inputs.setInput('data', g_rois)
def parseSSD(detections, size):
h, w = size
bboxes = []
detections = detections.reshape(-1, 7)
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
if confidence >= 0.5:
x = int(xmin * w)
y = int(ymin * h)
width = int(xmax * w - x)
height = int(ymax * h - y)
bboxes.append((x, y, width, height))
outputs = cv.gapi.infer2("net", g_in, inputs)
age_g = outputs.at("age_conv3")
gender_g = outputs.at("prob")
return bboxes
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)
net.setInput(blob)
dnn_detections = net.forward()
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
gapi_age_list, gapi_gender_list = comp.apply(cv.gin(img, rois),
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
# OpenCV G-API
g_in = cv.GMat()
inputs = cv.GInferInputs()
inputs.setInput('data', g_in)
# 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))
g_sz = cv.gapi.streaming.size(g_in)
outputs = cv.gapi.infer("net", inputs)
detections = outputs.at("detection_out")
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
args=cv.compile_args(cv.gapi.networks(pp)))
def test_person_detection_retail_0013(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/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')])
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')])
device_id = 'CPU'
img = cv.resize(cv.imread(img_path), (544, 320))
# OpenCV DNN
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)
def parseSSD(detections, size):
h, w = size
bboxes = []
detections = detections.reshape(-1, 7)
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
if confidence >= 0.5:
x = int(xmin * w)
y = int(ymin * h)
width = int(xmax * w - x)
height = int(ymax * h - y)
bboxes.append((x, y, width, height))
return bboxes
net.setInput(blob)
dnn_detections = net.forward()
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
# OpenCV G-API
g_in = cv.GMat()
inputs = cv.GInferInputs()
inputs.setInput('data', g_in)
g_sz = cv.gapi.streaming.size(g_in)
outputs = cv.gapi.infer("net", inputs)
detections = outputs.at("detection_out")
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
# Comparison
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):
# 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/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')])
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')])
device_id = 'CPU'
img = cv.resize(cv.imread(img_path), (544, 320))
# OpenCV DNN
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)
def parseSSD(detections, size):
h, w = size
bboxes = []
detections = detections.reshape(-1, 7)
for sample_id, class_id, confidence, xmin, ymin, xmax, ymax in detections:
if confidence >= 0.5:
x = int(xmin * w)
y = int(ymin * h)
width = int(xmax * w - x)
height = int(ymax * h - y)
bboxes.append((x, y, width, height))
return bboxes
net.setInput(blob)
dnn_detections = net.forward()
dnn_boxes = parseSSD(np.array(dnn_detections), img.shape[:2])
# OpenCV G-API
g_in = cv.GMat()
inputs = cv.GInferInputs()
inputs.setInput('data', g_in)
g_sz = cv.gapi.streaming.size(g_in)
outputs = cv.gapi.infer("net", inputs)
detections = outputs.at("detection_out")
bboxes = cv.gapi.parseSSD(detections, g_sz, 0.5, False, False)
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(bboxes))
pp = cv.gapi.ie.params("net", model_path, weights_path, device_id)
gapi_boxes = comp.apply(cv.gin(img.astype(np.float32)),
args=cv.gapi.compile_args(cv.gapi.networks(pp)))
# Comparison
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
np.array(gapi_boxes).flatten(),
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
# Comparison
self.assertEqual(0.0, cv.norm(np.array(dnn_boxes).flatten(),
np.array(gapi_boxes).flatten(),
cv.NORM_INF))
if __name__ == '__main__':
@@ -1,227 +0,0 @@
#!/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))
pkg = cv.gapi.kernels(GAddImpl)
actual = comp.apply(cv.gin(in_mat1, in_mat2), args=cv.gapi.compile_args(pkg))
actual = comp.apply(cv.gin(in_mat1, in_mat2), args=cv.compile_args(pkg))
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))
pkg = cv.gapi.kernels(GSplit3Impl)
ch1, ch2, ch3 = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
ch1, ch2, ch3 = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
self.assertEqual(0.0, cv.norm(in_ch1, ch1, 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)
pkg = cv.gapi.kernels(GMeanImpl)
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
# Comparison
self.assertEqual(expected, actual)
@@ -287,7 +287,7 @@ try:
comp = cv.GComputation(cv.GIn(g_in, g_sc), cv.GOut(g_out))
pkg = cv.gapi.kernels(GAddCImpl)
actual = comp.apply(cv.gin(in_mat, sc), args=cv.gapi.compile_args(pkg))
actual = comp.apply(cv.gin(in_mat, sc), args=cv.compile_args(pkg))
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))
pkg = cv.gapi.kernels(GSizeImpl)
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
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))
pkg = cv.gapi.kernels(GSizeRImpl)
actual = comp.apply(cv.gin(roi), args=cv.gapi.compile_args(pkg))
actual = comp.apply(cv.gin(roi), args=cv.compile_args(pkg))
# cv.norm works with tuples ?
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))
pkg = cv.gapi.kernels(GBoundingRectImpl)
actual = comp.apply(cv.gin(points), args=cv.gapi.compile_args(pkg))
actual = comp.apply(cv.gin(points), args=cv.compile_args(pkg))
# cv.norm works with tuples ?
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))
pkg = cv.gapi.kernels(GGoodFeaturesImpl)
actual = comp.apply(cv.gin(in_mat), args=cv.gapi.compile_args(pkg))
actual = comp.apply(cv.gin(in_mat), args=cv.compile_args(pkg))
# NB: OpenCV & G-API have different output types.
# OpenCV - numpy array with shape (num_points, 1, 2)
@@ -453,10 +453,10 @@ try:
g_in = cv.GArray.Int()
comp = cv.GComputation(cv.GIn(g_in), cv.GOut(GSum.on(g_in)))
s = comp.apply(cv.gin([1, 2, 3, 4]), args=cv.gapi.compile_args(cv.gapi.kernels(GSumImpl)))
s = comp.apply(cv.gin([1, 2, 3, 4]), args=cv.compile_args(cv.gapi.kernels(GSumImpl)))
self.assertEqual(10, s)
s = comp.apply(cv.gin([1, 2, 8, 7]), args=cv.gapi.compile_args(cv.gapi.kernels(GSumImpl)))
s = comp.apply(cv.gin([1, 2, 8, 7]), args=cv.compile_args(cv.gapi.kernels(GSumImpl)))
self.assertEqual(18, s)
self.assertEqual(18, GSumImpl.last_result)
@@ -488,13 +488,13 @@ try:
'tuple': (42, 42)
}
out = comp.apply(cv.gin(table, 'int'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
out = comp.apply(cv.gin(table, 'int'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl)))
self.assertEqual(42, out)
out = comp.apply(cv.gin(table, 'str'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
out = comp.apply(cv.gin(table, 'str'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl)))
self.assertEqual('hello, world!', out)
out = comp.apply(cv.gin(table, 'tuple'), args=cv.gapi.compile_args(cv.gapi.kernels(GLookUpImpl)))
out = comp.apply(cv.gin(table, 'tuple'), args=cv.compile_args(cv.gapi.kernels(GLookUpImpl)))
self.assertEqual((42, 42), out)
@@ -521,7 +521,7 @@ try:
arr1 = [3, 'str']
out = comp.apply(cv.gin(arr0, arr1),
args=cv.gapi.compile_args(cv.gapi.kernels(GConcatImpl)))
args=cv.compile_args(cv.gapi.kernels(GConcatImpl)))
self.assertEqual(arr0 + arr1, out)
@@ -550,7 +550,7 @@ try:
img1 = np.array([1, 2, 3])
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
args=cv.gapi.compile_args(
args=cv.compile_args(
cv.gapi.kernels(GAddImpl)))
@@ -577,7 +577,7 @@ try:
img1 = np.array([1, 2, 3])
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
args=cv.gapi.compile_args(
args=cv.compile_args(
cv.gapi.kernels(GAddImpl)))
@@ -607,7 +607,7 @@ try:
# FIXME: Cause Bad variant access.
# Need to provide more descriptive error messsage.
with self.assertRaises(Exception): comp.apply(cv.gin(img0, img1),
args=cv.gapi.compile_args(
args=cv.compile_args(
cv.gapi.kernels(GAddImpl)))
def test_pipeline_with_custom_kernels(self):
@@ -657,7 +657,7 @@ try:
g_mean = cv.gapi.mean(g_transposed)
comp = cv.GComputation(cv.GIn(g_bgr), cv.GOut(g_mean))
actual = comp.apply(cv.gin(img), args=cv.gapi.compile_args(
actual = comp.apply(cv.gin(img), args=cv.compile_args(
cv.gapi.kernels(GResizeImpl, GTransposeImpl)))
self.assertEqual(0.0, cv.norm(expected, actual, cv.NORM_INF))
@@ -3,323 +3,201 @@
import numpy as np
import cv2 as cv
import os
import sys
import unittest
import time
from tests_common import NewOpenCVTests
class test_gapi_streaming(NewOpenCVTests):
try:
if sys.version_info[:2] < (3, 0):
raise unittest.SkipTest('Python 2.x is not supported')
def test_image_input(self):
sz = (1280, 720)
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
# 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))
@cv.gapi.op('custom.delay', in_types=[cv.GMat], out_types=[cv.GMat])
class GDelay:
"""Delay for 10 ms."""
def test_video_input(self):
ksize = 3
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
@staticmethod
def outMeta(desc):
return desc
# 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(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;
@cv.gapi.kernel(GDelay)
class GDelayImpl:
"""Implementation for GDelay operation."""
def test_video_split3(self):
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
@staticmethod
def run(img):
time.sleep(0.01)
return img
# 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(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;
class test_gapi_streaming(NewOpenCVTests):
def test_video_add(self):
sz = (576, 768, 3)
in_mat = np.random.randint(0, 100, sz).astype(np.uint8)
def test_image_input(self):
sz = (1280, 720)
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
expected = cv.medianBlur(in_mat, 3)
# OpenCV
cap = cv.VideoCapture(path)
# 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.gapi.descr_of(in_mat))
ccomp.setSource(cv.gin(in_mat))
ccomp.start()
# 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))
_, actual = ccomp.pull()
ccomp = c.compileStreaming()
source = cv.gapi.wip.make_capture_src(path)
ccomp.setSource(cv.gin(source, in_mat))
ccomp.start()
# Assert
# 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_input(self):
ksize = 3
path = self.find_file('cv/video/768x576.avi', [os.environ['OPENCV_TEST_DATA_PATH']])
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
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)
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
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;
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
@@ -3,51 +3,29 @@
import numpy as np
import cv2 as cv
import os
import sys
import unittest
from tests_common import NewOpenCVTests
class gapi_types_test(NewOpenCVTests):
try:
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]
if sys.version_info[:2] < (3, 0):
raise unittest.SkipTest('Python 2.x is not supported')
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())
for t in types:
g_array = cv.GArrayT(t)
self.assertEqual(t, g_array.type())
def test_gopaque_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]
def test_gopaque_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]
for t in types:
g_opaque = cv.GOpaqueT(t)
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
for t in types:
g_opaque = cv.GOpaqueT(t)
self.assertEqual(t, g_opaque.type())
if __name__ == '__main__':
+1 -11
View File
@@ -9,14 +9,6 @@
#include <opencv2/gapi/fluid/core.hpp>
#include <opencv2/gapi/fluid/imgproc.hpp>
static void gscalar_example()
{
//! [gscalar_implicit]
cv::GMat a;
cv::GMat b = a + 1;
//! [gscalar_implicit]
}
static void typed_example()
{
const cv::Size sz(32, 32);
@@ -124,9 +116,7 @@ int main(int argc, char *argv[])
>();
//! [kernels_snippet]
// Just call typed example with no input/output - avoid warnings about
// unused functions
// Just call typed example with no input/output
typed_example();
gscalar_example();
return 0;
}
+5 -5
View File
@@ -16,13 +16,13 @@ const std::string keys =
"{ h help | | Print this help message }"
"{ input | | Path to the input video file }"
"{ facem | face-detection-retail-0005.xml | Path to OpenVINO face detection model (.xml) }"
"{ faced | CPU | Target device for the face detection (e.g. CPU, GPU, ...) }"
"{ faced | CPU | Target device for the face detection (e.g. CPU, GPU, VPU, ...) }"
"{ landm | facial-landmarks-35-adas-0002.xml | Path to OpenVINO landmarks detector model (.xml) }"
"{ landd | CPU | Target device for the landmarks detector (e.g. CPU, GPU, ...) }"
"{ landd | CPU | Target device for the landmarks detector (e.g. CPU, GPU, VPU, ...) }"
"{ headm | head-pose-estimation-adas-0001.xml | Path to OpenVINO head pose estimation model (.xml) }"
"{ headd | CPU | Target device for the head pose estimation inference (e.g. CPU, GPU, ...) }"
"{ headd | CPU | Target device for the head pose estimation inference (e.g. CPU, GPU, VPU, ...) }"
"{ gazem | gaze-estimation-adas-0002.xml | Path to OpenVINO gaze vector estimaiton model (.xml) }"
"{ gazed | CPU | Target device for the gaze vector estimation inference (e.g. CPU, GPU, ...) }"
"{ gazed | CPU | Target device for the gaze vector estimation inference (e.g. CPU, GPU, VPU, ...) }"
;
namespace {
@@ -338,7 +338,7 @@ int main(int argc, char *argv[])
cv::GMat in;
cv::GMat faces = cv::gapi::infer<custom::Faces>(in);
cv::GOpaque<cv::Size> sz = cv::gapi::streaming::size(in);
cv::GOpaque<cv::Size> sz = custom::Size::on(in); // FIXME
cv::GArray<cv::Rect> faces_rc = custom::ParseSSD::on(faces, sz, true);
cv::GArray<cv::GMat> angles_y, angles_p, angles_r;
std::tie(angles_y, angles_p, angles_r) = cv::gapi::infer<custom::HeadPose>(faces_rc, in);
-4
View File
@@ -15,10 +15,6 @@ cv::gapi::GNetPackage::GNetPackage(std::initializer_list<GNetParam> ii)
: networks(ii) {
}
cv::gapi::GNetPackage::GNetPackage(std::vector<GNetParam> nets)
: networks(nets) {
}
std::vector<cv::gapi::GBackend> cv::gapi::GNetPackage::backends() const {
std::unordered_set<cv::gapi::GBackend> unique_set;
for (const auto &nn : networks) unique_set.insert(nn.backend);
+3 -3
View File
@@ -159,7 +159,7 @@ void drawPrimitivesOCV(cv::Mat& in,
{
const auto& rp = cv::util::get<Rect>(p);
const auto color = converter.cvtColor(rp.color);
cv::rectangle(in, rp.rect, color, rp.thick, rp.lt, rp.shift);
cv::rectangle(in, rp.rect, color , rp.thick);
break;
}
@@ -198,7 +198,7 @@ void drawPrimitivesOCV(cv::Mat& in,
{
const auto& cp = cv::util::get<Circle>(p);
const auto color = converter.cvtColor(cp.color);
cv::circle(in, cp.center, cp.radius, color, cp.thick, cp.lt, cp.shift);
cv::circle(in, cp.center, cp.radius, color, cp.thick);
break;
}
@@ -206,7 +206,7 @@ void drawPrimitivesOCV(cv::Mat& in,
{
const auto& lp = cv::util::get<Line>(p);
const auto color = converter.cvtColor(lp.color);
cv::line(in, lp.pt1, lp.pt2, color, lp.thick, lp.lt, lp.shift);
cv::line(in, lp.pt1, lp.pt2, color, lp.thick);
break;
}
@@ -85,19 +85,6 @@ class GGraphMetaBackendImpl final: public cv::gapi::GBackend::Priv {
const std::vector<cv::gimpl::Data>&) const override {
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() {
+2 -13
View File
@@ -652,12 +652,7 @@ GAPI_OCV_KERNEL(GCPUParseSSDBL, cv::gapi::nn::parsers::GParseSSDBL)
std::vector<cv::Rect>& out_boxes,
std::vector<int>& out_labels)
{
cv::ParseSSD(in_ssd_result, in_size,
confidence_threshold,
filter_label,
false,
false,
out_boxes, out_labels);
cv::parseSSDBL(in_ssd_result, in_size, confidence_threshold, filter_label, out_boxes, out_labels);
}
};
@@ -670,13 +665,7 @@ GAPI_OCV_KERNEL(GOCVParseSSD, cv::gapi::nn::parsers::GParseSSD)
const bool filter_out_of_bounds,
std::vector<cv::Rect>& 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);
cv::parseSSD(in_ssd_result, in_size, confidence_threshold, alignment_to_square, filter_out_of_bounds, out_boxes);
}
};
+40 -13
View File
@@ -170,14 +170,12 @@ private:
} // namespace nn
} // namespace gapi
void ParseSSD(const cv::Mat& in_ssd_result,
const cv::Size& in_size,
const float confidence_threshold,
const int filter_label,
const bool alignment_to_square,
const bool filter_out_of_bounds,
std::vector<cv::Rect>& out_boxes,
std::vector<int>& out_labels)
void parseSSDBL(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)
{
cv::gapi::nn::SSDParser parser(in_ssd_result.size, in_size, in_ssd_result.ptr<float>());
out_boxes.clear();
@@ -190,6 +188,38 @@ void ParseSSD(const cv::Mat& in_ssd_result,
{
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)
{
break; // marks end-of-detections
@@ -198,14 +228,12 @@ void ParseSSD(const cv::Mat& in_ssd_result,
{
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)
{
parser.adjustBoundingBox(rc);
}
const auto clipped_rc = rc & parser.getSurface();
if (filter_out_of_bounds)
{
@@ -215,7 +243,6 @@ void ParseSSD(const cv::Mat& in_ssd_result,
}
}
out_boxes.emplace_back(clipped_rc);
out_labels.emplace_back(label);
}
}
+9 -4
View File
@@ -11,14 +11,19 @@
namespace cv
{
void ParseSSD(const cv::Mat& in_ssd_result,
void parseSSDBL(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 float confidence_threshold,
const int filter_label,
const bool alignment_to_square,
const bool filter_out_of_bounds,
std::vector<cv::Rect>& out_boxes,
std::vector<int>& out_labels);
std::vector<cv::Rect>& out_boxes);
void parseYolo(const cv::Mat& in_yolo_result,
const cv::Size& in_size,
+2 -38
View File
@@ -222,17 +222,8 @@ struct IEUnit {
IE::ExecutableNetwork this_network;
cv::gimpl::ie::wrap::Plugin this_plugin;
InferenceEngine::RemoteContext::Ptr rctx = nullptr;
explicit IEUnit(const cv::gapi::ie::detail::ParamDesc &pp)
: params(pp) {
InferenceEngine::ParamMap* ctx_params =
cv::util::any_cast<InferenceEngine::ParamMap>(&params.context_config);
if (ctx_params != nullptr) {
auto ie_core = cv::gimpl::ie::wrap::getCore();
rctx = ie_core.CreateContext(params.device_id, *ctx_params);
}
if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Load) {
net = cv::gimpl::ie::wrap::readNetwork(params);
inputs = net.getInputsInfo();
@@ -240,7 +231,7 @@ struct IEUnit {
} else if (params.kind == cv::gapi::ie::detail::ParamDesc::Kind::Import) {
this_plugin = cv::gimpl::ie::wrap::getPlugin(params);
this_plugin.SetConfig(params.config);
this_network = cv::gimpl::ie::wrap::importNetwork(this_plugin, params, rctx);
this_network = cv::gimpl::ie::wrap::importNetwork(this_plugin, params);
// FIXME: ICNNetwork returns InputsDataMap/OutputsDataMap,
// but ExecutableNetwork returns ConstInputsDataMap/ConstOutputsDataMap
inputs = cv::gimpl::ie::wrap::toInputsDataMap(this_network.GetInputsInfo());
@@ -288,8 +279,7 @@ struct IEUnit {
// for loadNetwork they can be obtained by using readNetwork
non_const_this->this_plugin = cv::gimpl::ie::wrap::getPlugin(params);
non_const_this->this_plugin.SetConfig(params.config);
non_const_this->this_network = cv::gimpl::ie::wrap::loadNetwork(non_const_this->this_plugin,
net, params, rctx);
non_const_this->this_network = cv::gimpl::ie::wrap::loadNetwork(non_const_this->this_plugin, net, params);
}
return {params, this_plugin, this_network};
@@ -491,32 +481,7 @@ using GConstGIEModel = ade::ConstTypedGraph
, IECallable
>;
inline IE::Blob::Ptr extractRemoteBlob(IECallContext& ctx, std::size_t i) {
GAPI_Assert(ctx.inShape(i) == cv::GShape::GFRAME &&
"Remote blob is supported for MediaFrame only");
cv::util::any any_blob_params = ctx.inFrame(i).blobParams();
auto ie_core = cv::gimpl::ie::wrap::getCore();
using ParamType = std::pair<InferenceEngine::TensorDesc,
InferenceEngine::ParamMap>;
ParamType* blob_params = cv::util::any_cast<ParamType>(&any_blob_params);
if (blob_params == nullptr) {
GAPI_Assert(false && "Incorrect type of blobParams: "
"expected std::pair<InferenceEngine::TensorDesc,"
"InferenceEngine::ParamMap>");
}
return ctx.uu.rctx->CreateBlob(blob_params->first,
blob_params->second);
}
inline IE::Blob::Ptr extractBlob(IECallContext& ctx, std::size_t i) {
if (ctx.uu.rctx != nullptr) {
return extractRemoteBlob(ctx, i);
}
switch (ctx.inShape(i)) {
case cv::GShape::GFRAME: {
const auto& frame = ctx.inFrame(i);
@@ -1095,7 +1060,6 @@ struct InferList: public cv::detail::KernelTag {
}
IE::Blob::Ptr this_blob = extractBlob(*ctx, 1);
std::vector<std::vector<int>> cached_dims(ctx->uu.params.num_out);
for (auto i : ade::util::iota(ctx->uu.params.num_out)) {
const IE::DataPtr& ie_out = ctx->uu.outputs.at(ctx->uu.params.output_names[i]);
@@ -124,11 +124,7 @@ IE::Core giewrap::getPlugin(const GIEParam& params) {
{
try
{
#if INF_ENGINE_RELEASE >= 2021040000
plugin.AddExtension(std::make_shared<IE::Extension>(extlib), params.device_id);
#else
plugin.AddExtension(IE::make_so_pointer<IE::IExtension>(extlib), params.device_id);
#endif
CV_LOG_INFO(NULL, "DNN-IE: Loaded extension plugin: " << extlib);
break;
}
@@ -13,7 +13,6 @@
#include <vector>
#include <string>
#include <fstream>
#include "opencv2/gapi/infer/ie.hpp"
@@ -51,29 +50,12 @@ GAPI_EXPORTS IE::Core getCore();
GAPI_EXPORTS IE::Core getPlugin(const GIEParam& params);
GAPI_EXPORTS inline IE::ExecutableNetwork loadNetwork( IE::Core& core,
const IE::CNNNetwork& net,
const GIEParam& params,
IE::RemoteContext::Ptr rctx = nullptr) {
if (rctx != nullptr) {
return core.LoadNetwork(net, rctx);
} else {
return core.LoadNetwork(net, params.device_id);
}
const GIEParam& params) {
return core.LoadNetwork(net, params.device_id);
}
GAPI_EXPORTS inline IE::ExecutableNetwork importNetwork( IE::Core& core,
const GIEParam& params,
IE::RemoteContext::Ptr rctx = nullptr) {
if (rctx != nullptr) {
std::filebuf blobFile;
if (!blobFile.open(params.model_path, std::ios::in | std::ios::binary))
{
blobFile.close();
throw std::runtime_error("Could not open file");
}
std::istream graphBlob(&blobFile);
return core.ImportNetwork(graphBlob, rctx);
} else {
return core.ImportNetwork(params.model_path, params.device_id, {});
}
const GIEParam& param) {
return core.ImportNetwork(param.model_path, param.device_id, {});
}
#endif // INF_ENGINE_RELEASE < 2019020000
}}}}
+11 -7
View File
@@ -75,11 +75,6 @@ bool cv::GStreamingCompiled::Priv::pull(cv::GOptRunArgsP &&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)
{
return m_exec->try_pull(std::move(outs));
@@ -128,9 +123,18 @@ bool cv::GStreamingCompiled::pull(cv::GRunArgsP &&outs)
return m_priv->pull(std::move(outs));
}
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> cv::GStreamingCompiled::pull()
std::tuple<bool, cv::GRunArgs> cv::GStreamingCompiled::pull()
{
return m_priv->pull();
GRunArgs run_args;
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)
@@ -46,7 +46,6 @@ public:
void start();
bool pull(cv::GRunArgsP &&outs);
bool pull(cv::GOptRunArgsP &&outs);
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> pull();
bool try_pull(cv::GRunArgsP &&outs);
void stop();
@@ -1017,49 +1017,6 @@ void check_DesyncObjectConsumedByMultipleIslands(const cv::gimpl::GIslandModel::
} // 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
class cv::gimpl::GStreamingExecutor::Synchronizer final {
@@ -1363,16 +1320,6 @@ cv::gimpl::GStreamingExecutor::GStreamingExecutor(std::unique_ptr<ade::Graph> &&
// per the same input frame, so the output traffic multiplies)
GAPI_Assert(m_collector_map.size() > 0u);
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()
@@ -1706,31 +1653,6 @@ bool cv::gimpl::GStreamingExecutor::pull(cv::GOptRunArgsP &&outs)
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)
{
@@ -195,8 +195,6 @@ protected:
void wait_shutdown();
cv::GTypesInfo out_info;
public:
explicit GStreamingExecutor(std::unique_ptr<ade::Graph> &&g_model,
const cv::GCompileArgs &comp_args);
@@ -205,7 +203,6 @@ public:
void start();
bool pull(cv::GRunArgsP &&outs);
bool pull(cv::GOptRunArgsP &&outs);
std::tuple<bool, cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>> pull();
bool try_pull(cv::GRunArgsP &&outs);
void stop();
bool running() const;
@@ -639,8 +639,8 @@ INSTANTIATE_TEST_CASE_P(RenderBGROCVTestRectsImpl, RenderBGROCVTestRects,
Values(cv::Rect(100, 100, 200, 200)),
Values(cv::Scalar(100, 50, 150)),
Values(2),
Values(LINE_8, LINE_4),
Values(0, 1)));
Values(LINE_8),
Values(0)));
INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestRectsImpl, RenderNV12OCVTestRects,
Combine(Values(cv::Size(1280, 720)),
@@ -673,8 +673,8 @@ INSTANTIATE_TEST_CASE_P(RenderNV12OCVTestCirclesImpl, RenderNV12OCVTestCircles,
Values(10),
Values(cv::Scalar(100, 50, 150)),
Values(2),
Values(LINE_8, LINE_4),
Values(0, 1)));
Values(LINE_8),
Values(0)));
INSTANTIATE_TEST_CASE_P(RenderMFrameOCVTestCirclesImpl, RenderMFrameOCVTestCircles,
Combine(Values(cv::Size(1280, 720)),
@@ -244,35 +244,6 @@ 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
TEST_P(GAPI_Streaming, SmokeTest_ConstInput_GMat)
@@ -1365,45 +1336,13 @@ TEST(Streaming, Python_Pull_Overload)
bool has_output;
cv::GRunArgs outputs;
using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
RunArgs args;
std::tie(has_output, outputs) = ccomp.pull();
std::tie(has_output, args) = ccomp.pull();
EXPECT_TRUE(has_output);
EXPECT_EQ(1u, outputs.size());
checkPullOverload(in_mat, has_output, args);
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);
auto out_mat = cv::util::get<cv::Mat>(outputs[0]);
EXPECT_EQ(0., cv::norm(in_mat, out_mat, cv::NORM_INF));
ccomp.stop();
EXPECT_FALSE(ccomp.running());
@@ -2193,17 +2132,9 @@ TEST(GAPI_Streaming, TestPythonAPI)
bool is_over = false;
cv::GRunArgs out_args;
using RunArgs = cv::util::variant<cv::GRunArgs, cv::GOptRunArgs>;
RunArgs args;
// NB: Used by python bridge
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");
}
std::tie(is_over, out_args) = cc.pull();
ASSERT_EQ(1u, out_args.size());
ASSERT_TRUE(cv::util::holds_alternative<cv::Mat>(out_args[0]));
+6 -10
View File
@@ -131,6 +131,12 @@ elseif(WINRT)
message(STATUS " ${name}: Removing 'comctl32.lib, gdi32.lib, ole32.lib, setupapi.lib'")
message(STATUS " ${name}: Leaving '${HIGHGUI_LIBRARIES}'")
endif()
elseif(HAVE_WIN32UI)
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "WIN32UI")
list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_w32.cpp)
if(OpenCV_ARCH STREQUAL "ARM64")
list(APPEND HIGHGUI_LIBRARIES "comdlg32" "advapi32")
endif()
elseif(HAVE_COCOA)
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "COCOA")
add_definitions(-DHAVE_COCOA)
@@ -138,16 +144,6 @@ elseif(HAVE_COCOA)
list(APPEND HIGHGUI_LIBRARIES "-framework Cocoa")
endif()
if(TARGET ocv.3rdparty.win32ui)
if("win32ui" IN_LIST HIGHGUI_PLUGIN_LIST OR HIGHGUI_PLUGIN_LIST STREQUAL "all")
ocv_create_builtin_highgui_plugin(opencv_highgui_win32 ocv.3rdparty.win32ui "window_w32.cpp")
elseif(NOT OPENCV_HIGHGUI_BUILTIN_BACKEND)
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "WIN32UI")
list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_w32.cpp)
list(APPEND tgts ocv.3rdparty.win32ui)
endif()
endif()
if(TARGET ocv.3rdparty.gtk3 OR TARGET ocv.3rdparty.gtk2)
if(TARGET ocv.3rdparty.gtk3 AND NOT WITH_GTK_2_X)
set(__gtk_dependency "ocv.3rdparty.gtk3")
@@ -1,17 +0,0 @@
#--- Win32 UI ---
ocv_clear_vars(HAVE_WIN32UI)
if(WITH_WIN32UI)
try_compile(HAVE_WIN32UI
"${CMAKE_CURRENT_BINARY_DIR}"
"${OpenCV_SOURCE_DIR}/cmake/checks/win32uitest.cpp"
CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32")
if(HAVE_WIN32UI)
set(__libs "user32" "gdi32")
if(OpenCV_ARCH STREQUAL "ARM64")
list(APPEND __libs "comdlg32" "advapi32")
endif()
ocv_add_external_target(win32ui "" "${__libs}" "HAVE_WIN32UI")
endif()
endif()
set(HAVE_WIN32UI "${HAVE_WIN32UI}" PARENT_SCOPE) # informational

Some files were not shown because too many files have changed in this diff Show More