1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin
2020-12-04 18:25:32 +00:00
51 changed files with 2880 additions and 112 deletions
+1 -1
View File
@@ -91,7 +91,7 @@ respectively) by the same factor.
The joint rotation-translation matrix \f$[R|t]\f$ is the matrix product of a projective
transformation and a homogeneous transformation. The 3-by-4 projective transformation maps 3D points
represented in camera coordinates to 2D poins in the image plane and represented in normalized
represented in camera coordinates to 2D points in the image plane and represented in normalized
camera coordinates \f$x' = X_c / Z_c\f$ and \f$y' = Y_c / Z_c\f$:
\f[Z_c \begin{bmatrix}
+4 -3
View File
@@ -153,9 +153,8 @@ void CV_ChessboardSubpixelTest::run( int )
vector<Point2f> test_corners;
bool result = findChessboardCorners(chessboard_image, pattern_size, test_corners, 15);
if(!result)
if (!result && cvtest::debugLevel > 0)
{
#if 0
ts->printf(cvtest::TS::LOG, "Warning: chessboard was not detected! Writing image to test.png\n");
ts->printf(cvtest::TS::LOG, "Size = %d, %d\n", pattern_size.width, pattern_size.height);
ts->printf(cvtest::TS::LOG, "Intrinsic params: fx = %f, fy = %f, cx = %f, cy = %f\n",
@@ -167,7 +166,9 @@ void CV_ChessboardSubpixelTest::run( int )
distortion_coeffs_.at<double>(0, 4));
imwrite("test.png", chessboard_image);
#endif
}
if (!result)
{
continue;
}
+4 -2
View File
@@ -551,7 +551,10 @@ TEST_F(fisheyeTest, stereoRectify)
<< "Q =" << std::endl << Q << std::endl;
}
#if 1 // Debug code
if (cvtest::debugLevel == 0)
return;
// DEBUG code is below
cv::Mat lmapx, lmapy, rmapx, rmapy;
//rewrite for fisheye
cv::fisheye::initUndistortRectifyMap(K1, D1, R1, P1, requested_size, CV_32F, lmapx, lmapy);
@@ -584,7 +587,6 @@ TEST_F(fisheyeTest, stereoRectify)
cv::imwrite(cv::format("fisheye_rectification_AB_%03d.png", i), rectification);
}
#endif
}
TEST_F(fisheyeTest, stereoCalibrate)
+2 -11
View File
@@ -2397,20 +2397,11 @@ public:
UMat(const UMat& m, const Rect& roi);
UMat(const UMat& m, const Range* ranges);
UMat(const UMat& m, const std::vector<Range>& ranges);
// FIXIT copyData=false is not implemented, drop this in favor of cv::Mat (OpenCV 5.0)
//! builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit UMat(const std::vector<_Tp>& vec, bool copyData=false);
//! builds matrix from cv::Vec; the data is copied by default
template<typename _Tp, int n> explicit UMat(const Vec<_Tp, n>& vec, bool copyData=true);
//! builds matrix from cv::Matx; the data is copied by default
template<typename _Tp, int m, int n> explicit UMat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
//! builds matrix from a 2D point
template<typename _Tp> explicit UMat(const Point_<_Tp>& pt, bool copyData=true);
//! builds matrix from a 3D point
template<typename _Tp> explicit UMat(const Point3_<_Tp>& pt, bool copyData=true);
//! builds matrix from comma initializer
template<typename _Tp> explicit UMat(const MatCommaInitializer_<_Tp>& commaInitializer);
//! destructor - calls release()
~UMat();
//! assignment operators
+1 -3
View File
@@ -62,11 +62,9 @@ static bool ipp_countNonZero( Mat &src, int &res )
{
CV_INSTRUMENT_REGION_IPP();
#if defined __APPLE__ || (defined _MSC_VER && defined _M_IX86)
// see https://github.com/opencv/opencv/issues/17453
if (src.dims <= 2 && src.step > 520000)
if (src.dims <= 2 && src.step > 520000 && cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
return false;
#endif
#if IPP_VERSION_X100 < 201801
// Poor performance of SSE42
+2 -2
View File
@@ -152,10 +152,10 @@ float normL2Sqr_(const float* a, const float* b, int n)
{
v_float32 t0 = vx_load(a + j) - vx_load(b + j);
v_float32 t1 = vx_load(a + j + v_float32::nlanes) - vx_load(b + j + v_float32::nlanes);
v_float32 t2 = vx_load(a + j + 2 * v_float32::nlanes) - vx_load(b + j + 2 * v_float32::nlanes);
v_float32 t3 = vx_load(a + j + 3 * v_float32::nlanes) - vx_load(b + j + 3 * v_float32::nlanes);
v_d0 = v_muladd(t0, t0, v_d0);
v_float32 t2 = vx_load(a + j + 2 * v_float32::nlanes) - vx_load(b + j + 2 * v_float32::nlanes);
v_d1 = v_muladd(t1, t1, v_d1);
v_float32 t3 = vx_load(a + j + 3 * v_float32::nlanes) - vx_load(b + j + 3 * v_float32::nlanes);
v_d2 = v_muladd(t2, t2, v_d2);
v_d3 = v_muladd(t3, t3, v_d3);
}
+9 -6
View File
@@ -2365,6 +2365,13 @@ public:
ippTopFeatures = ippCPUID_SSE42;
pIppLibInfo = ippiGetLibVersion();
// workaround: https://github.com/opencv/opencv/issues/12959
std::string ippName(pIppLibInfo->Name ? pIppLibInfo->Name : "");
if (ippName.find("SSE4.2") != std::string::npos)
{
ippTopFeatures = ippCPUID_SSE42;
}
}
public:
@@ -2396,16 +2403,12 @@ unsigned long long getIppFeatures()
#endif
}
unsigned long long getIppTopFeatures();
#ifdef HAVE_IPP
unsigned long long getIppTopFeatures()
{
#ifdef HAVE_IPP
return getIPPSingleton().ippTopFeatures;
#else
return 0;
#endif
}
#endif
void setIppStatus(int status, const char * const _funcname, const char * const _filename, int _line)
{
+2 -1
View File
@@ -535,7 +535,8 @@ protected:
img->copyTo(sub);
shift += img->size().height + 1;
}
//imwrite("/tmp/all_fonts.png", result);
if (cvtest::debugLevel > 0)
imwrite("all_fonts.png", result);
}
};
+25 -55
View File
@@ -1,13 +1,19 @@
# ----------------------------------------------------------------------------
# CMake file for js support
# ----------------------------------------------------------------------------
set(the_description "The js bindings")
if(NOT BUILD_opencv_js) # should be enabled explicitly (by build_js.py script)
ocv_module_disable(js)
if(OPENCV_INITIAL_PASS)
# generator for Objective-C source code and documentation signatures
add_subdirectory(generator)
endif()
if(NOT BUILD_opencv_js) # should be enabled explicitly (by build_js.py script)
return()
endif()
set(the_description "The JavaScript(JS) bindings")
set(OPENCV_JS "opencv.js")
set(JS_HELPER "${CMAKE_CURRENT_SOURCE_DIR}/src/helpers.js")
find_path(EMSCRIPTEN_INCLUDE_DIR
emscripten/bind.h
@@ -28,59 +34,18 @@ if(NOT EMSCRIPTEN_INCLUDE_DIR OR NOT PYTHON_DEFAULT_AVAILABLE)
ocv_module_disable(js)
endif()
ocv_add_module(js BINDINGS)
ocv_add_module(js BINDINGS PRIVATE_REQUIRED opencv_js_bindings_generator)
ocv_module_include_directories(${EMSCRIPTEN_INCLUDE_DIR})
# get list of modules to wrap
# message(STATUS "Wrapped in js:")
set(OPENCV_JS_MODULES)
foreach(m ${OPENCV_MODULES_BUILD})
if(";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";js;" AND HAVE_${m})
list(APPEND OPENCV_JS_MODULES ${m})
# message(STATUS "\t${m}")
endif()
endforeach()
set(opencv_hdrs "")
foreach(m ${OPENCV_JS_MODULES})
list(APPEND opencv_hdrs ${OPENCV_MODULE_${m}_HEADERS})
endforeach(m)
# header blacklist
ocv_list_filterout(opencv_hdrs "modules/.*.h$")
ocv_list_filterout(opencv_hdrs "modules/core/.*/cuda")
ocv_list_filterout(opencv_hdrs "modules/core/.*/opencl")
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/opengl.hpp")
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/ocl.hpp")
ocv_list_filterout(opencv_hdrs "modules/cuda.*")
ocv_list_filterout(opencv_hdrs "modules/cudev")
ocv_list_filterout(opencv_hdrs "modules/core/.*/hal/")
ocv_list_filterout(opencv_hdrs "modules/.*/detection_based_tracker.hpp") # Conditional compilation
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/utils/.*")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")
set(bindings_cpp "${CMAKE_CURRENT_BINARY_DIR}/bindings.cpp")
set(scripts_hdr_parser "${CMAKE_CURRENT_SOURCE_DIR}/../python/src2/hdr_parser.py")
set(JS_HELPER "${CMAKE_CURRENT_SOURCE_DIR}/src/helpers.js")
add_custom_command(
OUTPUT ${bindings_cpp}
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/src/embindgen.py" ${scripts_hdr_parser} ${bindings_cpp} "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${CMAKE_CURRENT_SOURCE_DIR}/src/core_bindings.cpp"
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/core_bindings.cpp
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/embindgen.py
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/templates.py
DEPENDS ${scripts_hdr_parser}
#(not needed - generated by CMake) DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
DEPENDS ${opencv_hdrs}
DEPENDS ${JS_HELPER})
add_definitions("-std=c++11")
link_libraries(${OPENCV_MODULE_${the_module}_DEPS})
set(deps ${OPENCV_MODULE_${the_module}_DEPS})
list(REMOVE_ITEM deps opencv_js_bindings_generator) # don't add dummy module
link_libraries(${deps})
set(bindings_cpp "${OPENCV_JS_BINDINGS_DIR}/gen/bindings.cpp")
set_source_files_properties(${bindings_cpp} PROPERTIES GENERATED TRUE)
OCV_OPTION(BUILD_WASM_INTRIN_TESTS "Build WASM intrin tests" OFF )
if(BUILD_WASM_INTRIN_TESTS)
@@ -94,6 +59,8 @@ else()
ocv_add_executable(${the_module} ${bindings_cpp})
endif()
add_dependencies(${the_module} gen_opencv_js_source)
set(COMPILE_FLAGS "")
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(COMPILE_FLAGS "${COMPILE_FLAGS} -Wno-missing-prototypes")
@@ -101,6 +68,7 @@ endif()
if(COMPILE_FLAGS)
set_target_properties(${the_module} PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS})
endif()
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} --memory-init-file 0 -s TOTAL_MEMORY=128MB -s WASM_MEM_MAX=1GB -s ALLOW_MEMORY_GROWTH=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1 -s SINGLE_FILE=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s EXPORT_NAME=\"'cv'\" -s DEMANGLE_SUPPORT=1")
@@ -155,7 +123,7 @@ add_custom_command(OUTPUT "${opencv_test_js_bin_dir}/${test_data}"
)
list(APPEND opencv_test_js_file_deps "${test_data_path}" "${opencv_test_js_bin_dir}/${test_data}")
add_custom_target(${PROJECT_NAME}_test ALL
add_custom_target(${PROJECT_NAME}_test
DEPENDS ${OCV_JS_PATH} ${opencv_test_js_file_deps})
# perf
@@ -178,7 +146,7 @@ foreach(f ${perf_files})
list(APPEND opencv_perf_js_file_deps "${perf_dir}/${f}" "${opencv_perf_js_bin_dir}/${f}")
endforeach()
add_custom_target(${PROJECT_NAME}_perf ALL
add_custom_target(${PROJECT_NAME}_perf
DEPENDS ${OCV_JS_PATH} ${opencv_perf_js_file_deps})
#loader
@@ -198,4 +166,6 @@ add_custom_command(
list(APPEND opencv_loader_js_file_deps "${loader_dir}/loader.js" "${opencv_loader_js_bin_dir}/loader.js")
add_custom_target(${PROJECT_NAME}_loader ALL
DEPENDS ${OCV_JS_PATH} ${opencv_loader_js_file_deps})
DEPENDS ${OCV_JS_PATH} ${opencv_loader_js_file_deps})
add_custom_target(opencv_test_js ALL DEPENDS opencv_js_test opencv_js_perf opencv_js_loader)
+13
View File
@@ -0,0 +1,13 @@
# get list of modules to wrap
if(HAVE_opencv_js)
message(STATUS "Wrapped in JavaScript(js):")
endif()
set(OPENCV_JS_MODULES "")
foreach(m ${OPENCV_MODULES_BUILD})
if(";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";js;" AND HAVE_${m})
list(APPEND OPENCV_JS_MODULES ${m})
if(HAVE_opencv_js)
message(STATUS " ${m}")
endif()
endif()
endforeach()
+74
View File
@@ -0,0 +1,74 @@
set(MODULE_NAME "js_bindings_generator")
set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
ocv_add_module(${MODULE_NAME} INTERNAL)
set(OPENCV_JS_BINDINGS_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")
file(REMOVE_RECURSE "${OPENCV_JS_BINDINGS_DIR}/gen")
file(MAKE_DIRECTORY "${OPENCV_JS_BINDINGS_DIR}/gen")
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_js_source") # force re-run after CMake
# This file is included from a subdirectory
set(JS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
include(${JS_SOURCE_DIR}/common.cmake) # fill OPENCV_JS_MODULES
set(opencv_hdrs "")
foreach(m ${OPENCV_JS_MODULES})
list(APPEND opencv_hdrs ${OPENCV_MODULE_${m}_HEADERS})
endforeach(m)
# header blacklist
ocv_list_filterout(opencv_hdrs "modules/.*.h$")
ocv_list_filterout(opencv_hdrs "modules/core/.*/cuda")
ocv_list_filterout(opencv_hdrs "modules/core/.*/opencl")
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/opengl.hpp")
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/ocl.hpp")
ocv_list_filterout(opencv_hdrs "modules/cuda.*")
ocv_list_filterout(opencv_hdrs "modules/cudev")
ocv_list_filterout(opencv_hdrs "modules/core/.*/hal/")
ocv_list_filterout(opencv_hdrs "modules/.*/detection_based_tracker.hpp") # Conditional compilation
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/utils/.*")
ocv_update_file("${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")
set(bindings_cpp "${OPENCV_JS_BINDINGS_DIR}/gen/bindings.cpp")
set(scripts_hdr_parser "${JS_SOURCE_DIR}/../python/src2/hdr_parser.py")
if(DEFINED ENV{OPENCV_JS_WHITELIST})
set(OPENCV_JS_WHITELIST_FILE "$ENV{OPENCV_JS_WHITELIST}")
else()
set(OPENCV_JS_WHITELIST_FILE "${OpenCV_SOURCE_DIR}/platforms/js/opencv_js.config.py")
endif()
add_custom_command(
OUTPUT ${bindings_cpp} "${OPENCV_DEPHELPER}/gen_opencv_js_source"
COMMAND
${PYTHON_DEFAULT_EXECUTABLE}
"${CMAKE_CURRENT_SOURCE_DIR}/embindgen.py"
"${scripts_hdr_parser}"
"${bindings_cpp}"
"${CMAKE_CURRENT_BINARY_DIR}/headers.txt"
"${JS_SOURCE_DIR}/src/core_bindings.cpp"
"${OPENCV_JS_WHITELIST_FILE}"
COMMAND
${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/gen_opencv_js_source"
WORKING_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/gen"
DEPENDS
${JS_SOURCE_DIR}/src/core_bindings.cpp
${CMAKE_CURRENT_SOURCE_DIR}/embindgen.py
${CMAKE_CURRENT_SOURCE_DIR}/templates.py
${scripts_hdr_parser}
#(not needed - generated by CMake) ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
${opencv_hdrs}
COMMENT "Generate source files for JavaScript bindings"
)
add_custom_target(gen_opencv_js_source
# excluded from all: ALL
DEPENDS ${bindings_cpp} "${OPENCV_DEPHELPER}/gen_opencv_js_source"
SOURCES
${JS_SOURCE_DIR}/src/core_bindings.cpp
${CMAKE_CURRENT_SOURCE_DIR}/embindgen.py
${CMAKE_CURRENT_SOURCE_DIR}/templates.py
)
@@ -104,8 +104,6 @@ def makeWhiteList(module_list):
return wl
white_list = None
exec(open(os.environ["OPENCV_JS_WHITELIST"]).read())
assert(white_list)
# Features to be exported
export_enums = False
@@ -891,10 +889,10 @@ class JSWrapperGenerator(object):
if __name__ == "__main__":
if len(sys.argv) < 4:
if len(sys.argv) < 5:
print("Usage:\n", \
os.path.basename(sys.argv[0]), \
"<full path to hdr_parser.py> <bindings.cpp> <headers.txt> <core_bindings.cpp>")
"<full path to hdr_parser.py> <bindings.cpp> <headers.txt> <core_bindings.cpp> <opencv_js.config.py>")
print("Current args are: ", ", ".join(["'"+a+"'" for a in sys.argv]))
exit(0)
@@ -908,5 +906,9 @@ if __name__ == "__main__":
bindingsCpp = sys.argv[2]
headers = open(sys.argv[3], 'r').read().split(';')
coreBindings = sys.argv[4]
whiteListFile = sys.argv[5]
exec(open(whiteListFile).read())
assert(white_list)
generator = JSWrapperGenerator()
generator.gen(bindingsCpp, headers, coreBindings)
+1 -1
View File
@@ -88,7 +88,7 @@ using namespace emscripten;
using namespace cv;
#ifdef HAVE_OPENCV_DNN
using namespace dnn;
using namespace cv::dnn;
#endif
#ifdef HAVE_OPENCV_ARUCO
+1 -1
View File
@@ -11,7 +11,7 @@ set(PYTHON_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../")
# get list of modules to wrap
set(OPENCV_PYTHON_MODULES)
foreach(m ${OPENCV_MODULES_BUILD})
if (";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";${MODULE_NAME};" AND HAVE_${m})
if (";${OPENCV_MODULE_${m}_WRAPPERS};" MATCHES ";python;" AND HAVE_${m})
list(APPEND OPENCV_PYTHON_MODULES ${m})
#message(STATUS "\t${m}")
endif()
+6
View File
@@ -18,6 +18,10 @@ except ImportError:
def bootstrap():
import sys
import copy
save_sys_path = copy.copy(sys.path)
if hasattr(sys, 'OpenCV_LOADER'):
print(sys.path)
raise ImportError('ERROR: recursion is detected during loading of "cv2" binary extensions. Check OpenCV installation.')
@@ -85,6 +89,8 @@ def bootstrap():
del sys.modules['cv2']
import cv2
sys.path = save_sys_path # multiprocessing should start from bootstrap code (https://github.com/opencv/opencv/issues/18502)
try:
import sys
del sys.OpenCV_LOADER
+1
View File
@@ -13,6 +13,7 @@ void checkIppStatus();
extern bool skipUnstableTests;
extern bool runBigDataTests;
extern int testThreads;
extern int debugLevel; //< 0 - no debug, 1 - basic test debug information, >1 - extra debug information
void testSetUp();
void testTearDown();
+13 -1
View File
@@ -774,6 +774,7 @@ static bool checkTestData = cv::utils::getConfigurationParameterBool("OPENCV_TES
bool skipUnstableTests = false;
bool runBigDataTests = false;
int testThreads = 0;
int debugLevel = (int)cv::utils::getConfigurationParameterSizeT("OPENCV_TEST_DEBUG", 0);
static size_t memory_usage_base = 0;
@@ -883,6 +884,7 @@ void parseCustomOptions(int argc, char **argv)
"{ test_threads |-1 |the number of worker threads, if parallel execution is enabled}"
"{ skip_unstable |false |skip unstable tests }"
"{ test_bigdata |false |run BigData tests (>=2Gb) }"
"{ test_debug | |0 - no debug (default), 1 - basic test debug information, >1 - extra debug information }"
"{ test_require_data |") + (checkTestData ? "true" : "false") + string("|fail on missing non-required test data instead of skip (env:OPENCV_TEST_REQUIRE_DATA)}"
CV_TEST_TAGS_PARAMS
"{ h help |false |print help info }"
@@ -909,6 +911,14 @@ void parseCustomOptions(int argc, char **argv)
skipUnstableTests = parser.get<bool>("skip_unstable");
runBigDataTests = parser.get<bool>("test_bigdata");
if (parser.has("test_debug"))
{
cv::String s = parser.get<cv::String>("test_debug");
if (s.empty() || s == "true")
debugLevel = 1;
else
debugLevel = parser.get<int>("test_debug");
}
if (parser.has("test_require_data"))
checkTestData = parser.get<bool>("test_require_data");
@@ -1122,7 +1132,9 @@ void SystemInfoCollector::OnTestProgramStart(const testing::UnitTest&)
}
recordPropertyVerbose("cv_cpu_features", "CPU features", cv::getCPUFeaturesLine());
#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");
if (cv::ipp::useIPP())
recordPropertyVerbose("cv_ipp_features", "Intel(R) IPP features code", cv::format("0x%llx", cv::ipp::getIppTopFeatures()));
#endif
#ifdef HAVE_OPENCL
cv::dumpOpenCLInformation();
@@ -116,6 +116,8 @@ double MotionJpegCapture::getProperty(int property) const
{
case CAP_PROP_POS_FRAMES:
return (double)getFramePos();
case CAP_PROP_POS_MSEC:
return (double)getFramePos() * (1000. / m_fps);
case CAP_PROP_POS_AVI_RATIO:
return double(getFramePos())/m_mjpeg_frames.size();
case CAP_PROP_FRAME_WIDTH:
+3 -2
View File
@@ -351,8 +351,6 @@ public:
STDMETHODIMP OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex, DWORD dwStreamFlags, LONGLONG llTimestamp, IMFSample *pSample) CV_OVERRIDE
{
CV_UNUSED(llTimestamp);
HRESULT hr = 0;
cv::AutoLock lock(m_mutex);
@@ -365,6 +363,7 @@ public:
{
CV_LOG_DEBUG(NULL, "videoio(MSMF): drop frame (not processed)");
}
m_lastSampleTimestamp = llTimestamp;
m_lastSample = pSample;
}
}
@@ -444,6 +443,7 @@ public:
IMFSourceReader *m_reader;
DWORD m_dwStreamIndex;
LONGLONG m_lastSampleTimestamp;
_ComPtr<IMFSample> m_lastSample;
};
@@ -917,6 +917,7 @@ bool CvCapture_MSMF::grabFrame()
CV_LOG_WARNING(NULL, "videoio(MSMF): EOS signal. Capture stream is lost");
return false;
}
sampleTime = reader->m_lastSampleTimestamp;
return true;
}
else if (isOpen)
+32 -2
View File
@@ -12,21 +12,51 @@
namespace opencv_test { namespace {
static void test_readFrames(/*const*/ VideoCapture& capture, const int N = 100, Mat* lastFrame = NULL)
static void test_readFrames(/*const*/ VideoCapture& capture, const int N = 100, Mat* lastFrame = NULL, bool testTimestamps = true)
{
Mat frame;
int64 time0 = cv::getTickCount();
int64 sysTimePrev = time0;
const double cvTickFreq = cv::getTickFrequency();
double camTimePrev = 0.0;
const double fps = capture.get(cv::CAP_PROP_FPS);
const double framePeriod = fps == 0.0 ? 1. : 1.0 / fps;
const bool validTickAndFps = cvTickFreq != 0 && fps != 0.;
testTimestamps &= validTickAndFps;
for (int i = 0; i < N; i++)
{
SCOPED_TRACE(cv::format("frame=%d", i));
capture >> frame;
const int64 sysTimeCurr = cv::getTickCount();
const double camTimeCurr = capture.get(cv::CAP_PROP_POS_MSEC);
ASSERT_FALSE(frame.empty());
// Do we have a previous frame?
if (i > 0 && testTimestamps)
{
const double sysTimeElapsedSecs = (sysTimeCurr - sysTimePrev) / cvTickFreq;
const double camTimeElapsedSecs = (camTimeCurr - camTimePrev) / 1000.;
// Check that the time between two camera frames and two system time calls
// are within 1.5 frame periods of one another.
//
// 1.5x is chosen to accomodate for a dropped frame, and an additional 50%
// to account for drift in the scale of the camera and system time domains.
EXPECT_NEAR(sysTimeElapsedSecs, camTimeElapsedSecs, framePeriod * 1.5);
}
EXPECT_GT(cvtest::norm(frame, NORM_INF), 0) << "Complete black image has been received";
sysTimePrev = sysTimeCurr;
camTimePrev = camTimeCurr;
}
int64 time1 = cv::getTickCount();
printf("Processed %d frames on %.2f FPS\n", N, (N * cv::getTickFrequency()) / (time1 - time0 + 1));
printf("Processed %d frames on %.2f FPS\n", N, (N * cvTickFreq) / (time1 - time0 + 1));
if (lastFrame) *lastFrame = frame.clone();
}
+30
View File
@@ -233,6 +233,34 @@ public:
else
std::cout << "Frames counter is not available. Actual frames: " << count_actual << ". SKIP check." << std::endl;
}
void doTimestampTest()
{
if (!isBackendAvailable(apiPref, cv::videoio_registry::getStreamBackends()))
throw SkipTestException(cv::String("Backend is not available/disabled: ") + cv::videoio_registry::getBackendName(apiPref));
if (((apiPref == CAP_FFMPEG) && ((ext == "h264") || (ext == "h265"))))
throw SkipTestException(cv::String("Backend ") + cv::videoio_registry::getBackendName(apiPref) +
cv::String(" does not support CAP_PROP_POS_MSEC option"));
VideoCapture cap;
EXPECT_NO_THROW(cap.open(video_file, apiPref));
if (!cap.isOpened())
throw SkipTestException(cv::String("Backend ") + cv::videoio_registry::getBackendName(apiPref) +
cv::String(" can't open the video: ") + video_file);
Mat img;
for(int i = 0; i < 10; i++)
{
double timestamp = 0;
ASSERT_NO_THROW(cap >> img);
EXPECT_NO_THROW(timestamp = cap.get(CAP_PROP_POS_MSEC));
const double frame_period = 1000.f/bunny_param.getFps();
// NOTE: eps == frame_period, because videoCapture returns frame begining timestamp or frame end
// timestamp depending on codec and back-end. So the first frame has timestamp 0 or frame_period.
EXPECT_NEAR(timestamp, i*frame_period, frame_period);
}
}
};
//==================================================================================================
@@ -353,6 +381,8 @@ TEST_P(videoio_bunny, read_position) { doTest(); }
TEST_P(videoio_bunny, frame_count) { doFrameCountTest(); }
TEST_P(videoio_bunny, frame_timestamp) { doTimestampTest(); }
INSTANTIATE_TEST_CASE_P(videoio, videoio_bunny,
testing::Combine(
testing::ValuesIn(bunny_params),