mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ad6e82942b | |||
| d60bb57d4b | |||
| f9d62fba7a | |||
| 85dde8a800 | |||
| 9d039c206b | |||
| cbff19ff1a | |||
| 4c3f9b2ef4 | |||
| 167bac23aa | |||
| 5d0cfa2527 | |||
| 0e523618a1 | |||
| 821fae0d94 | |||
| 3b26105f68 | |||
| 0f2f966a91 | |||
| d7d491d445 | |||
| 41effbe2da | |||
| 9b0d6862c4 | |||
| 890fcdf842 | |||
| 18dbac203f | |||
| 8d1f254dcc | |||
| e5841d3126 | |||
| 90df3af6cf | |||
| 11cc36d770 | |||
| 05f1939b02 | |||
| 050ea9762f | |||
| 0f24d4d2a1 | |||
| fc799191f4 | |||
| 8fad85edda | |||
| d70053aba5 | |||
| b699fe7a9d | |||
| 94c67faaea | |||
| b2ed5c3070 | |||
| 9fe49497bb | |||
| 5b8c10f2f8 | |||
| 24983f62e2 | |||
| f2057ce1ab | |||
| 6797fd65a5 | |||
| bf489feef1 | |||
| 947e06a860 | |||
| 6a3d925a47 | |||
| 04d5ba266f | |||
| 90be83ae99 | |||
| 5e80bd3cc9 | |||
| fb7ef76e74 | |||
| db4b1e613c | |||
| ee39081b11 | |||
| 7d842f5bcf | |||
| 4eac198270 | |||
| faac32418c | |||
| 42810621df | |||
| 61a5378aeb | |||
| 42d644ef91 | |||
| c95a56450d | |||
| dc5199feea | |||
| f88fdf6a1b | |||
| b68057d927 | |||
| e9a860d9cb | |||
| 8be86cbdfd | |||
| 5091e64a42 | |||
| 828304d587 | |||
| 9d584475f6 | |||
| bb60cb0bf9 | |||
| 25f908b320 | |||
| 9b7dca2fa1 | |||
| 55e1dfb778 | |||
| 735a79ae83 | |||
| ef2b400c61 | |||
| c2263db7bc | |||
| 53eca2ff5b | |||
| 7bbbda71df | |||
| 9557b9f70f | |||
| 464441d8c3 | |||
| f30f1afd47 | |||
| b3db37b99d | |||
| 7a276f39fb | |||
| 415668ecf0 | |||
| 651967b95c | |||
| 8e0baf257c | |||
| c8268e65fd | |||
| 3cf4375387 | |||
| 438e2dc228 | |||
| c1adbe3189 | |||
| 7ee1816612 | |||
| b4084491e5 | |||
| 8f4f834ce6 | |||
| 411fd2b761 |
@@ -1,6 +1,6 @@
|
||||
/*************************************************
|
||||
USAGE:
|
||||
./model_diagnostics -m <onnx file location>
|
||||
./model_diagnostics -m <model 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 .onnx file. }"
|
||||
"{ model m | | Path to the model 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 model"
|
||||
argParser.about("Use this tool to run the diagnostics of provided ONNX/TF model"
|
||||
"to obtain the information about its support (supported layers).");
|
||||
|
||||
if (argc == 1)
|
||||
|
||||
@@ -179,7 +179,13 @@ if(CV_GCC OR CV_CLANG)
|
||||
endif()
|
||||
|
||||
# We need pthread's
|
||||
if(UNIX AND NOT ANDROID AND NOT (APPLE AND CV_CLANG)) # TODO
|
||||
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
|
||||
)
|
||||
add_extra_compiler_option(-pthread)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -9,9 +9,14 @@ 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)
|
||||
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)
|
||||
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()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -28,18 +33,15 @@ 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}" CACHE PATH "Halide include directories" FORCE)
|
||||
set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}" CACHE PATH "Halide libraries" FORCE)
|
||||
set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}")
|
||||
set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}")
|
||||
set(HAVE_HALIDE TRUE)
|
||||
endif()
|
||||
if(NOT HAVE_HALIDE)
|
||||
ocv_clear_vars(HALIDE_LIBRARIES HALIDE_INCLUDE_DIRS CACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_HALIDE)
|
||||
include_directories(${HALIDE_INCLUDE_DIRS})
|
||||
if(HALIDE_INCLUDE_DIRS)
|
||||
include_directories(${HALIDE_INCLUDE_DIRS})
|
||||
endif()
|
||||
list(APPEND OPENCV_LINKER_LIBS ${HALIDE_LIBRARIES})
|
||||
else()
|
||||
ocv_clear_vars(HALIDE_INCLUDE_DIRS HALIDE_LIBRARIES)
|
||||
endif()
|
||||
|
||||
@@ -134,16 +134,21 @@ endif()
|
||||
# Add more features to the target
|
||||
|
||||
if(INF_ENGINE_TARGET)
|
||||
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")
|
||||
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()
|
||||
endif()
|
||||
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")
|
||||
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}")
|
||||
endif()
|
||||
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(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_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()
|
||||
|
||||
|
||||
@@ -2,15 +2,6 @@
|
||||
# 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)
|
||||
|
||||
@@ -78,17 +78,10 @@ function(ocv_create_plugin module default_name dependency_target dependency_targ
|
||||
set_target_properties(${OPENCV_PLUGIN_NAME} PROPERTIES PREFIX "${OPENCV_PLUGIN_MODULE_PREFIX}")
|
||||
endif()
|
||||
|
||||
if(WIN32 OR NOT APPLE)
|
||||
set(OPENCV_PLUGIN_NO_LINK FALSE CACHE BOOL "")
|
||||
else()
|
||||
set(OPENCV_PLUGIN_NO_LINK TRUE CACHE BOOL "")
|
||||
endif()
|
||||
|
||||
if(OPENCV_PLUGIN_NO_LINK)
|
||||
if(APPLE)
|
||||
set_target_properties(${OPENCV_PLUGIN_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
||||
endif()
|
||||
else()
|
||||
if(APPLE)
|
||||
set_target_properties(${OPENCV_PLUGIN_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
||||
elseif(WIN32)
|
||||
# Hack for Windows only, Linux/MacOS uses global symbol table (without exact .so binding)
|
||||
find_package(OpenCV REQUIRED ${module} ${OPENCV_PLUGIN_DEPS})
|
||||
target_link_libraries(${OPENCV_PLUGIN_NAME} PRIVATE ${OpenCV_LIBRARIES})
|
||||
endif()
|
||||
|
||||
@@ -121,9 +121,6 @@
|
||||
/* 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
@@ -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*
|
||||
EXCLUDE_SYMBOLS = cv::DataType<*> cv::traits::* int void CV__* T __CV* cv::gapi::detail*
|
||||
EXAMPLE_PATH = @CMAKE_DOXYGEN_EXAMPLE_PATH@
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = YES
|
||||
|
||||
@@ -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 = 0;
|
||||
meta.setTo(cv::Scalar::all(0));
|
||||
for(int row =0;row < meta.rows-1;++row)
|
||||
{
|
||||
for(int col=0;col< meta.cols-1;++col)
|
||||
|
||||
@@ -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*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);
|
||||
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];
|
||||
@@ -1807,4 +1807,78 @@ 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
|
||||
|
||||
@@ -2451,7 +2451,8 @@ 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);
|
||||
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
|
||||
|
||||
//! returns deep copy of the matrix, i.e. the data is copied
|
||||
UMat clone() const CV_NODISCARD;
|
||||
@@ -2485,14 +2486,22 @@ public:
|
||||
double dot(InputArray m) const;
|
||||
|
||||
//! Matlab-style matrix initialization
|
||||
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);
|
||||
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
|
||||
|
||||
//! allocates new matrix data unless the matrix already has specified size and type.
|
||||
// previous data is unreferenced if needed.
|
||||
|
||||
@@ -144,6 +144,10 @@ 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());
|
||||
@@ -191,6 +195,9 @@ 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_OSX) && !TARGET_OS_IPHONE)
|
||||
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX only
|
||||
# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (defined(TARGET_OS_IOS) && TARGET_OS_IOS)
|
||||
# define OPENCV_HAVE_FILESYSTEM_SUPPORT 1 // OSX, iOS 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 "-openvino"
|
||||
#define CV_VERSION_STATUS ""
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||
|
||||
@@ -3,6 +3,16 @@ 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:
|
||||
*
|
||||
@@ -19,6 +29,7 @@ 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")
|
||||
}
|
||||
|
||||
@@ -30,6 +41,7 @@ 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")
|
||||
}
|
||||
|
||||
@@ -38,46 +50,95 @@ 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 = ByteArray(1)
|
||||
mat[indices, data]
|
||||
return data[0].toUByte()
|
||||
val data = UByteArray(1)
|
||||
mat.get(indices, data)
|
||||
return data[0]
|
||||
}
|
||||
|
||||
override fun setV(v: UByte) {
|
||||
val data = byteArrayOf(v.toByte())
|
||||
val data = ubyteArrayOf(v)
|
||||
mat.put(indices, data)
|
||||
}
|
||||
|
||||
override fun getV2c(): Tuple2<UByte> {
|
||||
val data = ByteArray(2)
|
||||
mat[indices, data]
|
||||
return Tuple2(data[0].toUByte(), data[1].toUByte())
|
||||
val data = UByteArray(2)
|
||||
mat.get(indices, data)
|
||||
return Tuple2(data[0], data[1])
|
||||
}
|
||||
|
||||
override fun setV2c(v: Tuple2<UByte>) {
|
||||
val data = byteArrayOf(v._0.toByte(), v._1.toByte())
|
||||
val data = ubyteArrayOf(v._0, v._1)
|
||||
mat.put(indices, data)
|
||||
}
|
||||
|
||||
override fun getV3c(): Tuple3<UByte> {
|
||||
val data = ByteArray(3)
|
||||
mat[indices, data]
|
||||
return Tuple3(data[0].toUByte(), data[1].toUByte(), data[2].toUByte())
|
||||
val data = UByteArray(3)
|
||||
mat.get(indices, data)
|
||||
return Tuple3(data[0], data[1], data[2])
|
||||
}
|
||||
|
||||
override fun setV3c(v: Tuple3<UByte>) {
|
||||
val data = byteArrayOf(v._0.toByte(), v._1.toByte(), v._2.toByte())
|
||||
val data = ubyteArrayOf(v._0, v._1, v._2)
|
||||
mat.put(indices, data)
|
||||
}
|
||||
|
||||
override fun getV4c(): Tuple4<UByte> {
|
||||
val data = ByteArray(4)
|
||||
mat[indices, data]
|
||||
return Tuple4(data[0].toUByte(), data[1].toUByte(), data[2].toUByte(), data[3].toUByte())
|
||||
val data = UByteArray(4)
|
||||
mat.get(indices, data)
|
||||
return Tuple4(data[0], data[1], data[2], data[3])
|
||||
}
|
||||
|
||||
override fun setV4c(v: Tuple4<UByte>) {
|
||||
val data = byteArrayOf(v._0.toByte(), v._1.toByte(), v._2.toByte(), v._3.toByte())
|
||||
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)
|
||||
mat.put(indices, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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, ^char (int index) { return cv::saturate_cast<char>(data[offset + index].doubleValue);} );
|
||||
putData(dest, count, ^schar (int index) { return cv::saturate_cast<schar>(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) {
|
||||
|
||||
@@ -62,6 +62,21 @@ 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 {
|
||||
@@ -114,10 +129,29 @@ 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)
|
||||
}
|
||||
@@ -134,6 +168,10 @@ 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 {
|
||||
@@ -147,6 +185,21 @@ 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 {
|
||||
@@ -214,10 +267,29 @@ 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)
|
||||
}
|
||||
@@ -238,6 +310,10 @@ 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])
|
||||
}
|
||||
@@ -303,46 +379,46 @@ public class MatAt<N: Atable> {
|
||||
|
||||
extension UInt8: Atable {
|
||||
public static func getAt(m: Mat, indices:[Int32]) -> UInt8 {
|
||||
var tmp = [Int8](repeating: 0, count: 1)
|
||||
var tmp = [UInt8](repeating: 0, count: 1)
|
||||
try! m.get(indices: indices, data: &tmp)
|
||||
return UInt8(bitPattern: tmp[0])
|
||||
return tmp[0]
|
||||
}
|
||||
|
||||
public static func putAt(m: Mat, indices: [Int32], v: UInt8) {
|
||||
let tmp = [Int8(bitPattern: v)]
|
||||
let tmp = [v]
|
||||
try! m.put(indices: indices, data: tmp)
|
||||
}
|
||||
|
||||
public static func getAt2c(m: Mat, indices:[Int32]) -> (UInt8, UInt8) {
|
||||
var tmp = [Int8](repeating: 0, count: 2)
|
||||
var tmp = [UInt8](repeating: 0, count: 2)
|
||||
try! m.get(indices: indices, data: &tmp)
|
||||
return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]))
|
||||
return (tmp[0], tmp[1])
|
||||
}
|
||||
|
||||
public static func putAt2c(m: Mat, indices: [Int32], v: (UInt8, UInt8)) {
|
||||
let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1)]
|
||||
let tmp = [v.0, v.1]
|
||||
try! m.put(indices: indices, data: tmp)
|
||||
}
|
||||
|
||||
public static func getAt3c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8) {
|
||||
var tmp = [Int8](repeating: 0, count: 3)
|
||||
var tmp = [UInt8](repeating: 0, count: 3)
|
||||
try! m.get(indices: indices, data: &tmp)
|
||||
return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]), UInt8(bitPattern: tmp[2]))
|
||||
return (tmp[0], tmp[1], tmp[2])
|
||||
}
|
||||
|
||||
public static func putAt3c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8)) {
|
||||
let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1), Int8(bitPattern: v.2)]
|
||||
let tmp = [v.0, v.1, v.2]
|
||||
try! m.put(indices: indices, data: tmp)
|
||||
}
|
||||
|
||||
public static func getAt4c(m: Mat, indices:[Int32]) -> (UInt8, UInt8, UInt8, UInt8) {
|
||||
var tmp = [Int8](repeating: 0, count: 4)
|
||||
var tmp = [UInt8](repeating: 0, count: 4)
|
||||
try! m.get(indices: indices, data: &tmp)
|
||||
return (UInt8(bitPattern: tmp[0]), UInt8(bitPattern: tmp[1]), UInt8(bitPattern: tmp[2]), UInt8(bitPattern: tmp[3]))
|
||||
return (tmp[0], tmp[1], tmp[2], tmp[3])
|
||||
}
|
||||
|
||||
public static func putAt4c(m: Mat, indices: [Int32], v: (UInt8, UInt8, UInt8, UInt8)) {
|
||||
let tmp = [Int8(bitPattern: v.0), Int8(bitPattern: v.1), Int8(bitPattern: v.2), Int8(bitPattern: v.3)]
|
||||
let tmp = [v.0, v.1, v.2, v.3]
|
||||
try! m.put(indices: indices, data: tmp)
|
||||
}
|
||||
}
|
||||
@@ -531,6 +607,52 @@ 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)
|
||||
|
||||
@@ -308,15 +308,15 @@ class MatTests: OpenCVTestCase {
|
||||
XCTAssert([340] == sm.get(row: 1, col: 1))
|
||||
}
|
||||
|
||||
func testGetIntIntByteArray() throws {
|
||||
let m = try getTestMat(size: 5, type: CvType.CV_8UC3)
|
||||
func testGetIntIntInt8Array() throws {
|
||||
let m = try getTestMat(size: 5, type: CvType.CV_8SC3)
|
||||
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, -126, -125, -124] == goodData)
|
||||
XCTAssert([110, 111, 112, 120, 121, 122, 127, 127, 127] == goodData)
|
||||
|
||||
var badData = [Int8](repeating: 0, count: 7)
|
||||
XCTAssertThrowsError(bytesNum = try m.get(row: 0, col: 0, data: &badData))
|
||||
@@ -326,11 +326,36 @@ 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 == [-26, -25, -24])
|
||||
XCTAssert(buff00 == [127, 127, 127])
|
||||
var buff11 = [Int8](repeating: 0, count: 3)
|
||||
bytesNum = try sm.get(row: 1, col: 1, data: &buff11)
|
||||
XCTAssertEqual(3, bytesNum)
|
||||
XCTAssert(buff11 == [-1, -1, -1])
|
||||
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])
|
||||
}
|
||||
|
||||
func testGetIntIntDoubleArray() throws {
|
||||
@@ -399,7 +424,7 @@ class MatTests: OpenCVTestCase {
|
||||
XCTAssert(buff11 == [340, 341, 0, 0])
|
||||
}
|
||||
|
||||
func testGetIntIntShortArray() throws {
|
||||
func testGetIntIntInt16Array() throws {
|
||||
let m = try getTestMat(size: 5, type: CvType.CV_16SC2)
|
||||
var buff = [Int16](repeating: 0, count: 6)
|
||||
|
||||
@@ -421,6 +446,28 @@ 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())
|
||||
@@ -653,7 +700,7 @@ class MatTests: OpenCVTestCase {
|
||||
try assertMatEqual(truth!, m1, OpenCVTestCase.EPS)
|
||||
}
|
||||
|
||||
func testPutIntIntByteArray() throws {
|
||||
func testPutIntIntInt8Array() 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)
|
||||
@@ -683,7 +730,37 @@ class MatTests: OpenCVTestCase {
|
||||
XCTAssert(buff == buff0)
|
||||
}
|
||||
|
||||
func testPutIntArrayByteArray() throws {
|
||||
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 {
|
||||
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)
|
||||
@@ -714,10 +791,41 @@ 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_8SC3, scalar: Scalar(1, 2, 3))
|
||||
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 = [Int8](repeating: 0, count: 6)
|
||||
var buff = [UInt8](repeating: 0, count: 6)
|
||||
|
||||
var bytesNum = try m.put(row: 1, col: 2, data: [10, 20, 30, 40, 50, 60] as [Double])
|
||||
|
||||
@@ -731,16 +839,16 @@ class MatTests: OpenCVTestCase {
|
||||
XCTAssertEqual(6, bytesNum)
|
||||
bytesNum = try sm.get(row: 0, col: 0, data: &buff)
|
||||
XCTAssertEqual(6, bytesNum);
|
||||
XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
|
||||
XCTAssert(buff == [255, 254, 253, 252, 251, 250])
|
||||
bytesNum = try m.get(row: 2, col: 3, data: &buff)
|
||||
XCTAssertEqual(6, bytesNum);
|
||||
XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
|
||||
XCTAssert(buff == [255, 254, 253, 252, 251, 250])
|
||||
}
|
||||
|
||||
func testPutIntArrayDoubleArray() throws {
|
||||
let m = Mat(sizes: [5, 5, 5], type: CvType.CV_8SC3, scalar: Scalar(1, 2, 3))
|
||||
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 = [Int8](repeating: 0, count: 6)
|
||||
var buff = [UInt8](repeating: 0, count: 6)
|
||||
|
||||
var bytesNum = try m.put(indices: [1, 2, 0], data: [10, 20, 30, 40, 50, 60] as [Double])
|
||||
|
||||
@@ -754,10 +862,10 @@ class MatTests: OpenCVTestCase {
|
||||
XCTAssertEqual(6, bytesNum);
|
||||
bytesNum = try sm.get(indices: [0, 0, 0], data: &buff)
|
||||
XCTAssertEqual(6, bytesNum);
|
||||
XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
|
||||
XCTAssert(buff == [255, 254, 253, 252, 251, 250])
|
||||
bytesNum = try m.get(indices: [0, 1, 2], data: &buff)
|
||||
XCTAssertEqual(6, bytesNum)
|
||||
XCTAssert(buff == [-1, -2, -3, -4, -5, -6])
|
||||
XCTAssert(buff == [255, 254, 253, 252, 251, 250])
|
||||
}
|
||||
|
||||
func testPutIntIntFloatArray() throws {
|
||||
@@ -820,7 +928,7 @@ class MatTests: OpenCVTestCase {
|
||||
XCTAssert([40, 50, 60] == m.get(indices: [0, 1, 0]))
|
||||
}
|
||||
|
||||
func testPutIntIntShortArray() throws {
|
||||
func testPutIntIntInt16Array() 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]
|
||||
|
||||
@@ -834,7 +942,21 @@ class MatTests: OpenCVTestCase {
|
||||
XCTAssert([40, 50, 60] == m.get(row: 2, col: 4))
|
||||
}
|
||||
|
||||
func testPutIntArrayShortArray() throws {
|
||||
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 {
|
||||
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]
|
||||
|
||||
@@ -848,6 +970,20 @@ 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)
|
||||
|
||||
@@ -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:
|
||||
case DXGI_FORMAT_R16G16B16A16_FLOAT: return CV_16FC4;
|
||||
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:
|
||||
//case DXGI_FORMAT_R32G32_UINT:
|
||||
//case DXGI_FORMAT_R32G32_SINT:
|
||||
case DXGI_FORMAT_R32G32_FLOAT: return CV_32FC2;
|
||||
case DXGI_FORMAT_R32G32_UINT:
|
||||
case DXGI_FORMAT_R32G32_SINT: return CV_32SC2;
|
||||
//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:
|
||||
case DXGI_FORMAT_R16G16_FLOAT: return CV_16FC2;
|
||||
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:
|
||||
case DXGI_FORMAT_R16_FLOAT: return CV_16FC1;
|
||||
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:
|
||||
case DXGI_FORMAT_R8G8_B8G8_UNORM:
|
||||
case DXGI_FORMAT_G8R8_G8B8_UNORM: return CV_8UC4;
|
||||
//case DXGI_FORMAT_BC1_TYPELESS:
|
||||
//case DXGI_FORMAT_BC1_UNORM:
|
||||
//case DXGI_FORMAT_BC1_UNORM_SRGB:
|
||||
|
||||
@@ -229,14 +229,14 @@ void cv::setIdentity( InputOutputArray _m, const Scalar& s )
|
||||
|
||||
namespace cv {
|
||||
|
||||
UMat UMat::eye(int rows, int cols, int type)
|
||||
UMat UMat::eye(int rows, int cols, int type, UMatUsageFlags usageFlags)
|
||||
{
|
||||
return UMat::eye(Size(cols, rows), type);
|
||||
return UMat::eye(Size(cols, rows), type, usageFlags);
|
||||
}
|
||||
|
||||
UMat UMat::eye(Size size, int type)
|
||||
UMat UMat::eye(Size size, int type, UMatUsageFlags usageFlags)
|
||||
{
|
||||
UMat m(size, type);
|
||||
UMat m(size, type, usageFlags);
|
||||
setIdentity(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
+35
-10
@@ -1566,6 +1566,7 @@ 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);
|
||||
@@ -1678,6 +1679,7 @@ struct Device::Impl
|
||||
String version_;
|
||||
std::string extensions_;
|
||||
int doubleFPConfig_;
|
||||
int halfFPConfig_;
|
||||
bool hostUnifiedMemory_;
|
||||
int maxComputeUnits_;
|
||||
size_t maxWorkGroupSize_;
|
||||
@@ -1827,11 +1829,7 @@ int Device::singleFPConfig() const
|
||||
{ return p ? p->getProp<cl_device_fp_config, int>(CL_DEVICE_SINGLE_FP_CONFIG) : 0; }
|
||||
|
||||
int Device::halfFPConfig() const
|
||||
#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
|
||||
{ return p ? p->halfFPConfig_ : 0; }
|
||||
|
||||
bool Device::endianLittle() const
|
||||
{ return p ? p->getBoolProp(CL_DEVICE_ENDIAN_LITTLE) : false; }
|
||||
@@ -6668,6 +6666,10 @@ 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");
|
||||
}
|
||||
@@ -6676,9 +6678,23 @@ 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:
|
||||
@@ -7068,6 +7084,13 @@ 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)
|
||||
@@ -7091,7 +7114,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>, 0 };
|
||||
kerToStr<int>, kerToStr<float>, kerToStr<double>, kerToStr<float16_t> };
|
||||
const func_t func = funcs[ddepth];
|
||||
CV_Assert(func != 0);
|
||||
|
||||
@@ -7130,14 +7153,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(), -1 };
|
||||
d.preferredVectorWidthDouble(), d.preferredVectorWidthHalf() };
|
||||
|
||||
// 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] = 2;
|
||||
vectorWidths[CV_16U] = vectorWidths[CV_16S] = vectorWidths[CV_16F] = 2;
|
||||
vectorWidths[CV_32S] = vectorWidths[CV_32F] = vectorWidths[CV_64F] = 1;
|
||||
}
|
||||
|
||||
@@ -7225,10 +7248,12 @@ 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, -1 };
|
||||
CL_SIGNED_INT16, CL_SIGNED_INT32, CL_FLOAT, -1, CL_HALF_FLOAT };
|
||||
static const int channelTypesNorm[] = { CL_UNORM_INT8, CL_SNORM_INT8, CL_UNORM_INT16,
|
||||
CL_SNORM_INT16, -1, -1, -1, -1 };
|
||||
static const int channelOrders[] = { -1, CL_R, CL_RG, -1, CL_RGBA };
|
||||
// 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 };
|
||||
|
||||
int channelType = norm ? channelTypesNorm[depth] : channelTypes[depth];
|
||||
int channelOrder = channelOrders[cn];
|
||||
|
||||
@@ -143,17 +143,17 @@ static const char symbols[9] = "ucwsifdh";
|
||||
static char typeSymbol(int depth)
|
||||
{
|
||||
CV_StaticAssert(CV_64F == 6, "");
|
||||
CV_Assert(depth >=0 && depth <= CV_64F);
|
||||
CV_CheckDepth(depth, depth >=0 && depth <= CV_16F, "");
|
||||
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,8 +245,12 @@ 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++ ) {
|
||||
switch ( *type )
|
||||
for ( const char * type = dt; *type != '\0'; type++ )
|
||||
{
|
||||
char v = *type;
|
||||
if (v >= '0' && v <= '9')
|
||||
continue; // skip vector size
|
||||
switch (v)
|
||||
{
|
||||
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; }
|
||||
@@ -255,7 +259,9 @@ 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; }
|
||||
default: 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));
|
||||
}
|
||||
}
|
||||
size = cvAlign( size, static_cast<int>(elem_max_size) );
|
||||
@@ -1054,6 +1060,7 @@ public:
|
||||
CV_Assert(write_mode);
|
||||
|
||||
size_t elemSize = fs::calcStructSize(dt.c_str(), 0);
|
||||
CV_Assert(elemSize);
|
||||
CV_Assert( len % elemSize == 0 );
|
||||
len /= elemSize;
|
||||
|
||||
|
||||
@@ -1835,7 +1835,15 @@ void* TLSDataContainer::getData() const
|
||||
{
|
||||
// Create new data instance and save it to TLS storage
|
||||
pData = createDataInstance();
|
||||
getTlsStorage().setData(key_, pData);
|
||||
try
|
||||
{
|
||||
getTlsStorage().setData(key_, pData);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
deleteDataInstance(pData);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return pData;
|
||||
}
|
||||
|
||||
@@ -951,11 +951,11 @@ UMat UMat::reshape(int new_cn, int new_rows) const
|
||||
return hdr;
|
||||
}
|
||||
|
||||
UMat UMat::diag(const UMat& d)
|
||||
UMat UMat::diag(const UMat& d, UMatUsageFlags usageFlags)
|
||||
{
|
||||
CV_Assert( d.cols == 1 || d.rows == 1 );
|
||||
int len = d.rows + d.cols - 1;
|
||||
UMat m(len, len, d.type(), Scalar(0));
|
||||
UMat m(len, len, d.type(), Scalar(0), usageFlags);
|
||||
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)
|
||||
UMat UMat::zeros(int rows, int cols, int type, UMatUsageFlags usageFlags)
|
||||
{
|
||||
return UMat(rows, cols, type, Scalar::all(0));
|
||||
return UMat(rows, cols, type, Scalar::all(0), usageFlags);
|
||||
}
|
||||
|
||||
UMat UMat::zeros(Size size, int type)
|
||||
UMat UMat::zeros(Size size, int type, UMatUsageFlags usageFlags)
|
||||
{
|
||||
return UMat(size, type, Scalar::all(0));
|
||||
return UMat(size, type, Scalar::all(0), usageFlags);
|
||||
}
|
||||
|
||||
UMat UMat::zeros(int ndims, const int* sz, int type)
|
||||
UMat UMat::zeros(int ndims, const int* sz, int type, UMatUsageFlags usageFlags)
|
||||
{
|
||||
return UMat(ndims, sz, type, Scalar::all(0));
|
||||
return UMat(ndims, sz, type, Scalar::all(0), usageFlags);
|
||||
}
|
||||
|
||||
UMat UMat::ones(int rows, int cols, int type)
|
||||
UMat UMat::ones(int rows, int cols, int type, UMatUsageFlags usageFlags)
|
||||
{
|
||||
return UMat::ones(Size(cols, rows), type);
|
||||
return UMat(rows, cols, type, Scalar(1), usageFlags);
|
||||
}
|
||||
|
||||
UMat UMat::ones(Size size, int type)
|
||||
UMat UMat::ones(Size size, int type, UMatUsageFlags usageFlags)
|
||||
{
|
||||
return UMat(size, type, Scalar(1));
|
||||
return UMat(size, type, Scalar(1), usageFlags);
|
||||
}
|
||||
|
||||
UMat UMat::ones(int ndims, const int* sz, int type)
|
||||
UMat UMat::ones(int ndims, const int* sz, int type, UMatUsageFlags usageFlags)
|
||||
{
|
||||
return UMat(ndims, sz, type, Scalar(1));
|
||||
return UMat(ndims, sz, type, Scalar(1), usageFlags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -76,6 +76,24 @@ 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));
|
||||
|
||||
@@ -1837,4 +1837,69 @@ 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
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
]
|
||||
|
||||
],
|
||||
"jni_name": "(*(cv::dnn::DictValue*)%(n)s_nativeObj)",
|
||||
"jni_name": "(*(*(Ptr<cv::dnn::DictValue>*)%(n)s_nativeObj))",
|
||||
"jni_type": "jlong",
|
||||
"suffix": "J",
|
||||
"j_import": "org.opencv.dnn.DictValue"
|
||||
|
||||
@@ -657,7 +657,11 @@ 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);
|
||||
@@ -1005,35 +1009,54 @@ 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;
|
||||
infRequestPtr->SetUserData(reqWrapper.get(), 0);
|
||||
CV_Assert(infRequestPtr);
|
||||
InferenceEngine::IInferRequest& infRequest = *infRequestPtr.get();
|
||||
infRequest.SetUserData(reqWrapper.get(), 0);
|
||||
#endif
|
||||
|
||||
infRequestPtr->SetCompletionCallback(
|
||||
[](InferenceEngine::IInferRequest::Ptr request, InferenceEngine::StatusCode status)
|
||||
#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
|
||||
{
|
||||
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* wrapper;
|
||||
request->GetUserData((void**)&wrapper, 0);
|
||||
CV_Assert(wrapper && "Internal error");
|
||||
NgraphReqWrapper* wrapperPtr;
|
||||
request.GetUserData((void**)&wrapperPtr, 0);
|
||||
CV_Assert(wrapperPtr && "Internal error");
|
||||
#endif
|
||||
NgraphReqWrapper& wrapper = *wrapperPtr;
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -1043,16 +1066,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;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ 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;
|
||||
@@ -88,11 +89,11 @@ public:
|
||||
const float* weightsData = hasWeights ? blobs[weightsBlobIndex].ptr<float>() : 0;
|
||||
const float* biasData = hasBias ? blobs[biasBlobIndex].ptr<float>() : 0;
|
||||
|
||||
weights_.create(1, (int)n, CV_32F);
|
||||
bias_.create(1, (int)n, CV_32F);
|
||||
origin_weights.create(1, (int)n, CV_32F);
|
||||
origin_bias.create(1, (int)n, CV_32F);
|
||||
|
||||
float* dstWeightsData = weights_.ptr<float>();
|
||||
float* dstBiasData = bias_.ptr<float>();
|
||||
float* dstWeightsData = origin_weights.ptr<float>();
|
||||
float* dstBiasData = origin_bias.ptr<float>();
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
@@ -100,15 +101,12 @@ 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
|
||||
{
|
||||
blobs[0].reshape(1, 1).copyTo(weights_);
|
||||
blobs[1].reshape(1, 1).copyTo(bias_);
|
||||
origin_weights.reshape(1, 1).copyTo(weights_);
|
||||
origin_bias.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::NormalizeL2>(ieInpNode, axes, epsilon, ngraph::op::EpsMode::ADD);
|
||||
auto norm = std::make_shared<ngraph::op::v0::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);
|
||||
|
||||
@@ -1954,6 +1954,23 @@ 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")
|
||||
{
|
||||
|
||||
@@ -30,10 +30,11 @@
|
||||
#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.3 by default")
|
||||
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2021_3
|
||||
#warning("IE version have not been provided via command-line. Using 2021.4 by default")
|
||||
#define INF_ENGINE_RELEASE INF_ENGINE_RELEASE_2021_4
|
||||
#endif
|
||||
|
||||
#define INF_ENGINE_VER_MAJOR_GT(ver) (((INF_ENGINE_RELEASE) / 10000) > ((ver) / 10000))
|
||||
|
||||
+1866
-1610
File diff suppressed because it is too large
Load Diff
@@ -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.252 : FLT_MIN;
|
||||
float detectionConfThresh = (target == DNN_TARGET_MYRIAD) ? 0.262 : 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.0056 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.072 : 0.0;
|
||||
const float l1 = (target == DNN_TARGET_MYRIAD) ? 0.009 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD) ? 0.09 : 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.012 : 0.0;
|
||||
const float lInf = (target == DNN_TARGET_MYRIAD || target == DNN_TARGET_OPENCL_FP16) ? 0.16 : 0.0;
|
||||
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;
|
||||
processNet("dnn/openpose_pose_mpi.caffemodel", "dnn/openpose_pose_mpi.prototxt",
|
||||
Size(46, 46), "", "", l1, lInf);
|
||||
expectNoFallbacksFromIE(net);
|
||||
|
||||
@@ -307,6 +307,15 @@ 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)
|
||||
{
|
||||
|
||||
@@ -349,6 +349,7 @@ 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)
|
||||
|
||||
@@ -290,9 +290,14 @@ 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)
|
||||
#if defined(INF_ENGINE_RELEASE) && ( \
|
||||
INF_ENGINE_VER_MAJOR_EQ(2021030000) || \
|
||||
INF_ENGINE_VER_MAJOR_EQ(2021040000) \
|
||||
)
|
||||
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_MYRIAD)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH); // crash
|
||||
// 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);
|
||||
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,6 +1337,13 @@ 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,
|
||||
|
||||
@@ -183,7 +183,8 @@ 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 KeyPoint& kp1, const KeyPoint& kp2, const Scalar& matchColor, DrawMatchesFlags flags,
|
||||
const int matchesThickness )
|
||||
{
|
||||
RNG& rng = theRNG();
|
||||
bool isRandMatchColor = matchColor == Scalar::all(-1);
|
||||
@@ -199,7 +200,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, 1, LINE_AA, draw_shift_bits );
|
||||
color, matchesThickness, LINE_AA, draw_shift_bits );
|
||||
}
|
||||
|
||||
void drawMatches( InputArray img1, const std::vector<KeyPoint>& keypoints1,
|
||||
@@ -207,6 +208,21 @@ 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" );
|
||||
@@ -226,11 +242,12 @@ 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 );
|
||||
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags, matchesThickness );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
@@ -254,7 +271,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 );
|
||||
_drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,31 +450,184 @@ 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;
|
||||
|
||||
for( int c = SIFT_IMG_BORDER; c < cols-SIFT_IMG_BORDER; c++)
|
||||
#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++)
|
||||
{
|
||||
sift_wt val = currptr[c];
|
||||
if (std::abs(val) <= threshold)
|
||||
continue;
|
||||
|
||||
// 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])))
|
||||
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)
|
||||
{
|
||||
CV_TRACE_REGION("pixel_candidate");
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
*/
|
||||
|
||||
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,6 +40,10 @@ namespace gimpl
|
||||
|
||||
namespace gapi
|
||||
{
|
||||
/**
|
||||
* @brief This namespace contains G-API CPU backend functions,
|
||||
* structures, and symbols.
|
||||
*/
|
||||
namespace cpu
|
||||
{
|
||||
/**
|
||||
@@ -492,7 +496,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,6 +25,9 @@ namespace cv {
|
||||
|
||||
namespace gapi
|
||||
{
|
||||
/**
|
||||
* @brief This namespace contains G-API Fluid backend functions, structures, and symbols.
|
||||
*/
|
||||
namespace fluid
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -340,21 +340,79 @@ 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(); }
|
||||
GArray() { putDetails(); } // Empty constructor
|
||||
explicit GArray(detail::GArrayU &&ref) // GArrayU-based constructor
|
||||
: m_ref(ref) { putDetails(); } // (used by GCall, not for users)
|
||||
|
||||
/**
|
||||
* @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)
|
||||
|
||||
/// @private
|
||||
detail::GArrayU strip() const {
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
|
||||
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 {
|
||||
|
||||
/**
|
||||
|
||||
@@ -437,7 +437,11 @@ public:
|
||||
*
|
||||
* @sa @ref gapi_compile_args
|
||||
*/
|
||||
GAPI_WRAP GStreamingCompiled compileStreaming(GMetaArgs &&in_metas, GCompileArgs &&args = {});
|
||||
GStreamingCompiled compileStreaming(GMetaArgs &&in_metas, GCompileArgs &&args = {});
|
||||
|
||||
/// @private -- Exclude this function from OpenCV documentation
|
||||
GAPI_WRAP GStreamingCompiled compileStreaming(const cv::detail::ExtractMetaCallback &callback,
|
||||
GCompileArgs &&args = {});
|
||||
|
||||
/**
|
||||
* @brief Compile the computation for streaming mode.
|
||||
@@ -460,10 +464,6 @@ public:
|
||||
*/
|
||||
GAPI_WRAP GStreamingCompiled compileStreaming(GCompileArgs &&args = {});
|
||||
|
||||
/// @private -- Exclude this function from OpenCV documentation
|
||||
GAPI_WRAP GStreamingCompiled compileStreaming(const cv::detail::ExtractMetaCallback &callback,
|
||||
GCompileArgs &&args = {});
|
||||
|
||||
// 2. Direct metadata version
|
||||
/**
|
||||
* @overload
|
||||
|
||||
@@ -28,14 +28,54 @@ 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:
|
||||
GAPI_WRAP GFrame(); // Empty constructor
|
||||
GFrame(const GNode &n, std::size_t out); // Operation result constructor
|
||||
/**
|
||||
* @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
|
||||
|
||||
GOrigin& priv(); // Internal use only
|
||||
const GOrigin& priv() const; // Internal use only
|
||||
/// @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
|
||||
|
||||
private:
|
||||
std::shared_ptr<GOrigin> m_priv;
|
||||
|
||||
@@ -372,6 +372,7 @@ 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:
|
||||
@@ -412,6 +413,7 @@ namespace std
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
/// @private
|
||||
class GFunctor
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -30,29 +30,57 @@ 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) and are used to construct
|
||||
* graphs.
|
||||
* associated values like with cv::GScalar or `cv::GArray<T>`) and are
|
||||
* used only 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.
|
||||
* G-API and regular data types when passing input and output data
|
||||
* structures to G-API:
|
||||
*
|
||||
* G-API data type | I/O data type
|
||||
* ------------------ | -------------
|
||||
* cv::GMat | cv::Mat
|
||||
* cv::GMat | cv::Mat, cv::UMat, cv::RMat
|
||||
* 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
|
||||
GMat(const GNode &n, std::size_t out); // Operation result 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:
|
||||
|
||||
@@ -307,15 +307,40 @@ 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)
|
||||
|
||||
|
||||
@@ -25,18 +25,83 @@ 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:
|
||||
GAPI_WRAP GScalar(); // Empty constructor
|
||||
explicit GScalar(const cv::Scalar& s); // Constant value constructor from cv::Scalar
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
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
|
||||
GScalar(const GNode &n, std::size_t out); // Operation result constructor
|
||||
|
||||
/// @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:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// Copyright (C) 2018 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_GSTREAMING_COMPILED_HPP
|
||||
@@ -65,7 +65,6 @@ using OptionalOpaqueRef = OptRef<cv::detail::OpaqueRef>;
|
||||
using GOptRunArgP = util::variant<
|
||||
optional<cv::Mat>*,
|
||||
optional<cv::RMat>*,
|
||||
optional<cv::MediaFrame>*,
|
||||
optional<cv::Scalar>*,
|
||||
cv::detail::OptionalVectorRef,
|
||||
cv::detail::OptionalOpaqueRef
|
||||
@@ -75,7 +74,6 @@ using GOptRunArgsP = std::vector<GOptRunArgP>;
|
||||
using GOptRunArg = util::variant<
|
||||
optional<cv::Mat>,
|
||||
optional<cv::RMat>,
|
||||
optional<cv::MediaFrame>,
|
||||
optional<cv::Scalar>,
|
||||
optional<cv::detail::VectorRef>,
|
||||
optional<cv::detail::OpaqueRef>
|
||||
@@ -97,14 +95,6 @@ template<> inline GOptRunArgP wrap_opt_arg(optional<cv::Mat> &m) {
|
||||
return GOptRunArgP{&m};
|
||||
}
|
||||
|
||||
template<> inline GOptRunArgP wrap_opt_arg(optional<cv::RMat> &m) {
|
||||
return GOptRunArgP{&m};
|
||||
}
|
||||
|
||||
template<> inline GOptRunArgP wrap_opt_arg(optional<cv::MediaFrame> &f) {
|
||||
return GOptRunArgP{&f};
|
||||
}
|
||||
|
||||
template<> inline GOptRunArgP wrap_opt_arg(optional<cv::Scalar> &s) {
|
||||
return GOptRunArgP{&s};
|
||||
}
|
||||
@@ -391,6 +381,14 @@ 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.
|
||||
@@ -398,11 +396,9 @@ namespace streaming {
|
||||
* In the streaming mode the pipeline steps are connected with queues
|
||||
* and this compile argument controls every queue's size.
|
||||
*/
|
||||
struct GAPI_EXPORTS_W_SIMPLE queue_capacity
|
||||
struct GAPI_EXPORTS queue_capacity
|
||||
{
|
||||
GAPI_WRAP
|
||||
explicit queue_capacity(size_t cap = 1) : capacity(cap) { };
|
||||
GAPI_PROP_RW
|
||||
size_t capacity;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
@@ -47,6 +47,10 @@ 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?
|
||||
|
||||
@@ -666,7 +666,7 @@ 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
|
||||
*/
|
||||
|
||||
@@ -22,28 +22,17 @@ namespace ie {
|
||||
// This class can be marked as SIMPLE, because it's implemented as pimpl
|
||||
class GAPI_EXPORTS_W_SIMPLE PyParams {
|
||||
public:
|
||||
GAPI_WRAP
|
||||
PyParams() = default;
|
||||
|
||||
GAPI_WRAP
|
||||
PyParams(const std::string &tag,
|
||||
const std::string &model,
|
||||
const std::string &weights,
|
||||
const std::string &device);
|
||||
|
||||
GAPI_WRAP
|
||||
PyParams(const std::string &tag,
|
||||
const std::string &model,
|
||||
const std::string &device);
|
||||
|
||||
GAPI_WRAP
|
||||
PyParams& constInput(const std::string &layer_name,
|
||||
const cv::Mat &data,
|
||||
TraitAs hint = TraitAs::TENSOR);
|
||||
|
||||
GAPI_WRAP
|
||||
PyParams& cfgNumRequests(size_t nireq);
|
||||
|
||||
GBackend backend() const;
|
||||
std::string tag() const;
|
||||
cv::util::any params() const;
|
||||
|
||||
@@ -24,6 +24,11 @@
|
||||
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();
|
||||
@@ -69,7 +74,11 @@ 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
|
||||
|
||||
@@ -110,7 +119,8 @@ public:
|
||||
, {}
|
||||
, {}
|
||||
, {}
|
||||
, 1u} {
|
||||
, 1u
|
||||
, {}} {
|
||||
};
|
||||
|
||||
/** @overload
|
||||
@@ -130,7 +140,8 @@ public:
|
||||
, {}
|
||||
, {}
|
||||
, {}
|
||||
, 1u} {
|
||||
, 1u
|
||||
, {}} {
|
||||
};
|
||||
|
||||
/** @brief Specifies sequence of network input layers names for inference.
|
||||
@@ -212,6 +223,30 @@ 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.
|
||||
@@ -313,7 +348,10 @@ 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
|
||||
@@ -328,7 +366,10 @@ 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,6 +20,10 @@
|
||||
|
||||
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();
|
||||
|
||||
@@ -17,28 +17,107 @@
|
||||
|
||||
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:
|
||||
enum class Access { R, W };
|
||||
/// 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
|
||||
};
|
||||
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&&...);
|
||||
|
||||
View access(Access) const;
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
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;
|
||||
|
||||
// Cast underlying MediaFrame adapter to the particular adapter type,
|
||||
// return nullptr if underlying type is different
|
||||
template<typename T> T* get() 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 {
|
||||
static_assert(std::is_base_of<IAdapter, T>::value,
|
||||
"T is not derived from cv::MediaFrame::IAdapter!");
|
||||
auto* adapter = getAdapter();
|
||||
@@ -58,6 +137,43 @@ 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;
|
||||
@@ -65,19 +181,38 @@ 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;
|
||||
Strides stride;
|
||||
Ptrs ptr; ///< Array of image plane pointers
|
||||
Strides stride; ///< Array of image plane strides, in bytes.
|
||||
|
||||
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;
|
||||
@@ -87,6 +222,7 @@ public:
|
||||
// The default implementation does nothing
|
||||
virtual cv::util::any blobParams() const;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
} //namespace cv
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@ namespace gimpl
|
||||
|
||||
namespace gapi
|
||||
{
|
||||
/**
|
||||
* @brief This namespace contains G-API OpenCL backend functions, structures, and symbols.
|
||||
*/
|
||||
namespace ocl
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,11 @@ namespace cv
|
||||
{
|
||||
namespace gapi
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief This namespace contains G-API own data structures used in
|
||||
* its standalone mode build.
|
||||
*/
|
||||
namespace own
|
||||
{
|
||||
|
||||
|
||||
@@ -15,6 +15,11 @@ namespace cv
|
||||
{
|
||||
namespace gapi
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief This namespace contains G-API PlaidML backend functions,
|
||||
* structures, and symbols.
|
||||
*/
|
||||
namespace plaidml
|
||||
{
|
||||
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
|
||||
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();
|
||||
|
||||
@@ -169,6 +169,10 @@ 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
|
||||
|
||||
@@ -42,6 +42,9 @@ 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:
|
||||
@@ -146,6 +149,7 @@ private:
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
RMat make_rmat(Ts&&... args) { return { std::make_shared<T>(std::forward<Ts>(args)...) }; }
|
||||
/** @} */
|
||||
|
||||
} //namespace cv
|
||||
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
|
||||
namespace cv {
|
||||
namespace gapi {
|
||||
|
||||
/**
|
||||
* @brief This namespace contains G-API serialization and
|
||||
* deserialization functions and data structures.
|
||||
*/
|
||||
namespace s11n {
|
||||
struct IOStream;
|
||||
struct IIStream;
|
||||
|
||||
@@ -38,6 +38,11 @@ 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") {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2020-2021 Intel Corporation
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
|
||||
|
||||
#ifndef OPENCV_GAPI_GSTREAMING_DESYNC_HPP
|
||||
@@ -73,10 +73,9 @@ G desync(const G &g) {
|
||||
* which produces an array of cv::util::optional<> objects.
|
||||
*
|
||||
* @note This feature is highly experimental now and is currently
|
||||
* limited to a single GMat/GFrame argument only.
|
||||
* limited to a single GMat argument only.
|
||||
*/
|
||||
GAPI_EXPORTS GMat desync(const GMat &g);
|
||||
GAPI_EXPORTS GFrame desync(const GFrame &f);
|
||||
|
||||
} // namespace streaming
|
||||
} // namespace gapi
|
||||
|
||||
@@ -42,6 +42,10 @@ 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>;
|
||||
|
||||
@@ -295,5 +295,3 @@ cv.gapi.wip.draw.Line = cv.gapi_wip_draw_Line
|
||||
cv.gapi.wip.draw.Mosaic = cv.gapi_wip_draw_Mosaic
|
||||
cv.gapi.wip.draw.Image = cv.gapi_wip_draw_Image
|
||||
cv.gapi.wip.draw.Poly = cv.gapi_wip_draw_Poly
|
||||
|
||||
cv.gapi.streaming.queue_capacity = cv.gapi_streaming_queue_capacity
|
||||
|
||||
@@ -11,14 +11,13 @@
|
||||
#include <opencv2/gapi/python/python.hpp>
|
||||
|
||||
// NB: Python wrapper replaces :: with _ for classes
|
||||
using gapi_GKernelPackage = cv::gapi::GKernelPackage;
|
||||
using gapi_GNetPackage = cv::gapi::GNetPackage;
|
||||
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>;
|
||||
using gapi_streaming_queue_capacity = cv::gapi::streaming::queue_capacity;
|
||||
using gapi_GKernelPackage = cv::gapi::GKernelPackage;
|
||||
using gapi_GNetPackage = cv::gapi::GNetPackage;
|
||||
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
|
||||
@@ -160,7 +159,7 @@ PyObject* pyopencv_from(const cv::gapi::wip::draw::Prims& value)
|
||||
}
|
||||
|
||||
template<>
|
||||
bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prim& value, const ArgInfo&)
|
||||
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))) \
|
||||
@@ -176,7 +175,6 @@ bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prim& value, const ArgInfo&
|
||||
TRY_EXTRACT(Mosaic)
|
||||
TRY_EXTRACT(Image)
|
||||
TRY_EXTRACT(Poly)
|
||||
#undef TRY_EXTRACT
|
||||
|
||||
failmsg("Unsupported primitive type");
|
||||
return false;
|
||||
@@ -188,34 +186,6 @@ bool pyopencv_to(PyObject* obj, cv::gapi::wip::draw::Prims& value, const ArgInfo
|
||||
return pyopencv_to_generic_vec(obj, value, info);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool pyopencv_to(PyObject* obj, cv::GMetaArg& value, const ArgInfo&)
|
||||
{
|
||||
#define TRY_EXTRACT(Meta) \
|
||||
if (PyObject_TypeCheck(obj, \
|
||||
reinterpret_cast<PyTypeObject*>(pyopencv_##Meta##_TypePtr))) \
|
||||
{ \
|
||||
value = reinterpret_cast<pyopencv_##Meta##_t*>(obj)->v; \
|
||||
return true; \
|
||||
} \
|
||||
|
||||
TRY_EXTRACT(GMatDesc)
|
||||
TRY_EXTRACT(GScalarDesc)
|
||||
TRY_EXTRACT(GArrayDesc)
|
||||
TRY_EXTRACT(GOpaqueDesc)
|
||||
#undef TRY_EXTRACT
|
||||
|
||||
failmsg("Unsupported cv::GMetaArg type");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool pyopencv_to(PyObject* obj, cv::GMetaArgs& value, const ArgInfo& info)
|
||||
{
|
||||
return pyopencv_to_generic_vec(obj, value, info);
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
PyObject* pyopencv_from(const cv::GArg& value)
|
||||
{
|
||||
@@ -737,12 +707,30 @@ static cv::GRunArgs run_py_kernel(cv::detail::PyObjectHolder kernel,
|
||||
|
||||
static GMetaArg get_meta_arg(PyObject* obj)
|
||||
{
|
||||
cv::GMetaArg arg;
|
||||
if (!pyopencv_to(obj, arg, ArgInfo("arg", false)))
|
||||
if (PyObject_TypeCheck(obj,
|
||||
reinterpret_cast<PyTypeObject*>(pyopencv_GMatDesc_TypePtr)))
|
||||
{
|
||||
return cv::GMetaArg{reinterpret_cast<pyopencv_GMatDesc_t*>(obj)->v};
|
||||
}
|
||||
else if (PyObject_TypeCheck(obj,
|
||||
reinterpret_cast<PyTypeObject*>(pyopencv_GScalarDesc_TypePtr)))
|
||||
{
|
||||
return cv::GMetaArg{reinterpret_cast<pyopencv_GScalarDesc_t*>(obj)->v};
|
||||
}
|
||||
else if (PyObject_TypeCheck(obj,
|
||||
reinterpret_cast<PyTypeObject*>(pyopencv_GArrayDesc_TypePtr)))
|
||||
{
|
||||
return cv::GMetaArg{reinterpret_cast<pyopencv_GArrayDesc_t*>(obj)->v};
|
||||
}
|
||||
else if (PyObject_TypeCheck(obj,
|
||||
reinterpret_cast<PyTypeObject*>(pyopencv_GOpaqueDesc_TypePtr)))
|
||||
{
|
||||
return cv::GMetaArg{reinterpret_cast<pyopencv_GOpaqueDesc_t*>(obj)->v};
|
||||
}
|
||||
else
|
||||
{
|
||||
util::throw_error(std::logic_error("Unsupported output meta type"));
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
static cv::GMetaArgs get_meta_args(PyObject* tuple)
|
||||
|
||||
@@ -0,0 +1,467 @@
|
||||
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))
|
||||
@@ -5,9 +5,8 @@ namespace cv
|
||||
{
|
||||
struct GAPI_EXPORTS_W_SIMPLE GCompileArg
|
||||
{
|
||||
GAPI_WRAP GCompileArg(gapi::GKernelPackage arg);
|
||||
GAPI_WRAP GCompileArg(gapi::GNetPackage arg);
|
||||
GAPI_WRAP GCompileArg(gapi::streaming::queue_capacity arg);
|
||||
GAPI_WRAP GCompileArg(gapi::GKernelPackage pkg);
|
||||
GAPI_WRAP GCompileArg(gapi::GNetPackage pkg);
|
||||
};
|
||||
|
||||
class GAPI_EXPORTS_W_SIMPLE GInferInputs
|
||||
|
||||
@@ -261,7 +261,6 @@ try:
|
||||
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']])
|
||||
|
||||
@@ -308,49 +307,6 @@ try:
|
||||
self.assertLess(0, none_counter)
|
||||
|
||||
|
||||
def test_compile_streaming_empty(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
comp.compileStreaming()
|
||||
|
||||
|
||||
def test_compile_streaming_args(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
comp.compileStreaming(cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||
|
||||
|
||||
def test_compile_streaming_descr_of(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
img = np.zeros((3,300,300), dtype=np.float32)
|
||||
comp.compileStreaming(cv.gapi.descr_of(img))
|
||||
|
||||
|
||||
def test_compile_streaming_descr_of_and_args(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
img = np.zeros((3,300,300), dtype=np.float32)
|
||||
comp.compileStreaming(cv.gapi.descr_of(img),
|
||||
cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||
|
||||
|
||||
def test_compile_streaming_meta(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
img = np.zeros((3,300,300), dtype=np.float32)
|
||||
comp.compileStreaming([cv.GMatDesc(cv.CV_8U, 3, (300, 300))])
|
||||
|
||||
|
||||
def test_compile_streaming_meta_and_args(self):
|
||||
g_in = cv.GMat()
|
||||
comp = cv.GComputation(g_in, cv.gapi.medianBlur(g_in, 3))
|
||||
img = np.zeros((3,300,300), dtype=np.float32)
|
||||
comp.compileStreaming([cv.GMatDesc(cv.CV_8U, 3, (300, 300))],
|
||||
cv.gapi.compile_args(cv.gapi.streaming.queue_capacity(1)))
|
||||
|
||||
|
||||
|
||||
except unittest.SkipTest as e:
|
||||
|
||||
message = str(e)
|
||||
|
||||
@@ -9,6 +9,14 @@
|
||||
#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);
|
||||
@@ -116,7 +124,9 @@ int main(int argc, char *argv[])
|
||||
>();
|
||||
//! [kernels_snippet]
|
||||
|
||||
// Just call typed example with no input/output
|
||||
// Just call typed example with no input/output - avoid warnings about
|
||||
// unused functions
|
||||
typed_example();
|
||||
gscalar_example();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -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, VPU, ...) }"
|
||||
"{ faced | CPU | Target device for the face detection (e.g. CPU, GPU, ...) }"
|
||||
"{ 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, VPU, ...) }"
|
||||
"{ landd | CPU | Target device for the landmarks detector (e.g. CPU, GPU, ...) }"
|
||||
"{ 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, VPU, ...) }"
|
||||
"{ headd | CPU | Target device for the head pose estimation inference (e.g. CPU, GPU, ...) }"
|
||||
"{ 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, VPU, ...) }"
|
||||
"{ gazed | CPU | Target device for the gaze vector estimation inference (e.g. CPU, GPU, ...) }"
|
||||
;
|
||||
|
||||
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 = custom::Size::on(in); // FIXME
|
||||
cv::GOpaque<cv::Size> sz = cv::gapi::streaming::size(in);
|
||||
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);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2020-2021 Intel Corporation
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
@@ -75,11 +75,6 @@ cv::GMat cv::gapi::streaming::desync(const cv::GMat &g) {
|
||||
// object will feed both branches of the streaming executable.
|
||||
}
|
||||
|
||||
// All notes from the above desync(GMat) are also applicable here
|
||||
cv::GFrame cv::gapi::streaming::desync(const cv::GFrame &f) {
|
||||
return cv::gapi::copy(detail::desync(f));
|
||||
}
|
||||
|
||||
cv::GMat cv::gapi::streaming::BGR(const cv::GFrame& in) {
|
||||
return cv::gapi::streaming::GBGR::on(in);
|
||||
}
|
||||
|
||||
@@ -37,15 +37,3 @@ cv::gapi::ie::PyParams cv::gapi::ie::params(const std::string &tag,
|
||||
const std::string &device) {
|
||||
return {tag, model, device};
|
||||
}
|
||||
|
||||
cv::gapi::ie::PyParams& cv::gapi::ie::PyParams::constInput(const std::string &layer_name,
|
||||
const cv::Mat &data,
|
||||
TraitAs hint) {
|
||||
m_priv->constInput(layer_name, data, hint);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cv::gapi::ie::PyParams& cv::gapi::ie::PyParams::cfgNumRequests(size_t nireq) {
|
||||
m_priv->cfgNumRequests(nireq);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -222,8 +222,17 @@ 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>(¶ms.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();
|
||||
@@ -231,7 +240,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);
|
||||
this_network = cv::gimpl::ie::wrap::importNetwork(this_plugin, params, rctx);
|
||||
// FIXME: ICNNetwork returns InputsDataMap/OutputsDataMap,
|
||||
// but ExecutableNetwork returns ConstInputsDataMap/ConstOutputsDataMap
|
||||
inputs = cv::gimpl::ie::wrap::toInputsDataMap(this_network.GetInputsInfo());
|
||||
@@ -279,7 +288,8 @@ 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);
|
||||
non_const_this->this_network = cv::gimpl::ie::wrap::loadNetwork(non_const_this->this_plugin,
|
||||
net, params, rctx);
|
||||
}
|
||||
|
||||
return {params, this_plugin, this_network};
|
||||
@@ -481,7 +491,32 @@ 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);
|
||||
@@ -1060,6 +1095,7 @@ 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,7 +124,11 @@ 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,6 +13,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
#include "opencv2/gapi/infer/ie.hpp"
|
||||
|
||||
@@ -50,12 +51,29 @@ 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) {
|
||||
return core.LoadNetwork(net, params.device_id);
|
||||
const GIEParam& params,
|
||||
IE::RemoteContext::Ptr rctx = nullptr) {
|
||||
if (rctx != nullptr) {
|
||||
return core.LoadNetwork(net, rctx);
|
||||
} else {
|
||||
return core.LoadNetwork(net, params.device_id);
|
||||
}
|
||||
}
|
||||
GAPI_EXPORTS inline IE::ExecutableNetwork importNetwork( IE::Core& core,
|
||||
const GIEParam& param) {
|
||||
return core.ImportNetwork(param.model_path, param.device_id, {});
|
||||
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, {});
|
||||
}
|
||||
}
|
||||
#endif // INF_ENGINE_RELEASE < 2019020000
|
||||
}}}}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <ade/util/zip_range.hpp>
|
||||
|
||||
#include <opencv2/gapi/opencv_includes.hpp>
|
||||
@@ -155,14 +157,10 @@ void writeBackExec(const Mag& mag, const RcDesc &rc, GRunArgP &g_arg)
|
||||
// FIXME:
|
||||
// Rework, find a better way to check if there should be
|
||||
// a real copy (add a pass to StreamingBackend?)
|
||||
// NB: In case RMat adapter not equal to "RMatAdapter" need to
|
||||
// copy data back to the host as well.
|
||||
// FIXME: Rename "RMatAdapter" to "OpenCVAdapter".
|
||||
auto& out_mat = *util::get<cv::Mat*>(g_arg);
|
||||
const auto& rmat = mag.template slot<cv::RMat>().at(rc.id);
|
||||
auto* adapter = rmat.get<RMatAdapter>();
|
||||
if ((adapter != nullptr && out_mat.data != adapter->data()) ||
|
||||
(adapter == nullptr)) {
|
||||
auto mag_data = rmat.get<RMatAdapter>()->data();
|
||||
if (out_mat.data != mag_data) {
|
||||
auto view = rmat.access(RMat::Access::R);
|
||||
asMat(view).copyTo(out_mat);
|
||||
}
|
||||
@@ -409,8 +407,7 @@ bool cv::gimpl::GExecutor::canReshape() const
|
||||
{
|
||||
// FIXME: Introduce proper reshaping support on GExecutor level
|
||||
// for all cases!
|
||||
return std::all_of(m_ops.begin(), m_ops.end(),
|
||||
[](const OpDesc& op) { return op.isl_exec->canReshape(); });
|
||||
return (m_ops.size() == 1) && m_ops[0].isl_exec->canReshape();
|
||||
}
|
||||
|
||||
void cv::gimpl::GExecutor::reshape(const GMetaArgs& inMetas, const GCompileArgs& args)
|
||||
@@ -420,17 +417,7 @@ void cv::gimpl::GExecutor::reshape(const GMetaArgs& inMetas, const GCompileArgs&
|
||||
ade::passes::PassContext ctx{g};
|
||||
passes::initMeta(ctx, inMetas);
|
||||
passes::inferMeta(ctx, true);
|
||||
|
||||
// NB: Before reshape islands need to re-init resources for every slot.
|
||||
for (auto slot : m_slots)
|
||||
{
|
||||
initResource(slot.slot_nh, slot.data_nh);
|
||||
}
|
||||
|
||||
for (auto& op : m_ops)
|
||||
{
|
||||
op.isl_exec->reshape(g, args);
|
||||
}
|
||||
m_ops[0].isl_exec->reshape(g, args);
|
||||
}
|
||||
|
||||
void cv::gimpl::GExecutor::prepareForNewStream()
|
||||
|
||||
@@ -186,9 +186,8 @@ void sync_data(cv::gimpl::stream::Result &r, cv::GOptRunArgsP &outputs)
|
||||
// FIXME: this conversion should be unified
|
||||
switch (out_obj.index())
|
||||
{
|
||||
HANDLE_CASE(cv::Scalar); break;
|
||||
HANDLE_CASE(cv::RMat); break;
|
||||
HANDLE_CASE(cv::MediaFrame); break;
|
||||
HANDLE_CASE(cv::Scalar); break;
|
||||
HANDLE_CASE(cv::RMat); break;
|
||||
|
||||
case T::index_of<O<cv::Mat>*>(): {
|
||||
// Mat: special handling.
|
||||
|
||||
@@ -6,158 +6,10 @@
|
||||
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
#include "../gapi_mock_kernels.hpp"
|
||||
|
||||
namespace opencv_test
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class GMockExecutable final: public cv::gimpl::GIslandExecutable
|
||||
{
|
||||
virtual inline bool canReshape() const override {
|
||||
return m_priv->m_can_reshape;
|
||||
}
|
||||
|
||||
virtual void reshape(ade::Graph&, const GCompileArgs&) override
|
||||
{
|
||||
m_priv->m_reshape_counter++;
|
||||
}
|
||||
virtual void handleNewStream() override { }
|
||||
virtual void run(std::vector<InObj>&&, std::vector<OutObj>&&) { }
|
||||
virtual bool allocatesOutputs() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual cv::RMat allocate(const cv::GMatDesc&) const override
|
||||
{
|
||||
m_priv->m_allocate_counter++;
|
||||
return cv::RMat();
|
||||
}
|
||||
|
||||
// NB: GMockBackendImpl creates new unique_ptr<GMockExecutable>
|
||||
// on every compile call. Need to share counters between instances in order
|
||||
// to validate it in tests.
|
||||
struct Priv
|
||||
{
|
||||
bool m_can_reshape;
|
||||
int m_reshape_counter;
|
||||
int m_allocate_counter;
|
||||
};
|
||||
|
||||
std::shared_ptr<Priv> m_priv;
|
||||
|
||||
public:
|
||||
GMockExecutable(bool can_reshape = true)
|
||||
: m_priv(new Priv{can_reshape, 0, 0})
|
||||
{
|
||||
};
|
||||
|
||||
void setReshape(bool can_reshape) { m_priv->m_can_reshape = can_reshape; }
|
||||
|
||||
int getReshapeCounter() const { return m_priv->m_reshape_counter; }
|
||||
int getAllocateCounter() const { return m_priv->m_allocate_counter; }
|
||||
};
|
||||
|
||||
class GMockBackendImpl final: public cv::gapi::GBackend::Priv
|
||||
{
|
||||
virtual void unpackKernel(ade::Graph &,
|
||||
const ade::NodeHandle &,
|
||||
const cv::GKernelImpl &) override { }
|
||||
|
||||
virtual EPtr compile(const ade::Graph &,
|
||||
const cv::GCompileArgs &,
|
||||
const std::vector<ade::NodeHandle> &) const override
|
||||
{
|
||||
++m_compile_counter;
|
||||
return EPtr{new GMockExecutable(m_exec)};
|
||||
}
|
||||
|
||||
mutable int m_compile_counter = 0;
|
||||
GMockExecutable m_exec;
|
||||
|
||||
virtual bool controlsMerge() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool allowsMerge(const cv::gimpl::GIslandModel::Graph &,
|
||||
const ade::NodeHandle &,
|
||||
const ade::NodeHandle &,
|
||||
const ade::NodeHandle &) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
GMockBackendImpl(const GMockExecutable& exec) : m_exec(exec) { };
|
||||
int getCompileCounter() const { return m_compile_counter; }
|
||||
};
|
||||
|
||||
class GMockFunctor : public gapi::cpu::GOCVFunctor
|
||||
{
|
||||
public:
|
||||
GMockFunctor(cv::gapi::GBackend backend,
|
||||
const char* id,
|
||||
const Meta &meta,
|
||||
const Impl& impl)
|
||||
: gapi::cpu::GOCVFunctor(id, meta, impl), m_backend(backend)
|
||||
{
|
||||
}
|
||||
|
||||
cv::gapi::GBackend backend() const override { return m_backend; }
|
||||
|
||||
private:
|
||||
cv::gapi::GBackend m_backend;
|
||||
};
|
||||
|
||||
template<typename K, typename Callable>
|
||||
GMockFunctor mock_kernel(const cv::gapi::GBackend& backend, Callable c)
|
||||
{
|
||||
using P = cv::detail::OCVCallHelper<Callable, typename K::InArgs, typename K::OutArgs>;
|
||||
return GMockFunctor{ backend
|
||||
, K::id()
|
||||
, &K::getOutMeta
|
||||
, std::bind(&P::callFunctor, std::placeholders::_1, c)
|
||||
};
|
||||
}
|
||||
|
||||
void dummyFooImpl(const cv::Mat&, cv::Mat&) { };
|
||||
void dummyBarImpl(const cv::Mat&, const cv::Mat&, cv::Mat&) { };
|
||||
|
||||
struct GExecutorReshapeTest: public ::testing::Test
|
||||
{
|
||||
GExecutorReshapeTest()
|
||||
: comp([](){
|
||||
cv::GMat in;
|
||||
cv::GMat out = I::Bar::on(I::Foo::on(in), in);
|
||||
return cv::GComputation(in, out);
|
||||
})
|
||||
{
|
||||
backend_impl1 = std::make_shared<GMockBackendImpl>(island1);
|
||||
backend1 = cv::gapi::GBackend{backend_impl1};
|
||||
backend_impl2 = std::make_shared<GMockBackendImpl>(island2);
|
||||
backend2 = cv::gapi::GBackend{backend_impl2};
|
||||
auto kernel1 = mock_kernel<I::Foo>(backend1, dummyFooImpl);
|
||||
auto kernel2 = mock_kernel<I::Bar>(backend2, dummyBarImpl);
|
||||
pkg = cv::gapi::kernels(kernel1, kernel2);
|
||||
in_mat1 = cv::Mat::eye(32, 32, CV_8UC1);
|
||||
in_mat2 = cv::Mat::eye(64, 64, CV_8UC1);
|
||||
}
|
||||
|
||||
cv::GComputation comp;
|
||||
GMockExecutable island1;
|
||||
std::shared_ptr<GMockBackendImpl> backend_impl1;
|
||||
cv::gapi::GBackend backend1;
|
||||
GMockExecutable island2;
|
||||
std::shared_ptr<GMockBackendImpl> backend_impl2;
|
||||
cv::gapi::GBackend backend2;
|
||||
cv::gapi::GKernelPackage pkg;
|
||||
cv::Mat in_mat1, in_mat2, out_mat;;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// FIXME: avoid code duplication
|
||||
// The below graph and config is taken from ComplexIslands test suite
|
||||
TEST(GExecutor, SmokeTest)
|
||||
@@ -225,75 +77,6 @@ TEST(GExecutor, SmokeTest)
|
||||
// with breakdown worked)
|
||||
}
|
||||
|
||||
TEST_F(GExecutorReshapeTest, ReshapeInsteadOfRecompile)
|
||||
{
|
||||
// NB: Initial state
|
||||
EXPECT_EQ(0, backend_impl1->getCompileCounter());
|
||||
EXPECT_EQ(0, backend_impl2->getCompileCounter());
|
||||
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||
|
||||
// NB: First compilation.
|
||||
comp.apply(cv::gin(in_mat1), cv::gout(out_mat), cv::compile_args(pkg));
|
||||
EXPECT_EQ(1, backend_impl1->getCompileCounter());
|
||||
EXPECT_EQ(1, backend_impl2->getCompileCounter());
|
||||
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||
|
||||
// NB: GMockBackendImpl implements "reshape" method,
|
||||
// so it won't be recompiled if the meta is changed.
|
||||
comp.apply(cv::gin(in_mat2), cv::gout(out_mat), cv::compile_args(pkg));
|
||||
EXPECT_EQ(1, backend_impl1->getCompileCounter());
|
||||
EXPECT_EQ(1, backend_impl2->getCompileCounter());
|
||||
EXPECT_EQ(1, island1.getReshapeCounter());
|
||||
EXPECT_EQ(1, island2.getReshapeCounter());
|
||||
}
|
||||
|
||||
TEST_F(GExecutorReshapeTest, OneBackendNotReshapable)
|
||||
{
|
||||
// NB: Make first island not reshapable
|
||||
island1.setReshape(false);
|
||||
|
||||
// NB: Initial state
|
||||
EXPECT_EQ(0, backend_impl1->getCompileCounter());
|
||||
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||
EXPECT_EQ(0, backend_impl2->getCompileCounter());
|
||||
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||
|
||||
// NB: First compilation.
|
||||
comp.apply(cv::gin(in_mat1), cv::gout(out_mat), cv::compile_args(pkg));
|
||||
EXPECT_EQ(1, backend_impl1->getCompileCounter());
|
||||
EXPECT_EQ(1, backend_impl2->getCompileCounter());
|
||||
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||
|
||||
// NB: Since one of islands isn't reshapable
|
||||
// the entire graph isn't reshapable as well.
|
||||
comp.apply(cv::gin(in_mat2), cv::gout(out_mat), cv::compile_args(pkg));
|
||||
EXPECT_EQ(2, backend_impl1->getCompileCounter());
|
||||
EXPECT_EQ(2, backend_impl2->getCompileCounter());
|
||||
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||
EXPECT_EQ(0, island2.getReshapeCounter());
|
||||
}
|
||||
|
||||
TEST_F(GExecutorReshapeTest, ReshapeCallAllocate)
|
||||
{
|
||||
// NB: Initial state
|
||||
EXPECT_EQ(0, island1.getAllocateCounter());
|
||||
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||
|
||||
// NB: First compilation.
|
||||
comp.apply(cv::gin(in_mat1), cv::gout(out_mat), cv::compile_args(pkg));
|
||||
EXPECT_EQ(1, island1.getAllocateCounter());
|
||||
EXPECT_EQ(0, island1.getReshapeCounter());
|
||||
|
||||
// NB: The entire graph is reshapable, so it won't be recompiled, but reshaped.
|
||||
// Check that reshape call "allocate" to reallocate buffers.
|
||||
comp.apply(cv::gin(in_mat2), cv::gout(out_mat), cv::compile_args(pkg));
|
||||
EXPECT_EQ(2, island1.getAllocateCounter());
|
||||
EXPECT_EQ(1, island1.getReshapeCounter());
|
||||
}
|
||||
|
||||
// FIXME: Add explicit tests on GMat/GScalar/GArray<T> being connectors
|
||||
// between executed islands
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
//
|
||||
// Copyright (C) 2019-2021 Intel Corporation
|
||||
// Copyright (C) 2019-2020 Intel Corporation
|
||||
|
||||
|
||||
#include "../test_precomp.hpp"
|
||||
@@ -2214,69 +2214,4 @@ TEST(GAPI_Streaming, TestPythonAPI)
|
||||
cc.stop();
|
||||
}
|
||||
|
||||
TEST(GAPI_Streaming, TestDesyncRMat) {
|
||||
cv::GMat in;
|
||||
auto blurred = cv::gapi::blur(in, cv::Size{3,3});
|
||||
auto desynced = cv::gapi::streaming::desync(blurred);
|
||||
auto out = in - blurred;
|
||||
auto pipe = cv::GComputation(cv::GIn(in), cv::GOut(desynced, out)).compileStreaming();
|
||||
|
||||
cv::Size sz(32,32);
|
||||
cv::Mat in_mat(sz, CV_8UC3);
|
||||
cv::randu(in_mat, cv::Scalar::all(0), cv::Scalar(255));
|
||||
pipe.setSource(cv::gin(in_mat));
|
||||
pipe.start();
|
||||
|
||||
cv::optional<cv::RMat> out_desync;
|
||||
cv::optional<cv::RMat> out_rmat;
|
||||
while (true) {
|
||||
// Initially it throwed "bad variant access" since there was
|
||||
// no RMat handling in wrap_opt_arg
|
||||
EXPECT_NO_THROW(pipe.pull(cv::gout(out_desync, out_rmat)));
|
||||
if (out_rmat) break;
|
||||
}
|
||||
}
|
||||
|
||||
G_API_OP(GTestBlur, <GFrame(GFrame)>, "test.blur") {
|
||||
static GFrameDesc outMeta(GFrameDesc d) { return d; }
|
||||
};
|
||||
GAPI_OCV_KERNEL(GOcvTestBlur, GTestBlur) {
|
||||
static void run(const cv::MediaFrame& in, cv::MediaFrame& out) {
|
||||
auto d = in.desc();
|
||||
GAPI_Assert(d.fmt == cv::MediaFormat::BGR);
|
||||
auto view = in.access(cv::MediaFrame::Access::R);
|
||||
cv::Mat mat(d.size, CV_8UC3, view.ptr[0]);
|
||||
cv::Mat blurred;
|
||||
cv::blur(mat, blurred, cv::Size{3,3});
|
||||
out = cv::MediaFrame::Create<TestMediaBGR>(blurred);
|
||||
}
|
||||
};
|
||||
|
||||
TEST(GAPI_Streaming, TestDesyncMediaFrame) {
|
||||
initTestDataPath();
|
||||
cv::GFrame in;
|
||||
auto blurred = GTestBlur::on(in);
|
||||
auto desynced = cv::gapi::streaming::desync(blurred);
|
||||
auto out = GTestBlur::on(blurred);
|
||||
auto pipe = cv::GComputation(cv::GIn(in), cv::GOut(desynced, out))
|
||||
.compileStreaming(cv::compile_args(cv::gapi::kernels<GOcvTestBlur>()));
|
||||
|
||||
std::string filepath = findDataFile("cv/video/768x576.avi");
|
||||
try {
|
||||
pipe.setSource<BGRSource>(filepath);
|
||||
} catch(...) {
|
||||
throw SkipTestException("Video file can not be opened");
|
||||
}
|
||||
pipe.start();
|
||||
|
||||
cv::optional<cv::MediaFrame> out_desync;
|
||||
cv::optional<cv::MediaFrame> out_frame;
|
||||
while (true) {
|
||||
// Initially it throwed "bad variant access" since there was
|
||||
// no MediaFrame handling in wrap_opt_arg
|
||||
EXPECT_NO_THROW(pipe.pull(cv::gout(out_desync, out_frame)));
|
||||
if (out_frame) break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace opencv_test
|
||||
|
||||
@@ -131,12 +131,6 @@ 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)
|
||||
@@ -144,6 +138,16 @@ 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")
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#--- 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
|
||||
@@ -43,8 +43,7 @@ else()
|
||||
endif()
|
||||
|
||||
add_backend("gtk" WITH_GTK)
|
||||
|
||||
# TODO win32
|
||||
add_backend("win32ui" WITH_WIN32UI)
|
||||
# TODO cocoa
|
||||
# TODO qt
|
||||
# TODO opengl
|
||||
|
||||
@@ -114,6 +114,10 @@ bool setUIBackend(const std::string& backendName);
|
||||
|
||||
#ifndef BUILD_PLUGIN
|
||||
|
||||
#ifdef HAVE_WIN32UI
|
||||
std::shared_ptr<UIBackend> createUIBackendWin32UI();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GTK
|
||||
std::shared_ptr<UIBackend> createUIBackendGTK();
|
||||
#endif
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if defined _WIN32 || defined WINCE
|
||||
#include <windows.h>
|
||||
@@ -127,6 +126,13 @@ void cvSetPropTopmost_COCOA(const char* name, const bool topmost);
|
||||
double cvGetPropVsync_W32(const char* name);
|
||||
void cvSetPropVsync_W32(const char* name, const bool enabled);
|
||||
|
||||
void setWindowTitle_W32(const cv::String& name, const cv::String& title);
|
||||
void setWindowTitle_GTK(const cv::String& name, const cv::String& title);
|
||||
void setWindowTitle_QT(const cv::String& name, const cv::String& title);
|
||||
void setWindowTitle_COCOA(const cv::String& name, const cv::String& title);
|
||||
|
||||
int pollKey_W32();
|
||||
|
||||
//for QT
|
||||
#if defined (HAVE_QT)
|
||||
CvRect cvGetWindowRect_QT(const char* name);
|
||||
|
||||
@@ -50,6 +50,14 @@ std::vector<BackendInfo>& getBuiltinBackendsInfo()
|
||||
#elif defined(ENABLE_PLUGINS)
|
||||
DECLARE_DYNAMIC_BACKEND("QT")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef HAVE_WIN32UI
|
||||
DECLARE_STATIC_BACKEND("WIN32", createUIBackendWin32UI)
|
||||
#elif defined(ENABLE_PLUGINS)
|
||||
DECLARE_DYNAMIC_BACKEND("WIN32")
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
return g_backends;
|
||||
|
||||
@@ -586,6 +586,46 @@ void cv::moveWindow( const String& winname, int x, int y )
|
||||
#endif
|
||||
}
|
||||
|
||||
void cv::setWindowTitle(const String& winname, const String& title)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
{
|
||||
cv::AutoLock lock(cv::getWindowMutex());
|
||||
auto window = findWindow_(winname);
|
||||
if (window)
|
||||
{
|
||||
return window->setTitle(title);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND) && defined(ENABLE_PLUGINS)
|
||||
auto backend = getCurrentUIBackend();
|
||||
if (backend)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "Can't find window with name: '" << winname << "'. Do nothing");
|
||||
CV_NOT_FOUND_DEPRECATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "No UI backends available. Use OPENCV_LOG_LEVEL=DEBUG for investigation");
|
||||
}
|
||||
return;
|
||||
#elif defined(HAVE_WIN32UI)
|
||||
return setWindowTitle_W32(winname, title);
|
||||
#elif defined (HAVE_GTK)
|
||||
return setWindowTitle_GTK(winname, title);
|
||||
#elif defined (HAVE_QT)
|
||||
return setWindowTitle_QT(winname, title);
|
||||
#elif defined (HAVE_COCOA)
|
||||
return setWindowTitle_COCOA(winname, title);
|
||||
#else
|
||||
CV_Error(Error::StsNotImplemented, "The function is not implemented. "
|
||||
"Rebuild the library with Windows, GTK+ 2.x or Cocoa support. "
|
||||
"If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script");
|
||||
#endif
|
||||
}
|
||||
|
||||
void cv::setWindowProperty(const String& winname, int prop_id, double prop_value)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
@@ -630,10 +670,9 @@ int cv::waitKey(int delay)
|
||||
return (code != -1) ? (code & 0xff) : -1;
|
||||
}
|
||||
|
||||
#if defined(HAVE_WIN32UI)
|
||||
// pollKey() implemented in window_w32.cpp
|
||||
#elif defined(HAVE_GTK) || defined(HAVE_COCOA) || defined(HAVE_QT) || (defined (WINRT) && !defined (WINRT_8_0))
|
||||
// pollKey() fallback implementation
|
||||
/*
|
||||
* process until queue is empty but don't wait.
|
||||
*/
|
||||
int cv::pollKey()
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
@@ -647,10 +686,13 @@ int cv::pollKey()
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_WIN32UI)
|
||||
return pollKey_W32();
|
||||
#else
|
||||
// fallback. please implement a proper polling function
|
||||
return cvWaitKey(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int cv::createTrackbar(const String& trackbarName, const String& winName,
|
||||
int* value, int count, TrackbarCallback callback,
|
||||
@@ -948,7 +990,7 @@ void cv::imshow( const String& winname, InputArray _img )
|
||||
auto backend = getCurrentUIBackend();
|
||||
if (backend)
|
||||
{
|
||||
auto window = backend->createWindow(winname, WINDOW_NORMAL);
|
||||
auto window = backend->createWindow(winname, WINDOW_AUTOSIZE);
|
||||
if (!window)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "OpenCV/UI: Can't create window: '" << winname << "'");
|
||||
@@ -1202,13 +1244,6 @@ int cv::createButton(const String&, ButtonCallback, void*, int , bool )
|
||||
// version with a more capable one without a need to recompile dependent
|
||||
// applications or libraries.
|
||||
|
||||
void cv::setWindowTitle(const String&, const String&)
|
||||
{
|
||||
CV_Error(Error::StsNotImplemented, "The function is not implemented. "
|
||||
"Rebuild the library with Windows, GTK+ 2.x or Cocoa support. "
|
||||
"If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script");
|
||||
}
|
||||
|
||||
#define CV_NO_GUI_ERROR(funcname) \
|
||||
cv::error(cv::Error::StsError, \
|
||||
"The function is not implemented. " \
|
||||
@@ -1359,11 +1394,6 @@ CV_IMPL int cvCreateButton(const char*, void (*)(int, void*), void*, int, int)
|
||||
CV_NO_GUI_ERROR("cvCreateButton");
|
||||
}
|
||||
|
||||
int cv::pollKey()
|
||||
{
|
||||
CV_NO_GUI_ERROR("cv::pollKey()");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* End of file. */
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace cv;
|
||||
|
||||
//Static and global first
|
||||
static GuiReceiver *guiMainThread = NULL;
|
||||
@@ -197,7 +198,7 @@ void cvSetPropWindow_QT(const char* name,double prop_value)
|
||||
Q_ARG(double, prop_value));
|
||||
}
|
||||
|
||||
void cv::setWindowTitle(const String& winname, const String& title)
|
||||
void setWindowTitle_QT(const String& winname, const String& title)
|
||||
{
|
||||
if (!guiMainThread)
|
||||
CV_Error(Error::StsNullPtr, "NULL guiReceiver (please create a window)");
|
||||
|
||||
@@ -795,18 +795,18 @@ void cvSetPropTopmost_COCOA( const char* name, const bool topmost )
|
||||
__END__;
|
||||
}
|
||||
|
||||
void cv::setWindowTitle(const String& winname, const String& title)
|
||||
void setWindowTitle_COCOA(const cv::String& winname, const cv::String& title)
|
||||
{
|
||||
CVWindow *window = cvGetWindow(winname.c_str());
|
||||
|
||||
if (window == NULL)
|
||||
{
|
||||
namedWindow(winname);
|
||||
cv::namedWindow(winname);
|
||||
window = cvGetWindow(winname.c_str());
|
||||
}
|
||||
|
||||
if (window == NULL)
|
||||
CV_Error(Error::StsNullPtr, "NULL window");
|
||||
CV_Error(cv::Error::StsNullPtr, "NULL window");
|
||||
|
||||
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
|
||||
@@ -364,7 +364,7 @@ static void cvImageWidget_set_size(GtkWidget * widget, int max_width, int max_he
|
||||
|
||||
|
||||
}
|
||||
assert( image_widget->scaled_image );
|
||||
CV_Assert(image_widget->scaled_image);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -849,7 +849,7 @@ static bool setModeWindow_(const std::shared_ptr<CvWindow>& window, int mode)
|
||||
return false;
|
||||
}
|
||||
|
||||
void cv::setWindowTitle(const String& winname, const String& title)
|
||||
void setWindowTitle_GTK(const String& winname, const String& title)
|
||||
{
|
||||
CV_LOCK_MUTEX();
|
||||
|
||||
@@ -2023,6 +2023,7 @@ static gboolean icvOnMouse( GtkWidget *widget, GdkEvent *event, gpointer user_da
|
||||
(unsigned)pt.y < (unsigned)(image_widget->original_image->height)
|
||||
))
|
||||
{
|
||||
state &= gtk_accelerator_get_default_mod_mask();
|
||||
flags |= BIT_MAP(state, GDK_SHIFT_MASK, CV_EVENT_FLAG_SHIFTKEY) |
|
||||
BIT_MAP(state, GDK_CONTROL_MASK, CV_EVENT_FLAG_CTRLKEY) |
|
||||
BIT_MAP(state, GDK_MOD1_MASK, CV_EVENT_FLAG_ALTKEY) |
|
||||
|
||||
+1425
-949
File diff suppressed because it is too large
Load Diff
@@ -47,24 +47,16 @@
|
||||
namespace cv
|
||||
{
|
||||
|
||||
int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion )
|
||||
static int _rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, std::vector<Point2f> &intersection )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
// L2 metric
|
||||
const float samePointEps = std::max(1e-16f, 1e-6f * (float)std::max(rect1.size.area(), rect2.size.area()));
|
||||
|
||||
if (rect1.size.empty() || rect2.size.empty())
|
||||
{
|
||||
intersectingRegion.release();
|
||||
return INTERSECT_NONE;
|
||||
}
|
||||
|
||||
Point2f vec1[4], vec2[4];
|
||||
Point2f pts1[4], pts2[4];
|
||||
|
||||
std::vector <Point2f> intersection; intersection.reserve(24);
|
||||
|
||||
rect1.points(pts1);
|
||||
rect2.points(pts2);
|
||||
|
||||
@@ -92,8 +84,6 @@ int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& r
|
||||
intersection[i] = pts1[i];
|
||||
}
|
||||
|
||||
Mat(intersection).copyTo(intersectingRegion);
|
||||
|
||||
return INTERSECT_FULL;
|
||||
}
|
||||
}
|
||||
@@ -300,7 +290,50 @@ int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& r
|
||||
}
|
||||
|
||||
intersection.resize(N);
|
||||
Mat(intersection).copyTo(intersectingRegion);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rotatedRectangleIntersection( const RotatedRect& rect1, const RotatedRect& rect2, OutputArray intersectingRegion )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
if (rect1.size.empty() || rect2.size.empty())
|
||||
{
|
||||
intersectingRegion.release();
|
||||
return INTERSECT_NONE;
|
||||
}
|
||||
|
||||
// Shift rectangles closer to origin (0, 0) to improve the calculation of the intesection region
|
||||
// To do that, the average center of the rectangles is moved to the origin
|
||||
const Point2f averageCenter = (rect1.center + rect2.center) / 2.0f;
|
||||
|
||||
RotatedRect shiftedRect1(rect1);
|
||||
RotatedRect shiftedRect2(rect2);
|
||||
|
||||
// Move rectangles closer to origin
|
||||
shiftedRect1.center -= averageCenter;
|
||||
shiftedRect2.center -= averageCenter;
|
||||
|
||||
std::vector <Point2f> intersection; intersection.reserve(24);
|
||||
|
||||
const int ret = _rotatedRectangleIntersection(shiftedRect1, shiftedRect2, intersection);
|
||||
|
||||
// If return is not None, the intersection Points are shifted back to the original position
|
||||
// and copied to the interesectingRegion
|
||||
if (ret != INTERSECT_NONE)
|
||||
{
|
||||
for (size_t i = 0; i < intersection.size(); ++i)
|
||||
{
|
||||
intersection[i] += averageCenter;
|
||||
}
|
||||
|
||||
Mat(intersection).copyTo(intersectingRegion);
|
||||
}
|
||||
else
|
||||
{
|
||||
intersectingRegion.release();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -391,4 +391,21 @@ TEST(Imgproc_RotatedRectangleIntersection, regression_18520)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Imgproc_RotatedRectangleIntersection, regression_19824)
|
||||
{
|
||||
RotatedRect r1(
|
||||
Point2f(246805.033f, 4002326.94f),
|
||||
Size2f(26.40587f, 6.20026f),
|
||||
-62.10156f);
|
||||
RotatedRect r2(
|
||||
Point2f(246805.122f, 4002326.59f),
|
||||
Size2f(27.4821f, 8.5361f),
|
||||
-56.33761f);
|
||||
|
||||
std::vector<Point2f> intersections;
|
||||
int interType = cv::rotatedRectangleIntersection(r1, r2, intersections);
|
||||
EXPECT_EQ(INTERSECT_PARTIAL, interType);
|
||||
EXPECT_LE(intersections.size(), (size_t)7);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -258,6 +258,8 @@ class ClassInfo(GeneralInfo):
|
||||
for m in decl[2]:
|
||||
if m.startswith("="):
|
||||
self.jname = m[1:]
|
||||
if m == '/Simple':
|
||||
self.smart = False
|
||||
|
||||
if self.classpath:
|
||||
prefix = self.classpath.replace('.', '_')
|
||||
@@ -445,7 +447,7 @@ class JavaWrapperGenerator(object):
|
||||
|
||||
def clear(self):
|
||||
self.namespaces = ["cv"]
|
||||
classinfo_Mat = ClassInfo([ 'class cv.Mat', '', [], [] ], self.namespaces)
|
||||
classinfo_Mat = ClassInfo([ 'class cv.Mat', '', ['/Simple'], [] ], self.namespaces)
|
||||
self.classes = { "Mat" : classinfo_Mat }
|
||||
self.module = ""
|
||||
self.Module = ""
|
||||
@@ -466,10 +468,15 @@ class JavaWrapperGenerator(object):
|
||||
if name in type_dict and not classinfo.base:
|
||||
logging.warning('duplicated: %s', classinfo)
|
||||
return
|
||||
if self.isSmartClass(classinfo):
|
||||
jni_name = "*((*(Ptr<"+classinfo.fullNameCPP()+">*)%(n)s_nativeObj).get())"
|
||||
else:
|
||||
jni_name = "(*("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj)"
|
||||
type_dict.setdefault(name, {}).update(
|
||||
{ "j_type" : classinfo.jname,
|
||||
"jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),),
|
||||
"jni_name" : "(*("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj)", "jni_type" : "jlong",
|
||||
"jni_name" : jni_name,
|
||||
"jni_type" : "jlong",
|
||||
"suffix" : "J",
|
||||
"j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname)
|
||||
}
|
||||
@@ -477,7 +484,8 @@ class JavaWrapperGenerator(object):
|
||||
type_dict.setdefault(name+'*', {}).update(
|
||||
{ "j_type" : classinfo.jname,
|
||||
"jn_type" : "long", "jn_args" : (("__int64", ".nativeObj"),),
|
||||
"jni_name" : "("+classinfo.fullNameCPP()+"*)%(n)s_nativeObj", "jni_type" : "jlong",
|
||||
"jni_name" : "&("+jni_name+")",
|
||||
"jni_type" : "jlong",
|
||||
"suffix" : "J",
|
||||
"j_import" : "org.opencv.%s.%s" % (self.module, classinfo.jname)
|
||||
}
|
||||
@@ -966,7 +974,13 @@ class JavaWrapperGenerator(object):
|
||||
ret = "return env->NewStringUTF(_retval_.c_str());"
|
||||
default = 'return env->NewStringUTF("");'
|
||||
elif self.isWrapped(fi.ctype): # wrapped class:
|
||||
ret = "return (jlong) new %s(_retval_);" % self.fullTypeNameCPP(fi.ctype)
|
||||
ret = None
|
||||
if fi.ctype in self.classes:
|
||||
ret_ci = self.classes[fi.ctype]
|
||||
if self.isSmartClass(ret_ci):
|
||||
ret = "return (jlong)(new Ptr<%(ctype)s>(new %(ctype)s(_retval_)));" % { 'ctype': ret_ci.fullNameCPP() }
|
||||
if ret is None:
|
||||
ret = "return (jlong) new %s(_retval_);" % self.fullTypeNameCPP(fi.ctype)
|
||||
elif fi.ctype.startswith('Ptr_'):
|
||||
c_prologue.append("typedef Ptr<%s> %s;" % (self.fullTypeNameCPP(fi.ctype[4:]), fi.ctype))
|
||||
ret = "return (jlong)(new %(ctype)s(_retval_));" % { 'ctype':fi.ctype }
|
||||
@@ -1207,17 +1221,7 @@ JNIEXPORT void JNICALL Java_org_opencv_%(module)s_%(j_cls)s_delete
|
||||
if ci.smart != None:
|
||||
return ci.smart
|
||||
|
||||
# if parents are smart (we hope) then children are!
|
||||
# if not we believe the class is smart if it has "create" method
|
||||
ci.smart = False
|
||||
if ci.base or ci.name == 'Algorithm':
|
||||
ci.smart = True
|
||||
else:
|
||||
for fi in ci.methods:
|
||||
if fi.name == "create":
|
||||
ci.smart = True
|
||||
break
|
||||
|
||||
ci.smart = True # smart class is not properly handled in case of base/derived classes
|
||||
return ci.smart
|
||||
|
||||
def smartWrap(self, ci, fullname):
|
||||
|
||||
@@ -70,7 +70,7 @@ void randu(InputOutputArray dst)
|
||||
cv::randu(dst, -128, 128);
|
||||
else if (dst.depth() == CV_16U)
|
||||
cv::randu(dst, 0, 1024);
|
||||
else if (dst.depth() == CV_32F || dst.depth() == CV_64F)
|
||||
else if (dst.depth() == CV_32F || dst.depth() == CV_64F || dst.depth() == CV_16F)
|
||||
cv::randu(dst, -1.0, 1.0);
|
||||
else if (dst.depth() == CV_16S || dst.depth() == CV_32S)
|
||||
cv::randu(dst, -4096, 4096);
|
||||
|
||||
@@ -1297,7 +1297,7 @@ void TestBase::warmup(cv::InputOutputArray a, WarmUpType wtype)
|
||||
cv::randu(a, -128, 128);
|
||||
else if (depth == CV_16U)
|
||||
cv::randu(a, 0, 1024);
|
||||
else if (depth == CV_32F || depth == CV_64F)
|
||||
else if (depth == CV_32F || depth == CV_64F || depth == CV_16F)
|
||||
cv::randu(a, -1.0, 1.0);
|
||||
else if (depth == CV_16S || depth == CV_32S)
|
||||
cv::randu(a, -4096, 4096);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user