mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
This commit is contained in:
commit
d00e58cdb0
@ -266,21 +266,21 @@ Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) c
|
|||||||
template<typename _Tp, int m, int n> static inline A& operator op (A& a, const Matx<_Tp,m,n>& b) { cvop; return a; } \
|
template<typename _Tp, int m, int n> static inline A& operator op (A& a, const Matx<_Tp,m,n>& b) { cvop; return a; } \
|
||||||
template<typename _Tp, int m, int n> static inline const A& operator op (const A& a, const Matx<_Tp,m,n>& b) { cvop; return a; }
|
template<typename _Tp, int m, int n> static inline const A& operator op (const A& a, const Matx<_Tp,m,n>& b) { cvop; return a; }
|
||||||
|
|
||||||
CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Mat)
|
CV_MAT_AUG_OPERATOR (+=, cv::add(a, b, (const Mat&)a), Mat, Mat)
|
||||||
CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Scalar)
|
CV_MAT_AUG_OPERATOR (+=, cv::add(a, b, (const Mat&)a), Mat, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat)
|
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
|
||||||
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Scalar)
|
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
|
||||||
CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a,Mat(b),a), Mat)
|
CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a, Mat(b), (const Mat&)a), Mat)
|
||||||
CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a,Mat(b),a), Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_TN(+=, cv::add(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
|
||||||
|
|
||||||
CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Mat)
|
CV_MAT_AUG_OPERATOR (-=, cv::subtract(a, b, (const Mat&)a), Mat, Mat)
|
||||||
CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Scalar)
|
CV_MAT_AUG_OPERATOR (-=, cv::subtract(a, b, (const Mat&)a), Mat, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat)
|
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
|
||||||
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Scalar)
|
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
|
||||||
CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a,Mat(b),a), Mat)
|
CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a, Mat(b), (const Mat&)a), Mat)
|
||||||
CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a,Mat(b),a), Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_TN(-=, cv::subtract(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
|
||||||
|
|
||||||
CV_MAT_AUG_OPERATOR (*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat, Mat)
|
CV_MAT_AUG_OPERATOR (*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat, Mat)
|
||||||
CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat)
|
CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat)
|
||||||
@ -290,37 +290,37 @@ CV_MAT_AUG_OPERATOR_T(*=, a.convertTo(a, -1, b), Mat_<_Tp>, double)
|
|||||||
CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat)
|
CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat)
|
||||||
CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_TN(*=, cv::gemm(a, Mat(b), 1, Mat(), 0, a, 0), Mat_<_Tp>)
|
||||||
|
|
||||||
CV_MAT_AUG_OPERATOR (/=, cv::divide(a,b,a), Mat, Mat)
|
CV_MAT_AUG_OPERATOR (/=, cv::divide(a, b, (const Mat&)a), Mat, Mat)
|
||||||
CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat)
|
CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
|
||||||
CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
|
||||||
CV_MAT_AUG_OPERATOR (/=, a.convertTo((Mat&)a, -1, 1./b), Mat, double)
|
CV_MAT_AUG_OPERATOR (/=, a.convertTo((Mat&)a, -1, 1./b), Mat, double)
|
||||||
CV_MAT_AUG_OPERATOR_T(/=, a.convertTo((Mat&)a, -1, 1./b), Mat_<_Tp>, double)
|
CV_MAT_AUG_OPERATOR_T(/=, a.convertTo((Mat&)a, -1, 1./b), Mat_<_Tp>, double)
|
||||||
CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), a), Mat)
|
CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), (const Mat&)a), Mat)
|
||||||
CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), a), Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_TN(/=, cv::divide(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
|
||||||
|
|
||||||
CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Mat)
|
CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a, b, (const Mat&)a), Mat, Mat)
|
||||||
CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Scalar)
|
CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a, b, (const Mat&)a), Mat, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat)
|
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
|
||||||
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Scalar)
|
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
|
||||||
CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), a), Mat)
|
CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), (const Mat&)a), Mat)
|
||||||
CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), a), Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_TN(&=, cv::bitwise_and(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
|
||||||
|
|
||||||
CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Mat)
|
CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a, b, (const Mat&)a), Mat, Mat)
|
||||||
CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Scalar)
|
CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a, b, (const Mat&)a), Mat, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat)
|
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
|
||||||
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Scalar)
|
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
|
||||||
CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), a), Mat)
|
CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), (const Mat&)a), Mat)
|
||||||
CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), a), Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_TN(|=, cv::bitwise_or(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
|
||||||
|
|
||||||
CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Mat)
|
CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat, Mat)
|
||||||
CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Scalar)
|
CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat)
|
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat_<_Tp>, Mat)
|
||||||
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Scalar)
|
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat_<_Tp>, Scalar)
|
||||||
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a, b, (const Mat&)a), Mat_<_Tp>, Mat_<_Tp>)
|
||||||
CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), a), Mat)
|
CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), (const Mat&)a), Mat)
|
||||||
CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), a), Mat_<_Tp>)
|
CV_MAT_AUG_OPERATOR_TN(^=, cv::bitwise_xor(a, Mat(b), (const Mat&)a), Mat_<_Tp>)
|
||||||
|
|
||||||
#undef CV_MAT_AUG_OPERATOR_TN
|
#undef CV_MAT_AUG_OPERATOR_TN
|
||||||
#undef CV_MAT_AUG_OPERATOR_T
|
#undef CV_MAT_AUG_OPERATOR_T
|
||||||
|
@ -151,13 +151,12 @@
|
|||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
namespace cv
|
namespace cv {
|
||||||
{
|
|
||||||
ParallelLoopBody::~ParallelLoopBody() {}
|
ParallelLoopBody::~ParallelLoopBody() {}
|
||||||
}
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
#ifdef CV_PARALLEL_FRAMEWORK
|
#ifdef CV_PARALLEL_FRAMEWORK
|
||||||
#ifdef ENABLE_INSTRUMENTATION
|
#ifdef ENABLE_INSTRUMENTATION
|
||||||
static void SyncNodes(cv::instr::InstrNode *pNode)
|
static void SyncNodes(cv::instr::InstrNode *pNode)
|
||||||
@ -476,7 +475,7 @@ static SchedPtr pplScheduler;
|
|||||||
|
|
||||||
#endif // CV_PARALLEL_FRAMEWORK
|
#endif // CV_PARALLEL_FRAMEWORK
|
||||||
|
|
||||||
} //namespace
|
} // namespace anon
|
||||||
|
|
||||||
/* ================================ parallel_for_ ================================ */
|
/* ================================ parallel_for_ ================================ */
|
||||||
|
|
||||||
@ -484,7 +483,7 @@ static SchedPtr pplScheduler;
|
|||||||
static void parallel_for_impl(const cv::Range& range, const cv::ParallelLoopBody& body, double nstripes); // forward declaration
|
static void parallel_for_impl(const cv::Range& range, const cv::ParallelLoopBody& body, double nstripes); // forward declaration
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void cv::parallel_for_(const cv::Range& range, const cv::ParallelLoopBody& body, double nstripes)
|
void parallel_for_(const cv::Range& range, const cv::ParallelLoopBody& body, double nstripes)
|
||||||
{
|
{
|
||||||
#ifdef OPENCV_TRACE
|
#ifdef OPENCV_TRACE
|
||||||
CV__TRACE_OPENCV_FUNCTION_NAME_("parallel_for", 0);
|
CV__TRACE_OPENCV_FUNCTION_NAME_("parallel_for", 0);
|
||||||
@ -596,7 +595,7 @@ static void parallel_for_impl(const cv::Range& range, const cv::ParallelLoopBody
|
|||||||
#endif // CV_PARALLEL_FRAMEWORK
|
#endif // CV_PARALLEL_FRAMEWORK
|
||||||
|
|
||||||
|
|
||||||
int cv::getNumThreads(void)
|
int getNumThreads(void)
|
||||||
{
|
{
|
||||||
#ifdef CV_PARALLEL_FRAMEWORK
|
#ifdef CV_PARALLEL_FRAMEWORK
|
||||||
|
|
||||||
@ -654,7 +653,6 @@ int cv::getNumThreads(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace cv {
|
|
||||||
unsigned defaultNumberOfThreads()
|
unsigned defaultNumberOfThreads()
|
||||||
{
|
{
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
@ -676,9 +674,8 @@ unsigned defaultNumberOfThreads()
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void cv::setNumThreads( int threads_ )
|
void setNumThreads( int threads_ )
|
||||||
{
|
{
|
||||||
CV_UNUSED(threads_);
|
CV_UNUSED(threads_);
|
||||||
#ifdef CV_PARALLEL_FRAMEWORK
|
#ifdef CV_PARALLEL_FRAMEWORK
|
||||||
@ -738,7 +735,7 @@ void cv::setNumThreads( int threads_ )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cv::getThreadNum(void)
|
int getThreadNum()
|
||||||
{
|
{
|
||||||
#if defined HAVE_TBB
|
#if defined HAVE_TBB
|
||||||
#if TBB_INTERFACE_VERSION >= 9100
|
#if TBB_INTERFACE_VERSION >= 9100
|
||||||
@ -860,14 +857,17 @@ T minNonZero(const T& val_1, const T& val_2)
|
|||||||
return (val_1 != 0) ? val_1 : val_2;
|
return (val_1 != 0) ? val_1 : val_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cv::getNumberOfCPUs(void)
|
static
|
||||||
|
int getNumberOfCPUs_()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Logic here is to try different methods of getting CPU counts and return
|
* Logic here is to try different methods of getting CPU counts and return
|
||||||
* the minimum most value as it has high probablity of being right and safe.
|
* the minimum most value as it has high probablity of being right and safe.
|
||||||
* Return 1 if we get 0 or not found on all methods.
|
* Return 1 if we get 0 or not found on all methods.
|
||||||
*/
|
*/
|
||||||
#if defined CV_CXX11
|
#if defined CV_CXX11 \
|
||||||
|
&& !defined(__MINGW32__) /* not implemented (2020-03) */ \
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for this standard C++11 way, we do not return directly because
|
* Check for this standard C++11 way, we do not return directly because
|
||||||
* running in a docker or K8s environment will mean this is the host
|
* running in a docker or K8s environment will mean this is the host
|
||||||
@ -881,13 +881,13 @@ int cv::getNumberOfCPUs(void)
|
|||||||
|
|
||||||
#if defined _WIN32
|
#if defined _WIN32
|
||||||
|
|
||||||
SYSTEM_INFO sysinfo;
|
SYSTEM_INFO sysinfo = {};
|
||||||
#if (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_X64) || defined(WINRT)) && _WIN32_WINNT >= 0x501
|
#if (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_X64) || defined(WINRT)) && _WIN32_WINNT >= 0x501
|
||||||
GetNativeSystemInfo( &sysinfo );
|
GetNativeSystemInfo( &sysinfo );
|
||||||
#else
|
#else
|
||||||
GetSystemInfo( &sysinfo );
|
GetSystemInfo( &sysinfo );
|
||||||
#endif
|
#endif
|
||||||
unsigned ncpus_sysinfo = sysinfo.dwNumberOfProcessors < 0 ? 1 : sysinfo.dwNumberOfProcessors; /* Just a fail safe */
|
unsigned ncpus_sysinfo = sysinfo.dwNumberOfProcessors;
|
||||||
ncpus = minNonZero(ncpus, ncpus_sysinfo);
|
ncpus = minNonZero(ncpus, ncpus_sysinfo);
|
||||||
|
|
||||||
#elif defined __APPLE__
|
#elif defined __APPLE__
|
||||||
@ -930,6 +930,7 @@ int cv::getNumberOfCPUs(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined _GNU_SOURCE \
|
#if defined _GNU_SOURCE \
|
||||||
|
&& !defined(__MINGW32__) /* not implemented (2020-03) */ \
|
||||||
&& !defined(__EMSCRIPTEN__) \
|
&& !defined(__EMSCRIPTEN__) \
|
||||||
&& !defined(__ANDROID__) // TODO: add check for modern Android NDK
|
&& !defined(__ANDROID__) // TODO: add check for modern Android NDK
|
||||||
|
|
||||||
@ -952,7 +953,13 @@ int cv::getNumberOfCPUs(void)
|
|||||||
return ncpus != 0 ? ncpus : 1;
|
return ncpus != 0 ? ncpus : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* cv::currentParallelFramework() {
|
int getNumberOfCPUs()
|
||||||
|
{
|
||||||
|
static int nCPUs = getNumberOfCPUs_();
|
||||||
|
return nCPUs; // cached value
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* currentParallelFramework() {
|
||||||
#ifdef CV_PARALLEL_FRAMEWORK
|
#ifdef CV_PARALLEL_FRAMEWORK
|
||||||
return CV_PARALLEL_FRAMEWORK;
|
return CV_PARALLEL_FRAMEWORK;
|
||||||
#else
|
#else
|
||||||
@ -960,6 +967,8 @@ const char* cv::currentParallelFramework() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace cv::
|
||||||
|
|
||||||
CV_IMPL void cvSetNumThreads(int nt)
|
CV_IMPL void cvSetNumThreads(int nt)
|
||||||
{
|
{
|
||||||
cv::setNumThreads(nt);
|
cv::setNumThreads(nt);
|
||||||
|
@ -1519,6 +1519,23 @@ TEST(Core_sortIdx, regression_8941)
|
|||||||
"expected=" << std::endl << expected;
|
"expected=" << std::endl << expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Core_Mat, augmentation_operations_9688)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Mat x(1, 1, CV_64FC1, 1.0f);
|
||||||
|
Mat p(1, 4, CV_64FC1, 5.0f);
|
||||||
|
EXPECT_ANY_THROW(
|
||||||
|
x += p;
|
||||||
|
) << x;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Mat x(1, 1, CV_64FC1, 1.0f);
|
||||||
|
Mat p(1, 4, CV_64FC1, 5.0f);
|
||||||
|
EXPECT_ANY_THROW(
|
||||||
|
x -= p;
|
||||||
|
) << x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//These tests guard regressions against running MatExpr
|
//These tests guard regressions against running MatExpr
|
||||||
//operations on empty operands and giving bogus
|
//operations on empty operands and giving bogus
|
||||||
|
@ -128,7 +128,7 @@ endif()
|
|||||||
|
|
||||||
set(dnn_runtime_libs "")
|
set(dnn_runtime_libs "")
|
||||||
if(INF_ENGINE_TARGET)
|
if(INF_ENGINE_TARGET)
|
||||||
ocv_option(OPENCV_DNN_IE_NN_BUILDER_2019 "Build with Inference Engine NN Builder API support" ON)
|
ocv_option(OPENCV_DNN_IE_NN_BUILDER_2019 "Build with Inference Engine NN Builder API support" ON) # future: NOT HAVE_NGRAPH
|
||||||
if(OPENCV_DNN_IE_NN_BUILDER_2019)
|
if(OPENCV_DNN_IE_NN_BUILDER_2019)
|
||||||
message(STATUS "DNN: Enabling Inference Engine NN Builder API support")
|
message(STATUS "DNN: Enabling Inference Engine NN Builder API support")
|
||||||
add_definitions(-DHAVE_DNN_IE_NN_BUILDER_2019=1)
|
add_definitions(-DHAVE_DNN_IE_NN_BUILDER_2019=1)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#define OPENCV_DNN_VERSION_HPP
|
#define OPENCV_DNN_VERSION_HPP
|
||||||
|
|
||||||
/// Use with major OpenCV version only.
|
/// Use with major OpenCV version only.
|
||||||
#define OPENCV_DNN_API_VERSION 20200128
|
#define OPENCV_DNN_API_VERSION 20200310
|
||||||
|
|
||||||
#if !defined CV_DOXYGEN && !defined CV_STATIC_ANALYSIS && !defined CV_DNN_DONT_ADD_INLINE_NS
|
#if !defined CV_DOXYGEN && !defined CV_STATIC_ANALYSIS && !defined CV_DNN_DONT_ADD_INLINE_NS
|
||||||
#define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION)
|
#define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION)
|
||||||
|
@ -149,7 +149,7 @@ namespace cv {
|
|||||||
|
|
||||||
|
|
||||||
void setConvolution(int kernel, int pad, int stride,
|
void setConvolution(int kernel, int pad, int stride,
|
||||||
int filters_num, int channels_num, int use_batch_normalize)
|
int filters_num, int channels_num, int groups, int use_batch_normalize)
|
||||||
{
|
{
|
||||||
cv::dnn::LayerParams conv_param =
|
cv::dnn::LayerParams conv_param =
|
||||||
getParamConvolution(kernel, pad, stride, filters_num);
|
getParamConvolution(kernel, pad, stride, filters_num);
|
||||||
@ -162,6 +162,8 @@ namespace cv {
|
|||||||
conv_param.set<bool>("bias_term", true);
|
conv_param.set<bool>("bias_term", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conv_param.set<int>("group", groups);
|
||||||
|
|
||||||
lp.layer_name = layer_name;
|
lp.layer_name = layer_name;
|
||||||
lp.layer_type = conv_param.type;
|
lp.layer_type = conv_param.type;
|
||||||
lp.layerParams = conv_param;
|
lp.layerParams = conv_param;
|
||||||
@ -215,15 +217,30 @@ namespace cv {
|
|||||||
fused_layer_names.push_back(last_layer);
|
fused_layer_names.push_back(last_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setReLU()
|
void setActivation(String type)
|
||||||
{
|
{
|
||||||
cv::dnn::LayerParams activation_param;
|
cv::dnn::LayerParams activation_param;
|
||||||
activation_param.set<float>("negative_slope", 0.1f);
|
if (type == "relu")
|
||||||
activation_param.name = "ReLU-name";
|
{
|
||||||
activation_param.type = "ReLU";
|
activation_param.set<float>("negative_slope", 0.1f);
|
||||||
|
activation_param.type = "ReLU";
|
||||||
|
}
|
||||||
|
else if (type == "swish")
|
||||||
|
{
|
||||||
|
activation_param.type = "Swish";
|
||||||
|
}
|
||||||
|
else if (type == "logistic")
|
||||||
|
{
|
||||||
|
activation_param.type = "Sigmoid";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CV_Error(cv::Error::StsParseError, "Unsupported activation: " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string layer_name = cv::format("%s_%d", type.c_str(), layer_id);
|
||||||
|
|
||||||
darknet::LayerParameter lp;
|
darknet::LayerParameter lp;
|
||||||
std::string layer_name = cv::format("relu_%d", layer_id);
|
|
||||||
lp.layer_name = layer_name;
|
lp.layer_name = layer_name;
|
||||||
lp.layer_type = activation_param.type;
|
lp.layer_type = activation_param.type;
|
||||||
lp.layerParams = activation_param;
|
lp.layerParams = activation_param;
|
||||||
@ -487,6 +504,25 @@ namespace cv {
|
|||||||
fused_layer_names.push_back(last_layer);
|
fused_layer_names.push_back(last_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setScaleChannels(int from)
|
||||||
|
{
|
||||||
|
cv::dnn::LayerParams shortcut_param;
|
||||||
|
shortcut_param.type = "Scale";
|
||||||
|
|
||||||
|
darknet::LayerParameter lp;
|
||||||
|
std::string layer_name = cv::format("scale_channels_%d", layer_id);
|
||||||
|
lp.layer_name = layer_name;
|
||||||
|
lp.layer_type = shortcut_param.type;
|
||||||
|
lp.layerParams = shortcut_param;
|
||||||
|
lp.bottom_indexes.push_back(fused_layer_names.at(from));
|
||||||
|
lp.bottom_indexes.push_back(last_layer);
|
||||||
|
last_layer = layer_name;
|
||||||
|
net->layers.push_back(lp);
|
||||||
|
|
||||||
|
layer_id++;
|
||||||
|
fused_layer_names.push_back(last_layer);
|
||||||
|
}
|
||||||
|
|
||||||
void setUpsample(int scaleFactor)
|
void setUpsample(int scaleFactor)
|
||||||
{
|
{
|
||||||
cv::dnn::LayerParams param;
|
cv::dnn::LayerParams param;
|
||||||
@ -608,6 +644,7 @@ namespace cv {
|
|||||||
int padding = getParam<int>(layer_params, "padding", 0);
|
int padding = getParam<int>(layer_params, "padding", 0);
|
||||||
int stride = getParam<int>(layer_params, "stride", 1);
|
int stride = getParam<int>(layer_params, "stride", 1);
|
||||||
int filters = getParam<int>(layer_params, "filters", -1);
|
int filters = getParam<int>(layer_params, "filters", -1);
|
||||||
|
int groups = getParam<int>(layer_params, "groups", 1);
|
||||||
bool batch_normalize = getParam<int>(layer_params, "batch_normalize", 0) == 1;
|
bool batch_normalize = getParam<int>(layer_params, "batch_normalize", 0) == 1;
|
||||||
int flipped = getParam<int>(layer_params, "flipped", 0);
|
int flipped = getParam<int>(layer_params, "flipped", 0);
|
||||||
if (flipped == 1)
|
if (flipped == 1)
|
||||||
@ -618,9 +655,10 @@ namespace cv {
|
|||||||
|
|
||||||
CV_Assert(kernel_size > 0 && filters > 0);
|
CV_Assert(kernel_size > 0 && filters > 0);
|
||||||
CV_Assert(tensor_shape[0] > 0);
|
CV_Assert(tensor_shape[0] > 0);
|
||||||
|
CV_Assert(tensor_shape[0] % groups == 0);
|
||||||
|
|
||||||
setParams.setConvolution(kernel_size, padding, stride, filters, tensor_shape[0],
|
setParams.setConvolution(kernel_size, padding, stride, filters, tensor_shape[0],
|
||||||
batch_normalize);
|
groups, batch_normalize);
|
||||||
|
|
||||||
tensor_shape[0] = filters;
|
tensor_shape[0] = filters;
|
||||||
tensor_shape[1] = (tensor_shape[1] - kernel_size + 2 * padding) / stride + 1;
|
tensor_shape[1] = (tensor_shape[1] - kernel_size + 2 * padding) / stride + 1;
|
||||||
@ -727,6 +765,14 @@ namespace cv {
|
|||||||
from = from < 0 ? from + layers_counter : from;
|
from = from < 0 ? from + layers_counter : from;
|
||||||
setParams.setShortcut(from, alpha);
|
setParams.setShortcut(from, alpha);
|
||||||
}
|
}
|
||||||
|
else if (layer_type == "scale_channels")
|
||||||
|
{
|
||||||
|
std::string bottom_layer = getParam<std::string>(layer_params, "from", "");
|
||||||
|
CV_Assert(!bottom_layer.empty());
|
||||||
|
int from = std::atoi(bottom_layer.c_str());
|
||||||
|
from = from < 0 ? from + layers_counter : from;
|
||||||
|
setParams.setScaleChannels(from);
|
||||||
|
}
|
||||||
else if (layer_type == "upsample")
|
else if (layer_type == "upsample")
|
||||||
{
|
{
|
||||||
int scaleFactor = getParam<int>(layer_params, "stride", 1);
|
int scaleFactor = getParam<int>(layer_params, "stride", 1);
|
||||||
@ -761,7 +807,15 @@ namespace cv {
|
|||||||
std::string activation = getParam<std::string>(layer_params, "activation", "linear");
|
std::string activation = getParam<std::string>(layer_params, "activation", "linear");
|
||||||
if (activation == "leaky")
|
if (activation == "leaky")
|
||||||
{
|
{
|
||||||
setParams.setReLU();
|
setParams.setActivation("relu");
|
||||||
|
}
|
||||||
|
else if (activation == "swish")
|
||||||
|
{
|
||||||
|
setParams.setActivation("swish");
|
||||||
|
}
|
||||||
|
else if (activation == "logistic")
|
||||||
|
{
|
||||||
|
setParams.setActivation("logistic");
|
||||||
}
|
}
|
||||||
else if (activation != "linear")
|
else if (activation != "linear")
|
||||||
CV_Error(cv::Error::StsParseError, "Unsupported activation: " + activation);
|
CV_Error(cv::Error::StsParseError, "Unsupported activation: " + activation);
|
||||||
@ -818,13 +872,15 @@ namespace cv {
|
|||||||
{
|
{
|
||||||
int kernel_size = getParam<int>(layer_params, "size", -1);
|
int kernel_size = getParam<int>(layer_params, "size", -1);
|
||||||
filters = getParam<int>(layer_params, "filters", -1);
|
filters = getParam<int>(layer_params, "filters", -1);
|
||||||
|
int groups = getParam<int>(layer_params, "groups", 1);
|
||||||
use_batch_normalize = getParam<int>(layer_params, "batch_normalize", 0) == 1;
|
use_batch_normalize = getParam<int>(layer_params, "batch_normalize", 0) == 1;
|
||||||
|
|
||||||
CV_Assert(kernel_size > 0 && filters > 0);
|
CV_Assert(kernel_size > 0 && filters > 0);
|
||||||
CV_Assert(tensor_shape[0] > 0);
|
CV_Assert(tensor_shape[0] > 0);
|
||||||
|
CV_Assert(tensor_shape[0] % groups == 0);
|
||||||
|
|
||||||
weights_size = filters * tensor_shape[0] * kernel_size * kernel_size;
|
weights_size = filters * (tensor_shape[0] / groups) * kernel_size * kernel_size;
|
||||||
int sizes_weights[] = { filters, tensor_shape[0], kernel_size, kernel_size };
|
int sizes_weights[] = { filters, tensor_shape[0] / groups, kernel_size, kernel_size };
|
||||||
weightsBlob.create(4, sizes_weights, CV_32F);
|
weightsBlob.create(4, sizes_weights, CV_32F);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -879,8 +935,8 @@ namespace cv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string activation = getParam<std::string>(layer_params, "activation", "linear");
|
std::string activation = getParam<std::string>(layer_params, "activation", "linear");
|
||||||
if(activation == "leaky")
|
if(activation == "leaky" || activation == "swish" || activation == "logistic")
|
||||||
++cv_layers_counter; // For ReLU
|
++cv_layers_counter; // For ReLU, Swish, Sigmoid
|
||||||
|
|
||||||
if(!darknet_layers_counter)
|
if(!darknet_layers_counter)
|
||||||
tensor_shape.resize(1);
|
tensor_shape.resize(1);
|
||||||
|
@ -41,11 +41,13 @@ static const char* dumpInferenceEngineBackendType(Backend backend)
|
|||||||
Backend& getInferenceEngineBackendTypeParam()
|
Backend& getInferenceEngineBackendTypeParam()
|
||||||
{
|
{
|
||||||
static Backend param = parseInferenceEngineBackendType(
|
static Backend param = parseInferenceEngineBackendType(
|
||||||
utils::getConfigurationParameterString("OPENCV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019_TYPE",
|
utils::getConfigurationParameterString("OPENCV_DNN_BACKEND_INFERENCE_ENGINE_TYPE",
|
||||||
#ifndef HAVE_DNN_IE_NN_BUILDER_2019
|
#ifdef HAVE_DNN_NGRAPH
|
||||||
CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH
|
CV_DNN_BACKEND_INFERENCE_ENGINE_NGRAPH
|
||||||
#else
|
#elif defined(HAVE_DNN_IE_NN_BUILDER_2019)
|
||||||
CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API
|
CV_DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_API
|
||||||
|
#else
|
||||||
|
#error "Build configuration error: nGraph or NN Builder API backend should be enabled"
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -97,7 +97,7 @@ TEST(Test_Darknet, read_yolo_voc_stream)
|
|||||||
class Test_Darknet_layers : public DNNTestLayer
|
class Test_Darknet_layers : public DNNTestLayer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void testDarknetLayer(const std::string& name, bool hasWeights = false)
|
void testDarknetLayer(const std::string& name, bool hasWeights = false, bool testBatchProcessing = true)
|
||||||
{
|
{
|
||||||
SCOPED_TRACE(name);
|
SCOPED_TRACE(name);
|
||||||
Mat inp = blobFromNPY(findDataFile("dnn/darknet/" + name + "_in.npy"));
|
Mat inp = blobFromNPY(findDataFile("dnn/darknet/" + name + "_in.npy"));
|
||||||
@ -117,7 +117,7 @@ public:
|
|||||||
Mat out = net.forward();
|
Mat out = net.forward();
|
||||||
normAssert(out, ref, "", default_l1, default_lInf);
|
normAssert(out, ref, "", default_l1, default_lInf);
|
||||||
|
|
||||||
if (inp.size[0] == 1) // test handling of batch size
|
if (inp.size[0] == 1 && testBatchProcessing) // test handling of batch size
|
||||||
{
|
{
|
||||||
SCOPED_TRACE("batch size 2");
|
SCOPED_TRACE("batch size 2");
|
||||||
|
|
||||||
@ -578,6 +578,12 @@ TEST_P(Test_Darknet_layers, convolutional)
|
|||||||
testDarknetLayer("convolutional", true);
|
testDarknetLayer("convolutional", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(Test_Darknet_layers, scale_channels)
|
||||||
|
{
|
||||||
|
// TODO: test fails for batches due to a bug/missing feature in ScaleLayer
|
||||||
|
testDarknetLayer("scale_channels", false, false);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(Test_Darknet_layers, connected)
|
TEST_P(Test_Darknet_layers, connected)
|
||||||
{
|
{
|
||||||
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
if (backend == DNN_BACKEND_OPENCV && target == DNN_TARGET_OPENCL_FP16)
|
||||||
|
@ -1099,14 +1099,6 @@ inline static void recordPropertyVerbose(const std::string & property,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static void recordPropertyVerbose(const std::string& property, const std::string& msg,
|
|
||||||
const char* value, const char* build_value = NULL)
|
|
||||||
{
|
|
||||||
return recordPropertyVerbose(property, msg,
|
|
||||||
value ? std::string(value) : std::string(),
|
|
||||||
build_value ? std::string(build_value) : std::string());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define CV_TEST_BUILD_CONFIG "Debug"
|
#define CV_TEST_BUILD_CONFIG "Debug"
|
||||||
#else
|
#else
|
||||||
@ -1120,7 +1112,14 @@ void SystemInfoCollector::OnTestProgramStart(const testing::UnitTest&)
|
|||||||
recordPropertyVerbose("cv_vcs_version", "OpenCV VCS version", getSnippetFromConfig("Version control:", "\n"));
|
recordPropertyVerbose("cv_vcs_version", "OpenCV VCS version", getSnippetFromConfig("Version control:", "\n"));
|
||||||
recordPropertyVerbose("cv_build_type", "Build type", getSnippetFromConfig("Configuration:", "\n"), CV_TEST_BUILD_CONFIG);
|
recordPropertyVerbose("cv_build_type", "Build type", getSnippetFromConfig("Configuration:", "\n"), CV_TEST_BUILD_CONFIG);
|
||||||
recordPropertyVerbose("cv_compiler", "Compiler", getSnippetFromConfig("C++ Compiler:", "\n"));
|
recordPropertyVerbose("cv_compiler", "Compiler", getSnippetFromConfig("C++ Compiler:", "\n"));
|
||||||
recordPropertyVerbose("cv_parallel_framework", "Parallel framework", cv::currentParallelFramework());
|
const char* parallelFramework = cv::currentParallelFramework();
|
||||||
|
if (parallelFramework)
|
||||||
|
{
|
||||||
|
::testing::Test::RecordProperty("cv_parallel_framework", parallelFramework);
|
||||||
|
int threads = testThreads > 0 ? testThreads : cv::getNumThreads();
|
||||||
|
::testing::Test::RecordProperty("cv_parallel_threads", threads);
|
||||||
|
std::cout << "Parallel framework: " << parallelFramework << " (nthreads=" << threads << ")" << std::endl;
|
||||||
|
}
|
||||||
recordPropertyVerbose("cv_cpu_features", "CPU features", cv::getCPUFeaturesLine());
|
recordPropertyVerbose("cv_cpu_features", "CPU features", cv::getCPUFeaturesLine());
|
||||||
#ifdef HAVE_IPP
|
#ifdef HAVE_IPP
|
||||||
recordPropertyVerbose("cv_ipp_version", "Intel(R) IPP version", cv::ipp::useIPP() ? cv::ipp::getIppVersion() : "disabled");
|
recordPropertyVerbose("cv_ipp_version", "Intel(R) IPP version", cv::ipp::useIPP() ? cv::ipp::getIppVersion() : "disabled");
|
||||||
|
@ -177,6 +177,7 @@ enum VideoCaptureProperties {
|
|||||||
CAP_PROP_AUTO_WB =44, //!< enable/ disable auto white-balance
|
CAP_PROP_AUTO_WB =44, //!< enable/ disable auto white-balance
|
||||||
CAP_PROP_WB_TEMPERATURE=45, //!< white-balance color temperature
|
CAP_PROP_WB_TEMPERATURE=45, //!< white-balance color temperature
|
||||||
CAP_PROP_CODEC_PIXEL_FORMAT =46, //!< (read-only) codec's pixel format. 4-character code - see VideoWriter::fourcc . Subset of [AV_PIX_FMT_*](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/raw.c) or -1 if unknown
|
CAP_PROP_CODEC_PIXEL_FORMAT =46, //!< (read-only) codec's pixel format. 4-character code - see VideoWriter::fourcc . Subset of [AV_PIX_FMT_*](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/raw.c) or -1 if unknown
|
||||||
|
CAP_PROP_BITRATE =47, //!< (read-only) Video bitrate in kbits/s
|
||||||
#ifndef CV_DOXYGEN
|
#ifndef CV_DOXYGEN
|
||||||
CV__CAP_PROP_LATEST
|
CV__CAP_PROP_LATEST
|
||||||
#endif
|
#endif
|
||||||
|
@ -495,7 +495,7 @@ struct CvCapture_FFMPEG
|
|||||||
int64_t get_total_frames() const;
|
int64_t get_total_frames() const;
|
||||||
double get_duration_sec() const;
|
double get_duration_sec() const;
|
||||||
double get_fps() const;
|
double get_fps() const;
|
||||||
int get_bitrate() const;
|
int64_t get_bitrate() const;
|
||||||
|
|
||||||
double r2d(AVRational r) const;
|
double r2d(AVRational r) const;
|
||||||
int64_t dts_to_frame_number(int64_t dts);
|
int64_t dts_to_frame_number(int64_t dts);
|
||||||
@ -1425,6 +1425,8 @@ double CvCapture_FFMPEG::getProperty( int property_id ) const
|
|||||||
if (rawMode)
|
if (rawMode)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
case CAP_PROP_BITRATE:
|
||||||
|
return static_cast<double>(get_bitrate());
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1449,9 +1451,9 @@ double CvCapture_FFMPEG::get_duration_sec() const
|
|||||||
return sec;
|
return sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CvCapture_FFMPEG::get_bitrate() const
|
int64_t CvCapture_FFMPEG::get_bitrate() const
|
||||||
{
|
{
|
||||||
return ic->bit_rate;
|
return ic->bit_rate / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
double CvCapture_FFMPEG::get_fps() const
|
double CvCapture_FFMPEG::get_fps() const
|
||||||
|
@ -333,4 +333,70 @@ TEST(videoio_ffmpeg, parallel)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef std::pair<VideoCaptureProperties, double> cap_property_t;
|
||||||
|
typedef std::vector<cap_property_t> cap_properties_t;
|
||||||
|
typedef std::pair<std::string, cap_properties_t> ffmpeg_cap_properties_param_t;
|
||||||
|
typedef testing::TestWithParam<ffmpeg_cap_properties_param_t> ffmpeg_cap_properties;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
namespace {
|
||||||
|
::testing::AssertionResult IsOneOf(double value, double expected1, double expected2)
|
||||||
|
{
|
||||||
|
// internal floating point class is used to perform accurate floating point types comparison
|
||||||
|
typedef ::testing::internal::FloatingPoint<double> FloatingPoint;
|
||||||
|
|
||||||
|
FloatingPoint val(value);
|
||||||
|
if (val.AlmostEquals(FloatingPoint(expected1)) || val.AlmostEquals(FloatingPoint(expected2)))
|
||||||
|
{
|
||||||
|
return ::testing::AssertionSuccess();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ::testing::AssertionFailure()
|
||||||
|
<< value << " is neither equal to " << expected1 << " nor " << expected2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TEST_P(ffmpeg_cap_properties, can_read_property)
|
||||||
|
{
|
||||||
|
if (!videoio_registry::hasBackend(CAP_FFMPEG))
|
||||||
|
throw SkipTestException("FFmpeg backend was not found");
|
||||||
|
|
||||||
|
ffmpeg_cap_properties_param_t parameters = GetParam();
|
||||||
|
const std::string path = parameters.first;
|
||||||
|
const cap_properties_t properties = parameters.second;
|
||||||
|
|
||||||
|
VideoCapture cap(findDataFile(path), CAP_FFMPEG);
|
||||||
|
ASSERT_TRUE(cap.isOpened()) << "Can not open " << findDataFile(path);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < properties.size(); ++i)
|
||||||
|
{
|
||||||
|
const cap_property_t& prop = properties[i];
|
||||||
|
const double actualValue = cap.get(static_cast<int>(prop.first));
|
||||||
|
#ifndef _WIN32
|
||||||
|
EXPECT_DOUBLE_EQ(actualValue, prop.second)
|
||||||
|
<< "Property " << static_cast<int>(prop.first) << " has wrong value";
|
||||||
|
#else
|
||||||
|
EXPECT_TRUE(IsOneOf(actualValue, prop.second, 0.0))
|
||||||
|
<< "Property " << static_cast<int>(prop.first) << " has wrong value";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cap_properties_t loadBigBuckBunnyFFProbeResults() {
|
||||||
|
cap_property_t properties[] = { cap_property_t(CAP_PROP_BITRATE, 5851.),
|
||||||
|
cap_property_t(CAP_PROP_FPS, 24.),
|
||||||
|
cap_property_t(CAP_PROP_FRAME_HEIGHT, 384.),
|
||||||
|
cap_property_t(CAP_PROP_FRAME_WIDTH, 672.) };
|
||||||
|
return cap_properties_t(properties, properties + sizeof(properties) / sizeof(cap_property_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
const ffmpeg_cap_properties_param_t videoio_ffmpeg_properties[] = {
|
||||||
|
ffmpeg_cap_properties_param_t("video/big_buck_bunny.avi", loadBigBuckBunnyFFProbeResults())
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(videoio, ffmpeg_cap_properties, testing::ValuesIn(videoio_ffmpeg_properties));
|
||||||
|
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
Loading…
Reference in New Issue
Block a user