chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# CMake file for js support
|
||||
# ----------------------------------------------------------------------------
|
||||
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
|
||||
PATHS
|
||||
ENV EMSCRIPTEN_ROOT
|
||||
PATH_SUFFIXES system/include include
|
||||
DOC "Location of Emscripten SDK")
|
||||
|
||||
if(NOT EMSCRIPTEN_INCLUDE_DIR OR NOT PYTHON_DEFAULT_AVAILABLE)
|
||||
set(DISABLE_MSG "Module 'js' disabled because the following dependencies are not found:")
|
||||
if(NOT EMSCRIPTEN_INCLUDE_DIR)
|
||||
set(DISABLE_MSG "${DISABLE_MSG} Emscripten")
|
||||
endif()
|
||||
if(NOT PYTHON_DEFAULT_AVAILABLE)
|
||||
set(DISABLE_MSG "${DISABLE_MSG} Python")
|
||||
endif()
|
||||
message(STATUS ${DISABLE_MSG})
|
||||
ocv_module_disable(js)
|
||||
endif()
|
||||
|
||||
# Get Emscripten version from emscripten/version.h
|
||||
unset(EMSCRIPTEN_VERSION)
|
||||
unset(EMSCRIPTEN_VERSION_CONTENTS)
|
||||
unset(EMSCRIPTEN_VERSION_MAJOR)
|
||||
unset(EMSCRIPTEN_VERSION_MINOR)
|
||||
unset(EMSCRIPTEN_VERSION_TINY)
|
||||
|
||||
set(EMSCRIPTEN_VERSION_PATH "${EMSCRIPTEN_INCLUDE_DIR}/emscripten/version.h")
|
||||
if(NOT EXISTS "${EMSCRIPTEN_VERSION_PATH}")
|
||||
message(STATUS "${EMSCRIPTEN_INCLUDE_DIR}/emscripten/version.h is missing")
|
||||
else()
|
||||
file(STRINGS "${EMSCRIPTEN_VERSION_PATH}" EMSCRIPTEN_VERSION_CONTENTS REGEX "^#define[ \t]+__EMSCRIPTEN_[a-zA-Z]+__[ \t][0-9]+")
|
||||
if(NOT EMSCRIPTEN_VERSION_CONTENTS)
|
||||
message(STATUS "${EMSCRIPTEN_INCLUDE_DIR}/emscripten/version.h is exists, but is not readable")
|
||||
else()
|
||||
if(EMSCRIPTEN_VERSION_CONTENTS MATCHES "__EMSCRIPTEN_[mM][aA][jJ][oO][rR]__[ \t]+([0-9]+)")
|
||||
set(EMSCRIPTEN_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
if(EMSCRIPTEN_VERSION_CONTENTS MATCHES "__EMSCRIPTEN_[mM][iI][nN][oO][rR]__[ \t]+([0-9]+)")
|
||||
set(EMSCRIPTEN_VERSION_MINOR "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
if(EMSCRIPTEN_VERSION_CONTENTS MATCHES "__EMSCRIPTEN_[tT][iI][nN][yY]__[ \t]+([0-9]+)")
|
||||
set(EMSCRIPTEN_VERSION_TINY "${CMAKE_MATCH_1}")
|
||||
endif()
|
||||
|
||||
# When version(major/minor/tiny) is 0, "if(version)" is failed.
|
||||
# "if(version GREATER_EQUAL 0)" can compare version as numeric.
|
||||
if( (EMSCRIPTEN_VERSION_MAJOR GREATER_EQUAL "0") AND
|
||||
(EMSCRIPTEN_VERSION_MINOR GREATER_EQUAL "0") AND
|
||||
(EMSCRIPTEN_VERSION_TINY GREATER_EQUAL "0")
|
||||
)
|
||||
set(EMSCRIPTEN_VERSION "${EMSCRIPTEN_VERSION_MAJOR}.${EMSCRIPTEN_VERSION_MINOR}.${EMSCRIPTEN_VERSION_TINY}")
|
||||
message(STATUS "js: Emscripten version = ${EMSCRIPTEN_VERSION}")
|
||||
else()
|
||||
message(STATUS "js: Emscripten version is not able to parsed")
|
||||
message(AUTHOR_WARNING "EMSCRIPTEN_VERSION_CONTENTS = ${EMSCRIPTEN_VERSION_CONTENTS}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Embind requires C++17 or newer from Emscripten 4.0.20.
|
||||
# See https://github.com/emscripten-core/emscripten/blob/main/ChangeLog.md#4020---111825
|
||||
if(EMSCRIPTEN_VERSION VERSION_GREATER_EQUAL "4.0.20")
|
||||
if(NOT CMAKE_CXX_STANDARD OR CMAKE_CXX_STANDARD STREQUAL "98"
|
||||
OR CMAKE_CXX_STANDARD STREQUAL "11" OR CMAKE_CXX_STANDARD STREQUAL "14")
|
||||
|
||||
message(FATAL_ERROR "[OpenCV.js Build Error] "
|
||||
"Emscripten ${EMSCRIPTEN_VERSION} requires C++17 or newer for Embind, "
|
||||
"but CMAKE_CXX_STANDARD is set to '${CMAKE_CXX_STANDARD}'.\n"
|
||||
"Please re-run emcmake with --cmake_option=\"-DCMAKE_CXX_STANDARD=17\"\n")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
ocv_add_module(js BINDINGS PRIVATE_REQUIRED opencv_js_bindings_generator)
|
||||
|
||||
ocv_module_include_directories(${EMSCRIPTEN_INCLUDE_DIR})
|
||||
|
||||
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)
|
||||
add_definitions(-DTEST_WASM_INTRIN)
|
||||
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../ts/include")
|
||||
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../imgcodecs/include")
|
||||
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../videoio/include")
|
||||
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../highgui/include")
|
||||
ocv_add_executable(${the_module} ${bindings_cpp} "${CMAKE_CURRENT_SOURCE_DIR}/../ts/src/ts_gtest.cpp")
|
||||
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")
|
||||
endif()
|
||||
if(COMPILE_FLAGS)
|
||||
set_target_properties(${the_module} PROPERTIES COMPILE_FLAGS ${COMPILE_FLAGS})
|
||||
endif()
|
||||
|
||||
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s TOTAL_MEMORY=128MB -s WASM_MEM_MAX=1GB -s ALLOW_MEMORY_GROWTH=1")
|
||||
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1")
|
||||
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s EXPORT_NAME=\"'cv'\"")
|
||||
# See https://github.com/opencv/opencv/issues/27513
|
||||
# DEMANGLE_SUPPRT is deprecated at Emscripten 3.1.54 and later.
|
||||
if(NOT EMSCRIPTEN_VERSION OR EMSCRIPTEN_VERSION VERSION_LESS "3.1.54")
|
||||
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s DEMANGLE_SUPPORT=1")
|
||||
endif()
|
||||
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s FORCE_FILESYSTEM=1 --use-preload-plugins --bind --post-js ${JS_HELPER} ${COMPILE_FLAGS}")
|
||||
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS}")
|
||||
|
||||
# add UMD wrapper
|
||||
set(MODULE_JS_PATH "${OpenCV_BINARY_DIR}/bin/${the_module}.js")
|
||||
set(OCV_JS_PATH "${OpenCV_BINARY_DIR}/bin/${OPENCV_JS}")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${OCV_JS_PATH}
|
||||
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/src/make_umd.py" ${MODULE_JS_PATH} "${OCV_JS_PATH}"
|
||||
DEPENDS ${the_module}
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/make_umd.py")
|
||||
|
||||
add_custom_target(${OPENCV_JS} ALL
|
||||
DEPENDS ${OCV_JS_PATH}
|
||||
DEPENDS ${the_module})
|
||||
|
||||
# test
|
||||
set(opencv_test_js_bin_dir "${EXECUTABLE_OUTPUT_PATH}")
|
||||
set(test_dir ${CMAKE_CURRENT_SOURCE_DIR}/test)
|
||||
|
||||
set(opencv_test_js_file_deps "")
|
||||
|
||||
# message(STATUS "${opencv_test_js_bin_dir}")
|
||||
|
||||
# make sure the build directory exists
|
||||
file(MAKE_DIRECTORY "${opencv_test_js_bin_dir}")
|
||||
|
||||
# gather and copy specific files for js test
|
||||
file(GLOB_RECURSE test_files RELATIVE "${test_dir}" "${test_dir}/*")
|
||||
foreach(f ${test_files})
|
||||
# message(STATUS "copy ${test_dir}/${f} ${opencv_test_js_bin_dir}/${f}")
|
||||
add_custom_command(OUTPUT "${opencv_test_js_bin_dir}/${f}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${test_dir}/${f}" "${opencv_test_js_bin_dir}/${f}"
|
||||
DEPENDS "${test_dir}/${f}"
|
||||
COMMENT "Copying ${f}"
|
||||
)
|
||||
list(APPEND opencv_test_js_file_deps "${test_dir}/${f}" "${opencv_test_js_bin_dir}/${f}")
|
||||
endforeach()
|
||||
|
||||
# copy test data
|
||||
set(test_data "haarcascade_frontalface_default.xml")
|
||||
set(test_data_path "${PROJECT_SOURCE_DIR}/../../data/haarcascades/${test_data}")
|
||||
|
||||
add_custom_command(OUTPUT "${opencv_test_js_bin_dir}/${test_data}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${test_data_path}" "${opencv_test_js_bin_dir}/${test_data}"
|
||||
DEPENDS "${test_data_path}"
|
||||
COMMENT "Copying ${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
|
||||
DEPENDS ${OCV_JS_PATH} ${opencv_test_js_file_deps})
|
||||
|
||||
# perf
|
||||
set(opencv_perf_js_bin_dir "${EXECUTABLE_OUTPUT_PATH}/perf")
|
||||
set(perf_dir ${CMAKE_CURRENT_SOURCE_DIR}/perf)
|
||||
|
||||
set(opencv_perf_js_file_deps "")
|
||||
|
||||
# make sure the build directory exists
|
||||
file(MAKE_DIRECTORY "${opencv_perf_js_bin_dir}")
|
||||
|
||||
# gather and copy specific files for js perf
|
||||
file(GLOB_RECURSE perf_files RELATIVE "${perf_dir}" "${perf_dir}/*")
|
||||
foreach(f ${perf_files})
|
||||
add_custom_command(OUTPUT "${opencv_perf_js_bin_dir}/${f}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different "${perf_dir}/${f}" "${opencv_perf_js_bin_dir}/${f}"
|
||||
DEPENDS "${perf_dir}/${f}"
|
||||
COMMENT "Copying ${f}"
|
||||
)
|
||||
list(APPEND opencv_perf_js_file_deps "${perf_dir}/${f}" "${opencv_perf_js_bin_dir}/${f}")
|
||||
endforeach()
|
||||
|
||||
add_custom_target(${PROJECT_NAME}_perf
|
||||
DEPENDS ${OCV_JS_PATH} ${opencv_perf_js_file_deps})
|
||||
|
||||
#loader
|
||||
set(opencv_loader_js_bin_dir "${EXECUTABLE_OUTPUT_PATH}")
|
||||
set(loader_dir ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
|
||||
set(opencv_loader_js_file_deps "")
|
||||
|
||||
# make sure the build directory exists
|
||||
file(MAKE_DIRECTORY "${opencv_loader_js_bin_dir}")
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${loader_dir}/loader.js
|
||||
${opencv_loader_js_bin_dir}/loader.js)
|
||||
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})
|
||||
|
||||
add_custom_target(opencv_test_js ALL DEPENDS opencv_js_test opencv_js_perf opencv_js_loader)
|
||||
@@ -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()
|
||||
@@ -0,0 +1,126 @@
|
||||
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/calib3d/include/opencv2/calib3d/private.hpp")
|
||||
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/fast_math.hpp")
|
||||
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/*.private.*")
|
||||
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/utils/instrumentation.hpp")
|
||||
ocv_list_filterout(opencv_hdrs "modules/core/include/opencv2/core/utils/trace*")
|
||||
|
||||
set(config_json_headers_list "")
|
||||
foreach(header IN LISTS opencv_hdrs)
|
||||
if(NOT config_json_headers_list STREQUAL "")
|
||||
set(config_json_headers_list "${config_json_headers_list},\n\"${header}\"")
|
||||
else()
|
||||
set(config_json_headers_list "\"${header}\"")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
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}")
|
||||
message(STATUS "Use white list from environment ${OPENCV_JS_WHITELIST_FILE}")
|
||||
else()
|
||||
#generate white list from modules/<module_name>/misc/js/whitelist.json
|
||||
set(OPENCV_JS_WHITELIST_FILE "${CMAKE_CURRENT_BINARY_DIR}/whitelist.json")
|
||||
foreach(m IN LISTS OPENCV_JS_MODULES)
|
||||
set(js_whitelist "${OPENCV_MODULE_${m}_LOCATION}/misc/js/gen_dict.json")
|
||||
if (EXISTS "${js_whitelist}")
|
||||
file(READ "${js_whitelist}" whitelist_content)
|
||||
list(APPEND OPENCV_JS_WHITELIST_CONTENT "\"${m}\": ${whitelist_content}")
|
||||
endif()
|
||||
endforeach(m)
|
||||
string(REPLACE ";" ", \n" OPENCV_JS_WHITELIST_CONTENT_STRING "${OPENCV_JS_WHITELIST_CONTENT}")
|
||||
set(OPENCV_JS_WHITELIST_CONTENT_STRING "{\n${OPENCV_JS_WHITELIST_CONTENT_STRING}}\n")
|
||||
ocv_update_file("${OPENCV_JS_WHITELIST_FILE}" "${OPENCV_JS_WHITELIST_CONTENT_STRING}")
|
||||
message(STATUS "Use autogenerated whitelist ${OPENCV_JS_WHITELIST_FILE}")
|
||||
endif()
|
||||
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVBindingsPreprocessorDefinitions.cmake")
|
||||
ocv_bindings_generator_populate_preprocessor_definitions(
|
||||
OPENCV_MODULES_BUILD
|
||||
opencv_preprocessor_defs
|
||||
)
|
||||
|
||||
set(__config_str
|
||||
"{
|
||||
\"headers\": [
|
||||
${config_json_headers_list}
|
||||
],
|
||||
\"preprocessor_definitions\": {
|
||||
${opencv_preprocessor_defs}
|
||||
},
|
||||
\"core_bindings_file_path\": \"${JS_SOURCE_DIR}/src/core_bindings.cpp\"
|
||||
}")
|
||||
set(JSON_CONFIG_FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/gen_js_config.json")
|
||||
if(EXISTS "${JSON_CONFIG_FILE_PATH}")
|
||||
file(READ "${JSON_CONFIG_FILE_PATH}" __content)
|
||||
else()
|
||||
set(__content "")
|
||||
endif()
|
||||
if(NOT "${__content}" STREQUAL "${__config_str}")
|
||||
file(WRITE "${JSON_CONFIG_FILE_PATH}" "${__config_str}")
|
||||
endif()
|
||||
unset(__config_str)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${bindings_cpp} "${OPENCV_DEPHELPER}/gen_opencv_js_source"
|
||||
COMMAND
|
||||
${PYTHON_DEFAULT_EXECUTABLE}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/embindgen.py"
|
||||
--parser "${scripts_hdr_parser}"
|
||||
--output_file "${bindings_cpp}"
|
||||
--config "${JSON_CONFIG_FILE_PATH}"
|
||||
--whitelist "${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
|
||||
${JSON_CONFIG_FILE_PATH}
|
||||
"${OPENCV_JS_WHITELIST_FILE}"
|
||||
${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
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,195 @@
|
||||
###############################################################################
|
||||
#
|
||||
# IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
#
|
||||
# By downloading, copying, installing or using the software you agree to this license.
|
||||
# If you do not agree to this license, do not download, install,
|
||||
# copy or use the software.
|
||||
#
|
||||
#
|
||||
# License Agreement
|
||||
# For Open Source Computer Vision Library
|
||||
#
|
||||
# Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
# Third party copyrights are property of their respective owners.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistribution's of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * The name of the copyright holders may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# This software is provided by the copyright holders and contributors "as is" and
|
||||
# any express or implied warranties, including, but not limited to, the implied
|
||||
# warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
# In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
# indirect, incidental, special, exemplary, or consequential damages
|
||||
# (including, but not limited to, procurement of substitute goods or services;
|
||||
# loss of use, data, or profits; or business interruption) however caused
|
||||
# and on any theory of liability, whether in contract, strict liability,
|
||||
# or tort (including negligence or otherwise) arising in any way out of
|
||||
# the use of this software, even if advised of the possibility of such damage.
|
||||
#
|
||||
|
||||
###############################################################################
|
||||
# AUTHOR: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu
|
||||
#
|
||||
# LICENSE AGREEMENT
|
||||
# Copyright (c) 2015, 2015 The Regents of the University of California (Regents)
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the University nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##############################################################################
|
||||
|
||||
from string import Template
|
||||
|
||||
wrapper_codes_template = Template("namespace $ns {\n$defs\n}")
|
||||
|
||||
call_template = Template("""$func($args)""")
|
||||
class_call_template = Template("""$obj.$func($args)""")
|
||||
static_class_call_template = Template("""$scope$func($args)""")
|
||||
|
||||
wrapper_function_template = Template(""" $ret_val $func($signature)$const {
|
||||
return $cpp_call;
|
||||
}
|
||||
""")
|
||||
|
||||
wrapper_function_with_def_args_template = Template(""" $ret_val $func($signature)$const {
|
||||
$check_args
|
||||
}
|
||||
""")
|
||||
|
||||
wrapper_overload_def_values = [
|
||||
Template("""return $cpp_call;"""), Template("""if ($arg0.isUndefined())
|
||||
return $cpp_call;
|
||||
else
|
||||
$next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined())
|
||||
return $cpp_call;
|
||||
else $next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined() && $arg2.isUndefined())
|
||||
return $cpp_call;
|
||||
else $next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined() && $arg2.isUndefined() && $arg3.isUndefined())
|
||||
return $cpp_call;
|
||||
else $next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined() && $arg2.isUndefined() && $arg3.isUndefined() &&
|
||||
$arg4.isUndefined())
|
||||
return $cpp_call;
|
||||
else $next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined() && $arg2.isUndefined() && $arg3.isUndefined() &&
|
||||
$arg4.isUndefined() && $arg5.isUndefined() )
|
||||
return $cpp_call;
|
||||
else $next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined() && $arg2.isUndefined() && $arg3.isUndefined() &&
|
||||
$arg4.isUndefined() && $arg5.isUndefined() && $arg6.isUndefined() )
|
||||
return $cpp_call;
|
||||
else $next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined() && $arg2.isUndefined() && $arg3.isUndefined() &&
|
||||
$arg4.isUndefined() && $arg5.isUndefined()&& $arg6.isUndefined() && $arg7.isUndefined())
|
||||
return $cpp_call;
|
||||
else $next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined() && $arg2.isUndefined() && $arg3.isUndefined() &&
|
||||
$arg4.isUndefined() && $arg5.isUndefined()&& $arg6.isUndefined() && $arg7.isUndefined() &&
|
||||
$arg8.isUndefined())
|
||||
return $cpp_call;
|
||||
else $next"""),
|
||||
Template("""if ($arg0.isUndefined() && $arg1.isUndefined() && $arg2.isUndefined() && $arg3.isUndefined() &&
|
||||
$arg4.isUndefined() && $arg5.isUndefined()&& $arg6.isUndefined() && $arg7.isUndefined()&&
|
||||
$arg8.isUndefined() && $arg9.isUndefined())
|
||||
return $cpp_call;
|
||||
else $next""")]
|
||||
|
||||
emscripten_binding_template = Template("""
|
||||
|
||||
EMSCRIPTEN_BINDINGS($binding_name) {$bindings
|
||||
}
|
||||
""")
|
||||
|
||||
simple_function_template = Template("""
|
||||
emscripten::function("$js_name", &$cpp_name);
|
||||
""")
|
||||
|
||||
smart_ptr_reg_template = Template("""
|
||||
.smart_ptr<Ptr<$cname>>("Ptr<$name>")
|
||||
""")
|
||||
|
||||
overload_function_template = Template("""
|
||||
function("$js_name", select_overload<$ret($args)$const>(&$cpp_name)$optional);
|
||||
""")
|
||||
|
||||
overload_class_function_template = Template("""
|
||||
.function("$js_name", select_overload<$ret($args)$const>(&$cpp_name)$optional)""")
|
||||
|
||||
overload_class_static_function_template = Template("""
|
||||
.class_function("$js_name", select_overload<$ret($args)$const>(&$cpp_name)$optional)""")
|
||||
|
||||
class_property_template = Template("""
|
||||
.property("$js_name", &$cpp_name)""")
|
||||
|
||||
class_property_enum_template = Template("""
|
||||
.property("$js_name", binding_utils::underlying_ptr(&$cpp_name))""")
|
||||
|
||||
ctr_template = Template("""
|
||||
.constructor(select_overload<$ret($args)$const>(&$cpp_name)$optional)""")
|
||||
|
||||
smart_ptr_ctr_overload_template = Template("""
|
||||
.smart_ptr_constructor("$ptr_type", select_overload<$ret($args)$const>(&$cpp_name)$optional)""")
|
||||
|
||||
function_template = Template("""
|
||||
.function("$js_name", &$cpp_name)""")
|
||||
|
||||
static_function_template = Template("""
|
||||
.class_function("$js_name", &$cpp_name)""")
|
||||
|
||||
constructor_template = Template("""
|
||||
.constructor<$signature>()""")
|
||||
|
||||
enum_item_template = Template("""
|
||||
.value("$val", $cpp_val)""")
|
||||
|
||||
enum_template = Template("""
|
||||
emscripten::enum_<$cpp_name>("$js_name")$enum_items;
|
||||
""")
|
||||
|
||||
const_template = Template("""
|
||||
constant("$js_name", static_cast<long>($value));
|
||||
""")
|
||||
|
||||
vector_template = Template("""
|
||||
emscripten::register_vector<$cType>("$js_name");
|
||||
""")
|
||||
|
||||
map_template = Template("""
|
||||
emscripten::register_map<cpp_type_key,$cpp_type_val>("$js_name");
|
||||
""")
|
||||
|
||||
class_template = Template("""
|
||||
emscripten::class_<$cpp_name $derivation>("$js_name")$class_templates;
|
||||
""")
|
||||
@@ -0,0 +1,35 @@
|
||||
# OpenCV.js Performance Test
|
||||
|
||||
## Node.js Version
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. node.js, npm: Make sure you have installed these beforehand with the system package manager.
|
||||
|
||||
2. Benchmark.js: Make sure you have installed Benchmark.js by npm before use. Please run `npm install` in the directory `<build_dir>/bin/perf`.
|
||||
|
||||
### How to Use
|
||||
|
||||
For example, if you want to test the performance of cvtColor, please run `perf_cvtcolor.js` by node in terminal:
|
||||
|
||||
```sh
|
||||
node perf_cvtcolor.js
|
||||
```
|
||||
|
||||
All tests of cvtColor will be run by above command.
|
||||
|
||||
If you just want to run one specific case, please use `--test_param_filter="()"` flag, like:
|
||||
|
||||
```sh
|
||||
node perf_cvtcolor.js --test_param_filter="(1920x1080, COLOR_BGR2GRAY)"
|
||||
```
|
||||
|
||||
## Browser Version
|
||||
|
||||
### How to Use
|
||||
|
||||
To run performance tests, please launch a local web server in <build_dir>/bin folder. For example, node http-server which serves on localhost:8080.
|
||||
|
||||
Navigate the web browser to the kernel page you want to test, like http://localhost:8080/perf/imgproc/cvtcolor.html.
|
||||
|
||||
You can input the parameter, and then click the `Run` button to run the specific case, or it will run all the cases.
|
||||
@@ -0,0 +1,38 @@
|
||||
if (typeof window === 'undefined') {
|
||||
var cv = require("../opencv");
|
||||
if (cv instanceof Promise) {
|
||||
loadOpenCV();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
let gCvSize;
|
||||
|
||||
function getCvSize() {
|
||||
if (gCvSize === undefined) {
|
||||
gCvSize = {
|
||||
szODD: new cv.Size(127, 61),
|
||||
szQVGA: new cv.Size(320, 240),
|
||||
szVGA: new cv.Size(640, 480),
|
||||
szSVGA: new cv.Size(800, 600),
|
||||
szqHD: new cv.Size(960, 540),
|
||||
szXGA: new cv.Size(1024, 768),
|
||||
sz720p: new cv.Size(1280, 720),
|
||||
szSXGA: new cv.Size(1280, 1024),
|
||||
sz1080p: new cv.Size(1920, 1080),
|
||||
sz130x60: new cv.Size(130, 60),
|
||||
sz213x120: new cv.Size(120 * 1280 / 720, 120),
|
||||
};
|
||||
}
|
||||
|
||||
return gCvSize;
|
||||
}
|
||||
|
||||
async function loadOpenCV() {
|
||||
cv = await cv;
|
||||
}
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
exports.getCvSize = getCvSize;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "opencv_js_perf",
|
||||
"description": "Performance tests for opencv js bindings",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"benchmark": "latest"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opencv/opencv.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "Apache 2.0 License",
|
||||
"bugs": {
|
||||
"url": "https://github.com/opencv/opencv/issues"
|
||||
},
|
||||
"homepage": "https://github.com/opencv/opencv"
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Functions for 64-bit Perf</h4>
|
||||
<h7>CountnonZero, Mat::dot, Split, Merge</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Mat Shape</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (1000x1000)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../opencv.js" type="text/javascript"></script>
|
||||
<script src="./perf_64bits.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,180 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
} else {
|
||||
runButton.removeAttribute('disabled');
|
||||
runButton.setAttribute('class', 'btn btn-primary');
|
||||
runButton.innerHTML = 'Run';
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
|
||||
function addCountNonZeroCase(suite) {
|
||||
suite.add('countNonZero', function() {
|
||||
cv.countNonZero(mat);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let mat = cv.Mat.eye(size[0], size[1], cv.CV_64F);
|
||||
}, 'teardown': function() {
|
||||
mat.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addMatDotCase(suite) {
|
||||
suite.add('Mat::dot', function() {
|
||||
mat.dot(matT);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let mat = cv.Mat.ones(size[0], size[1], cv.CV_64FC1);
|
||||
let matT = mat.t();
|
||||
}, 'teardown': function() {
|
||||
mat.delete();
|
||||
matT.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addSplitCase(suite) {
|
||||
suite.add('Split', function() {
|
||||
cv.split(mat, planes);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let mat = cv.Mat.ones(size[0], size[1], cv.CV_64FC3);
|
||||
let planes = new cv.MatVector();
|
||||
}, 'teardown': function() {
|
||||
mat.delete();
|
||||
planes.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addMergeCase(suite) {
|
||||
suite.add('Merge', function() {
|
||||
cv.merge(planes, mat);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let mat = new cv.Mat();
|
||||
let mat1 = cv.Mat.ones(size[0], size[1], cv.CV_64FC3);
|
||||
let planes = new cv.MatVector();
|
||||
cv.split(mat1, planes);
|
||||
}, 'teardown': function() {
|
||||
mat.delete();
|
||||
mat1.delete();
|
||||
planes.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setInitParams(suite, sizeArray) {
|
||||
for( let i =0; i < suite.length; i++) {
|
||||
suite[i].params = {
|
||||
size: sizeArray
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function log(message) {
|
||||
console.log(message);
|
||||
if (!isNodeJs) {
|
||||
logElement.innerHTML += `\n${'\t' + message}`;
|
||||
}
|
||||
}
|
||||
|
||||
function setBenchmarkSuite(suite) {
|
||||
suite
|
||||
// add listeners
|
||||
.on('cycle', function(event) {
|
||||
++currentCaseId;
|
||||
let size = event.target.params.size;
|
||||
log(`=== ${event.target.name} ${currentCaseId} ===`);
|
||||
log(`params: (${parseInt(size[0])}x${parseInt(size[1])})`);
|
||||
log('elapsed time:' +String(event.target.times.elapsed*1000)+' ms');
|
||||
log('mean time:' +String(event.target.stats.mean*1000)+' ms');
|
||||
log('stddev time:' +String(event.target.stats.deviation*1000)+' ms');
|
||||
log(String(event.target));
|
||||
})
|
||||
.on('error', function(event) { log(`test case ${event.target.name} failed`); })
|
||||
.on('complete', function(event) {
|
||||
log(`\n ###################################`)
|
||||
log(`Finished testing ${event.currentTarget.length} cases \n`);
|
||||
if (!isNodeJs) {
|
||||
runButton.removeAttribute('disabled');
|
||||
runButton.setAttribute('class', 'btn btn-primary');
|
||||
runButton.innerHTML = 'Run';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
var sizeArray;
|
||||
totalCaseNum = 4;
|
||||
currentCaseId = 0;
|
||||
if (/\([0-9]+x[0-9]+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+\)/g)[0];
|
||||
let sizeStrs = (params.match(/[0-9]+/g) || []).slice(0, 2).toString().split(",");
|
||||
sizeArray = sizeStrs.map(Number);
|
||||
} else {
|
||||
log("no getting invalid params, run all the cases with Mat of shape (1000 x 1000)");
|
||||
sizeArray = [1000, 1000];
|
||||
}
|
||||
addCountNonZeroCase(suite);
|
||||
addMatDotCase(suite);
|
||||
addSplitCase(suite);
|
||||
addMergeCase(suite);
|
||||
setInitParams(suite, sizeArray)
|
||||
setBenchmarkSuite(suite);
|
||||
log(`Running ${totalCaseNum} tests from 64-bit intrinsics`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
|
||||
// set test filter params
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
runButton.setAttribute("disabled", "disabled");
|
||||
runButton.setAttribute('class', 'btn btn-primary disabled');
|
||||
runButton.innerHTML = "Running";
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,310 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if(isNodeJs) {
|
||||
var Base = require("./base");
|
||||
global.getCvSize = Base.getCvSize;
|
||||
}
|
||||
|
||||
var fillGradient = function(cv, img, delta=5) {
|
||||
let ch = img.channels();
|
||||
console.assert(!img.empty() && img.depth() == cv.CV_8U && ch <= 4);
|
||||
|
||||
let n = 255 / delta;
|
||||
for(let r = 0; r < img.rows; ++r) {
|
||||
let kR = r % (2*n);
|
||||
let valR = (kR<=n) ? delta*kR : delta*(2*n-kR);
|
||||
for(let c = 0; c < img.cols; ++c) {
|
||||
let kC = c % (2*n);
|
||||
let valC = (kC<=n) ? delta*kC : delta*(2*n-kC);
|
||||
let vals = [valR, valC, 200*r/img.rows, 255];
|
||||
let p = img.ptr(r, c);
|
||||
for(let i = 0; i < ch; ++i) p[i] = vals[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var smoothBorder = function(cv, img, color, delta=5) {
|
||||
let ch = img.channels();
|
||||
console.assert(!img.empty() && img.depth() == cv.CV_8U && ch <= 4);
|
||||
|
||||
let n = 100/delta;
|
||||
let nR = Math.min(n, (img.rows+1)/2);
|
||||
let nC = Math.min(n, (img.cols+1)/2);
|
||||
let s = new cv.Scalar();
|
||||
|
||||
for (let r = 0; r < nR; r++) {
|
||||
let k1 = r*delta/100.0, k2 = 1-k1;
|
||||
for(let c = 0; c < img.cols; c++) {
|
||||
let view = img.ptr(r, c);
|
||||
for(let i = 0; i < ch; i++) s[i] = view[i];
|
||||
for(let i = 0; i < ch; i++) view[i] = s[i]*k1 + color[i] * k2;
|
||||
}
|
||||
for(let c=0; c < img.cols; c++) {
|
||||
let view = img.ptr(img.rows-r-1, c);
|
||||
for(let i = 0; i < ch; i++) s[i] = view[i];
|
||||
for(let i = 0; i < ch; i++) view[i] = s[i]*k1 + color[i] * k2;
|
||||
}
|
||||
}
|
||||
for (let r = 0; r < img.rows; r++) {
|
||||
for(let c = 0; c < nC; c++) {
|
||||
let k1 = c*delta/100.0, k2 = 1-k1;
|
||||
let view = img.ptr(r, c);
|
||||
for(let i = 0; i < ch; i++) s[i] = view[i];
|
||||
for(let i = 0; i < ch; i++) view[i] = s[i]*k1 + color[i] * k2;
|
||||
}
|
||||
for(let c = 0; c < n; c++) {
|
||||
let k1 = c*delta/100.0, k2 = 1-k1;
|
||||
let view = img.ptr(r, img.cols-c-1);
|
||||
for(let i = 0; i < ch; i++) s[i] = view[i];
|
||||
for(let i = 0; i < ch; i++) view[i] = s[i]*k1 + color[i] * k2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var cvtStr2cvSize = function(strSize) {
|
||||
let size;
|
||||
let cvSize = getCvSize();
|
||||
|
||||
switch(strSize) {
|
||||
case "127,61": size = cvSize.szODD;break;
|
||||
case '320,240': size = cvSize.szQVGA;break;
|
||||
case '640,480': size = cvSize.szVGA;break;
|
||||
case '800,600': size = cvSize.szSVGA;break;
|
||||
case '960,540': size = cvSize.szqHD;break;
|
||||
case '1024,768': size = cvSize.szXGA;break;
|
||||
case '1280,720': size = cvSize.sz720p;break;
|
||||
case '1280,1024': size = cvSize.szSXGA;break;
|
||||
case '1920,1080': size = cvSize.sz1080p;break;
|
||||
case "130,60": size = cvSize.sz130x60;break;
|
||||
case '213,120': size = cvSize.sz213x120;break;
|
||||
default: console.error("unsupported size for this case");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
var combine = function() {
|
||||
let result = [[]];
|
||||
for (let i = 0; i < arguments.length; ++i) {
|
||||
result = permute(result, arguments[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function permute (source, target) {
|
||||
let result = [];
|
||||
for (let i = 0; i < source.length; ++i) {
|
||||
for (let j = 0; j < target.length; ++j) {
|
||||
let tmp = source[i].slice();
|
||||
tmp.push(target[j]);
|
||||
result.push(tmp);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var constructMode = function (startStr, sChannel, dChannel) {
|
||||
let modeList = []
|
||||
for (let j in dChannel) {
|
||||
modeList.push(startStr+sChannel+"2"+dChannel[j])
|
||||
}
|
||||
return modeList;
|
||||
}
|
||||
|
||||
var enableButton = function () {
|
||||
runButton.removeAttribute('disabled');
|
||||
runButton.setAttribute('class', 'btn btn-primary');
|
||||
runButton.innerHTML = 'Run';
|
||||
}
|
||||
|
||||
var disableButton = function () {
|
||||
runButton.setAttribute("disabled", "disabled");
|
||||
runButton.setAttribute('class', 'btn btn-primary disabled');
|
||||
runButton.innerHTML = "Running";
|
||||
}
|
||||
|
||||
var log = function (message) {
|
||||
console.log(message);
|
||||
if (!isNodeJs) {
|
||||
logElement.innerHTML += `\n${'\t' + message}`;
|
||||
}
|
||||
}
|
||||
|
||||
var addKernelCase = function (suite, params, type, kernelFunc) {
|
||||
kernelFunc(suite, type);
|
||||
let index = suite.length - 1;
|
||||
suite[index].params = params;
|
||||
}
|
||||
|
||||
function constructParamLog(params, kernel) {
|
||||
let paramLog = '';
|
||||
if (kernel == "cvtcolor") {
|
||||
let mode = params.mode;
|
||||
let size = params.size;
|
||||
paramLog = `params: (${parseInt(size[0])}x${parseInt(size[1])}, ${mode})`;
|
||||
} else if (kernel == "resize") {
|
||||
let matType = params.matType;
|
||||
let size1 = params.from;
|
||||
let size2 = params.to;
|
||||
paramLog = `params: (${matType},${parseInt(size1.width)}x${parseInt(size1.height)},`+
|
||||
`${parseInt(size2.width)}x${parseInt(size2.height)})`;
|
||||
} else if (kernel == "threshold") {
|
||||
let matSize = params.matSize;
|
||||
let matType = params.matType;
|
||||
let threshType = params.threshType;
|
||||
paramLog = `params: (${parseInt(matSize.width)}x${parseInt(matSize.height)},`+
|
||||
`${matType},${threshType})`;
|
||||
} else if (kernel == "sobel") {
|
||||
let size = params.size;
|
||||
let ddepth = params.ddepth;
|
||||
let dxdy = params.dxdy;
|
||||
let ksize = params.ksize;
|
||||
let borderType = params.borderType;
|
||||
paramLog = `params: (${parseInt(size[0])}x${parseInt(size[1])},`+
|
||||
`${ddepth},${dxdy},${borderType}, ksize:${ksize})`;
|
||||
} else if (kernel == "filter2d") {
|
||||
let size = params.size;
|
||||
let ksize = params.ksize;
|
||||
let borderMode = params.borderMode;
|
||||
paramLog = `params: (${parseInt(size.width)}x${parseInt(size.height)},`+
|
||||
`${ksize},${borderMode})`;
|
||||
} else if (kernel == "scharr") {
|
||||
let size = params.size;
|
||||
let ddepth = params.ddepth;
|
||||
let dxdy = params.dxdy;
|
||||
let borderType = params.borderType;
|
||||
paramLog = `params: (${parseInt(size[0])}x${parseInt(size[1])},`+
|
||||
`${ddepth},${dxdy},${borderType})`;
|
||||
} else if (kernel == "gaussianBlur" || kernel == "blur") {
|
||||
let size = params.size;
|
||||
let matType = params.matType;
|
||||
let borderType = params.borderType;
|
||||
let ksize = params.ksize;
|
||||
paramLog = `params: (${parseInt(size.width)}x${parseInt(size.height)},`+
|
||||
`${matType},${borderType}, ksize: (${ksize}x${ksize}))`;
|
||||
} else if (kernel == "medianBlur") {
|
||||
let size = params.size;
|
||||
let matType = params.matType;
|
||||
let ksize = params.ksize;
|
||||
paramLog = `params: (${parseInt(size.width)}x${parseInt(size.height)},`+
|
||||
`${matType}, ksize: ${ksize})`;
|
||||
} else if (kernel == "erode" || kernel == "dilate" || kernel == "pyrDown") {
|
||||
let size = params.size;
|
||||
let matType = params.matType;
|
||||
paramLog = `params: (${parseInt(size.width)}x${parseInt(size.height)},`+
|
||||
`${matType})`;
|
||||
} else if (kernel == "remap") {
|
||||
let size = params.size;
|
||||
let matType = params.matType;
|
||||
let mapType = params.mapType;
|
||||
let interType = params.interType;
|
||||
paramLog = `params: (${parseInt(size.width)}x${parseInt(size.height)},`+
|
||||
`${matType}, ${mapType}, ${interType})`;
|
||||
} else if (kernel == "warpAffine" || kernel == "warpPerspective") {
|
||||
let size = params.size;
|
||||
let interType = params.interType;
|
||||
let borderMode = params.borderMode;
|
||||
paramLog = `params: (${parseInt(size.width)}x${parseInt(size.height)},`+
|
||||
`${interType}, ${borderMode})`;
|
||||
}
|
||||
return paramLog;
|
||||
}
|
||||
|
||||
var setBenchmarkSuite = function (suite, kernel, currentCaseId) {
|
||||
suite
|
||||
// add listeners
|
||||
.on('cycle', function(event) {
|
||||
++currentCaseId;
|
||||
let params = event.target.params;
|
||||
paramLog = constructParamLog(params, kernel);
|
||||
|
||||
log(`=== ${event.target.name} ${currentCaseId} ===`);
|
||||
log(paramLog);
|
||||
log('elapsed time:' +String(event.target.times.elapsed*1000)+' ms');
|
||||
log('mean time:' +String(event.target.stats.mean*1000)+' ms');
|
||||
log('stddev time:' +String(event.target.stats.deviation*1000)+' ms');
|
||||
log(String(event.target));
|
||||
})
|
||||
.on('error', function(event) { log(`test case ${event.target.name} failed`); })
|
||||
.on('complete', function(event) {
|
||||
log(`\n ###################################`)
|
||||
log(`Finished testing ${event.currentTarget.length} cases \n`);
|
||||
if (!isNodeJs) {
|
||||
runButton.removeAttribute('disabled');
|
||||
runButton.setAttribute('class', 'btn btn-primary');
|
||||
runButton.innerHTML = 'Run';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var decodeParams2Case = function(paramContent, paramsList, combinations) {
|
||||
let sizeString = (paramContent.match(/[0-9]+x[0-9]+/g) || []).toString();
|
||||
let sizes = (sizeString.match(/[0-9]+/g) || []);
|
||||
let paramSize = paramsList.length;
|
||||
let paramObjs = []
|
||||
let sizeCount = 0;
|
||||
for (let i = 0; i < paramSize; i++) {
|
||||
let param = paramsList[i];
|
||||
let paramName = param.name;
|
||||
let paramValue = param.value;
|
||||
let paramReg = param.reg;
|
||||
let paramIndex = param.index;
|
||||
|
||||
if(paramValue != "") {
|
||||
paramObjs.push({name: paramName, value: paramValue, index: paramIndex});
|
||||
} else if (paramName.startsWith('size')) {
|
||||
let sizeStr = sizes.slice(sizeCount, sizeCount+2).toString();
|
||||
paramValue = cvtStr2cvSize(sizeStr);
|
||||
sizeCount += 2;
|
||||
paramObjs.push({name: paramName, value: paramValue, index: paramIndex});
|
||||
} else {
|
||||
for (let index in paramReg) {
|
||||
let reg = eval(paramReg[index]);
|
||||
if ('loc' in param) {
|
||||
paramValue = (paramContent.match(reg) || [])[param.loc].toString();
|
||||
} else {
|
||||
paramValue = (paramContent.match(reg) || []).toString();
|
||||
}
|
||||
|
||||
if (paramValue != "") {
|
||||
paramObjs.push({name: paramName, value: paramValue, index: paramIndex});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let location = [];
|
||||
for (let i = 0; i < combinations.length; ++i) {
|
||||
let combination = combinations[i];
|
||||
for (let j = 0; j < combination.length; ++j) {
|
||||
if (judgeCombin(combination[j], paramObjs)) {
|
||||
location.push([i,j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
function judgeCombin(combination, paramObjs) {
|
||||
for (let i =0; i < paramObjs.length; i++) {
|
||||
if (paramObjs[i].value != combination[paramObjs[i].index]){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
exports.enableButton = enableButton;
|
||||
exports.disableButton = disableButton;
|
||||
exports.fillGradient = fillGradient;
|
||||
exports.smoothBorder = smoothBorder;
|
||||
exports.cvtStr2cvSize = cvtStr2cvSize;
|
||||
exports.combine = combine;
|
||||
exports.constructMode = constructMode;
|
||||
exports.log = log;
|
||||
exports.decodeParams2Case = decodeParams2Case;
|
||||
exports.setBenchmarkSuite = setBenchmarkSuite;
|
||||
exports.addKernelCase = addKernelCase;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Blur</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (1280x720, CV_8UC1, BORDER_REPLICATE)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_blur.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,133 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const BlurSize = [cvSize.szODD, cvSize.szQVGA, cvSize.szVGA, cvSize.sz720p];
|
||||
const Blur5x16Size = [cvSize.szVGA, cvSize.sz720p];
|
||||
const BlurType = ["CV_8UC1", "CV_8UC4", "CV_16UC1", "CV_16SC1", "CV_32FC1"];
|
||||
const BlurType5x5 = ["CV_8UC1", "CV_8UC4", "CV_16UC1", "CV_16SC1", "CV_32FC1", "CV_32FC3"];
|
||||
const BorderType3x3 = ["BORDER_REPLICATE", "BORDER_CONSTANT"];
|
||||
const BorderTypeAll = ["BORDER_REPLICATE", "BORDER_CONSTANT", "BORDER_REFLECT", "BORDER_REFLECT101"];
|
||||
|
||||
const combiBlur3x3 = combine(BlurSize, BlurType, BorderType3x3);
|
||||
const combiBlur16x16 = combine(Blur5x16Size, BlurType, BorderTypeAll);
|
||||
const combiBlur5x5 = combine(Blur5x16Size, BlurType5x5, BorderTypeAll);
|
||||
|
||||
function addBlurCase(suite, type) {
|
||||
suite.add('blur', function() {
|
||||
cv.blur(src, dst, ksize, new cv.Point(-1,-1), borderType);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let matType = cv[this.params.matType];
|
||||
let borderType = cv[this.params.borderType];
|
||||
let ksizeNum = this.params.ksize;
|
||||
let ksize = new cv.Size(ksizeNum, ksizeNum);
|
||||
let src = new cv.Mat(size, matType);
|
||||
let dst = new cv.Mat(size, matType);
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addBlurModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let matType = combination[i][1];
|
||||
let borderType = combination[i][2];
|
||||
let ksizeArray = [3, 16, 5];
|
||||
|
||||
let params = {size: size, matType:matType, ksize: ksizeArray[type], borderType:borderType};
|
||||
addKernelCase(suite, params, type, addBlurCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*BORDER\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*BORDER\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[FSUfsu]C[0-9]/"], index:1});
|
||||
paramObjs.push({name:"borderMode", value: "", reg:["/BORDER\_\\w+/"], index:2});
|
||||
let locationList = decodeParams2Case(params, paramObjs,blurCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addBlurModeCase(suite, [blurCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addBlurModeCase(suite, combiBlur3x3, 0);
|
||||
addBlurModeCase(suite, combiBlur16x16, 1);
|
||||
addBlurModeCase(suite, combiBlur5x5, 2);
|
||||
}
|
||||
setBenchmarkSuite(suite, "blur", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from blur`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let blurCombinations = [combiBlur3x3, combiBlur16x16, combiBlur5x5];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*BORDER\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*BORDER\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>CvtColor</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (640x480,COLOR_RGBA2GRAY)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_cvtcolor.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,414 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.constructMode = HelpFunc.constructMode;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
// extra color conversions supported implicitly
|
||||
{
|
||||
cv.CX_BGRA2HLS = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2HLS,
|
||||
cv.CX_BGRA2HLS_FULL = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2HLS_FULL,
|
||||
cv.CX_BGRA2HSV = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2HSV,
|
||||
cv.CX_BGRA2HSV_FULL = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2HSV_FULL,
|
||||
cv.CX_BGRA2Lab = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2Lab,
|
||||
cv.CX_BGRA2Luv = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2Luv,
|
||||
cv.CX_BGRA2XYZ = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2XYZ,
|
||||
cv.CX_BGRA2YCrCb = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2YCrCb,
|
||||
cv.CX_BGRA2YUV = cv.COLOR_COLORCVT_MAX + cv.COLOR_BGR2YUV,
|
||||
cv.CX_HLS2BGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_HLS2BGR,
|
||||
cv.CX_HLS2BGRA_FULL = cv.COLOR_COLORCVT_MAX + cv.COLOR_HLS2BGR_FULL,
|
||||
cv.CX_HLS2RGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_HLS2RGB,
|
||||
cv.CX_HLS2RGBA_FULL = cv.COLOR_COLORCVT_MAX + cv.COLOR_HLS2RGB_FULL,
|
||||
cv.CX_HSV2BGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_HSV2BGR,
|
||||
cv.CX_HSV2BGRA_FULL = cv.COLOR_COLORCVT_MAX + cv.COLOR_HSV2BGR_FULL,
|
||||
cv.CX_HSV2RGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_HSV2RGB,
|
||||
cv.CX_HSV2RGBA_FULL = cv.COLOR_COLORCVT_MAX + cv.COLOR_HSV2RGB_FULL,
|
||||
cv.CX_Lab2BGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_Lab2BGR,
|
||||
cv.CX_Lab2LBGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_Lab2LBGR,
|
||||
cv.CX_Lab2LRGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_Lab2LRGB,
|
||||
cv.CX_Lab2RGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_Lab2RGB,
|
||||
cv.CX_LBGRA2Lab = cv.COLOR_COLORCVT_MAX + cv.COLOR_LBGR2Lab,
|
||||
cv.CX_LBGRA2Luv = cv.COLOR_COLORCVT_MAX + cv.COLOR_LBGR2Luv,
|
||||
cv.CX_LRGBA2Lab = cv.COLOR_COLORCVT_MAX + cv.COLOR_LRGB2Lab,
|
||||
cv.CX_LRGBA2Luv = cv.COLOR_COLORCVT_MAX + cv.COLOR_LRGB2Luv,
|
||||
cv.CX_Luv2BGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_Luv2BGR,
|
||||
cv.CX_Luv2LBGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_Luv2LBGR,
|
||||
cv.CX_Luv2LRGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_Luv2LRGB,
|
||||
cv.CX_Luv2RGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_Luv2RGB,
|
||||
cv.CX_RGBA2HLS = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2HLS,
|
||||
cv.CX_RGBA2HLS_FULL = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2HLS_FULL,
|
||||
cv.CX_RGBA2HSV = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2HSV,
|
||||
cv.CX_RGBA2HSV_FULL = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2HSV_FULL,
|
||||
cv.CX_RGBA2Lab = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2Lab,
|
||||
cv.CX_RGBA2Luv = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2Luv,
|
||||
cv.CX_RGBA2XYZ = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2XYZ,
|
||||
cv.CX_RGBA2YCrCb = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2YCrCb,
|
||||
cv.CX_RGBA2YUV = cv.COLOR_COLORCVT_MAX + cv.COLOR_RGB2YUV,
|
||||
cv.CX_XYZ2BGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_XYZ2BGR,
|
||||
cv.CX_XYZ2RGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_XYZ2RGB,
|
||||
cv.CX_YCrCb2BGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_YCrCb2BGR,
|
||||
cv.CX_YCrCb2RGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_YCrCb2RGB,
|
||||
cv.CX_YUV2BGRA = cv.COLOR_COLORCVT_MAX + cv.COLOR_YUV2BGR,
|
||||
cv.CX_YUV2RGBA = cv.COLOR_COLORCVT_MAX + cv.COLOR_YUV2RGB
|
||||
};
|
||||
|
||||
// didn't support 16u and 32f perf tests according to
|
||||
// https://github.com/opencv/opencv/commit/4e679e1cc5b075ec006b29a58b4fe117523fba1d
|
||||
function constructCvtMode16U() {
|
||||
let cvtMode16U = [];
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("COLOR_", "BGR", ["BGRA", "GRAY", "RGB", "RGBA", "XYZ", "YCrCb", "YUV"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("COLOR_", "BGRA", ["BGR", "GRAY", "RGBA"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("CX_", "BGRA", ["XYZ", "YCrCb", "YUV"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("COLOR_", "GRAY", ["BGR", "BGRA"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("COLOR_", "RGB", ["GRAY", "XYZ", "YCrCb", "YUV"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("COLOR_", "RGBA", ["BGR", "GRAY"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("CX_", "RGBA", ["XYZ", "YCrCb", "YUV"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("COLOR_", "XYZ", ["BGR", "RGB"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("CX_", "XYZ", ["BGRA", "RGBA"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("COLOR_", "YCrCb", ["BGR", "RGB"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("CX_", "YCrCb", ["BGRA", "RGBA"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("COLOR_", "YUV", ["BGR", "RGB"]));
|
||||
cvtMode16U = cvtMode16U.concat(constructMode("CX_", "YUV", ["BGRA", "RGBA"]));
|
||||
|
||||
return cvtMode16U;
|
||||
}
|
||||
|
||||
const CvtMode16U = constructCvtMode16U();
|
||||
|
||||
const CvtMode16USize = [cvSize.szODD, cvSize.szVGA, cvSize.sz1080p];
|
||||
const combiCvtMode16U = combine(CvtMode16USize, CvtMode16U);
|
||||
|
||||
function constructCvtMode32F(source) {
|
||||
let cvtMode32F = source;
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("COLOR_", "BGR", ["HLS", "HLS_FULL", "HSV", "HSV_FULL", "Lab", "Luv"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("CX_", "BGRA", ["HLS", "HLS_FULL", "HSV", "HSV_FULL", "Lab", "Luv"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("COLOR_", "HLS", ["BGR", "BGR_FULL", "RGB", "RGB_FULL"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("CX_", "HLS", ["BGRA", "BGRA_FULL", "RGBA", "RGBA_FULL"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("COLOR_", "HSV", ["BGR", "BGR_FULL", "RGB", "RGB_FULL"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("CX_", "HSV", ["BGRA", "BGRA_FULL", "RGBA", "RGBA_FULL"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("COLOR_", "Lab", ["BGR", "LBGR", "RGB", "LRGB"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("CX_", "Lab", ["BGRA", "LBGRA", "RGBA", "LRGBA"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("COLOR_", "Luv", ["BGR", "LBGR", "RGB", "LRGB"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("CX_", "Luv", ["BGRA", "LBGRA", "RGBA", "LRGBA"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("COLOR_", "LBGR", ["Lab", "Luv"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("CX_", "LBGRA", ["Lab", "Luv"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("COLOR_", "LRGB", ["Lab", "Luv"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("CX_", "LRGBA", ["Lab", "Luv"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("COLOR_", "RGB", ["HLS", "HLS_FULL", "HSV", "HSV_FULL", "Lab", "Luv"]));
|
||||
cvtMode32F = cvtMode32F.concat(constructMode("CX_", "RGBA", ["HLS", "HLS_FULL", "HSV", "HSV_FULL", "Lab", "Luv"]));
|
||||
|
||||
return cvtMode32F;
|
||||
}
|
||||
|
||||
const CvtMode32F = constructCvtMode32F(CvtMode16U);
|
||||
|
||||
const CvtMode32FSize = [cvSize.szODD, cvSize.szVGA, cvSize.sz1080p];
|
||||
const combiCvtMode32F = combine(CvtMode32FSize, CvtMode32F);
|
||||
|
||||
function constructeCvtMode(source) {
|
||||
let cvtMode = source
|
||||
cvtMode = cvtMode.concat(constructMode("COLOR_", "BGR", ["BGR555", "BGR565"]));
|
||||
cvtMode = cvtMode.concat(constructMode("COLOR_", "BGR555", ["BGR", "BGRA", "GRAY", "RGB", "RGBA"]));
|
||||
cvtMode = cvtMode.concat(constructMode("COLOR_", "BGR565", ["BGR", "BGRA", "GRAY", "RGB", "RGBA"]));
|
||||
cvtMode = cvtMode.concat(constructMode("COLOR_", "BGRA", ["BGR555", "BGR565"]));
|
||||
cvtMode = cvtMode.concat(constructMode("COLOR_", "GRAY", ["BGR555", "BGR565"]));
|
||||
cvtMode = cvtMode.concat(constructMode("COLOR_", "RGB", ["BGR555", "BGR565"]));
|
||||
cvtMode = cvtMode.concat(constructMode("COLOR_", "RGBA", ["BGR555", "BGR565"]));
|
||||
|
||||
return cvtMode;
|
||||
}
|
||||
|
||||
const CvtMode = constructeCvtMode(CvtMode32F);
|
||||
|
||||
const CvtModeSize = [cvSize.szODD, cvSize.szVGA, cvSize.sz1080p];
|
||||
// combiCvtMode permute size and mode
|
||||
const combiCvtMode = combine(CvtModeSize, CvtMode);
|
||||
|
||||
const CvtModeBayer = [
|
||||
"COLOR_BayerBG2BGR", "COLOR_BayerBG2BGRA", "COLOR_BayerBG2BGR_VNG", "COLOR_BayerBG2GRAY",
|
||||
"COLOR_BayerGB2BGR", "COLOR_BayerGB2BGRA", "COLOR_BayerGB2BGR_VNG", "COLOR_BayerGB2GRAY",
|
||||
"COLOR_BayerGR2BGR", "COLOR_BayerGR2BGRA", "COLOR_BayerGR2BGR_VNG", "COLOR_BayerGR2GRAY",
|
||||
"COLOR_BayerRG2BGR", "COLOR_BayerRG2BGRA", "COLOR_BayerRG2BGR_VNG", "COLOR_BayerRG2GRAY"
|
||||
];
|
||||
const CvtModeBayerSize = [cvSize.szODD, cvSize.szVGA];
|
||||
const combiCvtModeBayer = combine(CvtModeBayerSize, CvtModeBayer);
|
||||
|
||||
|
||||
const CvtMode2 = [
|
||||
"COLOR_YUV2BGR_NV12", "COLOR_YUV2BGRA_NV12", "COLOR_YUV2RGB_NV12", "COLOR_YUV2RGBA_NV12", "COLOR_YUV2BGR_NV21", "COLOR_YUV2BGRA_NV21", "COLOR_YUV2RGB_NV21", "COLOR_YUV2RGBA_NV21",
|
||||
"COLOR_YUV2BGR_YV12", "COLOR_YUV2BGRA_YV12", "COLOR_YUV2RGB_YV12", "COLOR_YUV2RGBA_YV12", "COLOR_YUV2BGR_IYUV", "COLOR_YUV2BGRA_IYUV", "COLOR_YUV2RGB_IYUV", "COLOR_YUV2RGBA_IYUV",
|
||||
"COLOR_YUV2GRAY_420", "COLOR_YUV2RGB_UYVY", "COLOR_YUV2BGR_UYVY", "COLOR_YUV2RGBA_UYVY", "COLOR_YUV2BGRA_UYVY", "COLOR_YUV2RGB_YUY2", "COLOR_YUV2BGR_YUY2", "COLOR_YUV2RGB_YVYU",
|
||||
"COLOR_YUV2BGR_YVYU", "COLOR_YUV2RGBA_YUY2", "COLOR_YUV2BGRA_YUY2", "COLOR_YUV2RGBA_YVYU", "COLOR_YUV2BGRA_YVYU"
|
||||
];
|
||||
const CvtMode2Size = [cvSize.szVGA, cvSize.sz1080p, cvSize.sz130x60];
|
||||
const combiCvtMode2 = combine(CvtMode2Size, CvtMode2);
|
||||
|
||||
const CvtMode3 = [
|
||||
"COLOR_RGB2YUV_IYUV", "COLOR_BGR2YUV_IYUV", "COLOR_RGBA2YUV_IYUV", "COLOR_BGRA2YUV_IYUV",
|
||||
"COLOR_RGB2YUV_YV12", "COLOR_BGR2YUV_YV12", "COLOR_RGBA2YUV_YV12", "COLOR_BGRA2YUV_YV12"
|
||||
];
|
||||
const CvtMode3Size = [cvSize.szVGA, cvSize.sz720p, cvSize.sz1080p, cvSize.sz130x60];
|
||||
const combiCvtMode3 = combine(CvtMode3Size, CvtMode3);
|
||||
|
||||
const EdgeAwareBayerMode = [
|
||||
"COLOR_BayerBG2BGR_EA", "COLOR_BayerGB2BGR_EA", "COLOR_BayerRG2BGR_EA", "COLOR_BayerGR2BGR_EA"
|
||||
];
|
||||
const EdgeAwareBayerModeSize = [cvSize.szVGA, cvSize.sz720p, cvSize.sz1080p, cvSize.sz130x60];
|
||||
const combiEdgeAwareBayer = combine(EdgeAwareBayerModeSize, EdgeAwareBayerMode);
|
||||
|
||||
// This function returns an array. The 1st element is the channel number of
|
||||
// source mat and 2nd element is the channel number of destination mat.
|
||||
function getConversionInfo(cvtMode) {
|
||||
switch(cvtMode) {
|
||||
case "COLOR_BayerBG2GRAY": case "COLOR_BayerGB2GRAY":
|
||||
case "COLOR_BayerGR2GRAY": case "COLOR_BayerRG2GRAY":
|
||||
case "COLOR_YUV2GRAY_420":
|
||||
return [1, 1];
|
||||
case "COLOR_GRAY2BGR555": case "COLOR_GRAY2BGR565":
|
||||
return [1, 2];
|
||||
case "COLOR_BayerBG2BGR": case "COLOR_BayerBG2BGR_VNG":
|
||||
case "COLOR_BayerGB2BGR": case "COLOR_BayerGB2BGR_VNG":
|
||||
case "COLOR_BayerGR2BGR": case "COLOR_BayerGR2BGR_VNG":
|
||||
case "COLOR_BayerRG2BGR": case "COLOR_BayerRG2BGR_VNG":
|
||||
case "COLOR_GRAY2BGR":
|
||||
case "COLOR_YUV2BGR_NV12": case "COLOR_YUV2RGB_NV12":
|
||||
case "COLOR_YUV2BGR_NV21": case "COLOR_YUV2RGB_NV21":
|
||||
case "COLOR_YUV2BGR_YV12": case "COLOR_YUV2RGB_YV12":
|
||||
case "COLOR_YUV2BGR_IYUV": case "COLOR_YUV2RGB_IYUV":
|
||||
return [1, 3];
|
||||
case "COLOR_GRAY2BGRA":
|
||||
case "COLOR_YUV2BGRA_NV12": case "COLOR_YUV2RGBA_NV12":
|
||||
case "COLOR_YUV2BGRA_NV21": case "COLOR_YUV2RGBA_NV21":
|
||||
case "COLOR_YUV2BGRA_YV12": case "COLOR_YUV2RGBA_YV12":
|
||||
case "COLOR_YUV2BGRA_IYUV": case "COLOR_YUV2RGBA_IYUV":
|
||||
case "COLOR_BayerBG2BGRA": case "COLOR_BayerGB2BGRA":
|
||||
case "COLOR_BayerGR2BGRA": case "COLOR_BayerRG2BGRA":
|
||||
return [1, 4];
|
||||
case "COLOR_BGR5552GRAY": case "COLOR_BGR5652GRAY":
|
||||
return [2, 1];
|
||||
case "COLOR_BGR5552BGR": case "COLOR_BGR5552RGB":
|
||||
case "COLOR_BGR5652BGR": case "COLOR_BGR5652RGB":
|
||||
case "COLOR_YUV2RGB_UYVY": case "COLOR_YUV2BGR_UYVY":
|
||||
case "COLOR_YUV2RGB_YUY2": case "COLOR_YUV2BGR_YUY2":
|
||||
case "COLOR_YUV2RGB_YVYU": case "COLOR_YUV2BGR_YVYU":
|
||||
return [2, 3];
|
||||
case "COLOR_BGR5552BGRA": case "COLOR_BGR5552RGBA":
|
||||
case "COLOR_BGR5652BGRA": case "COLOR_BGR5652RGBA":
|
||||
case "COLOR_YUV2RGBA_UYVY": case "COLOR_YUV2BGRA_UYVY":
|
||||
case "COLOR_YUV2RGBA_YUY2": case "COLOR_YUV2BGRA_YUY2":
|
||||
case "COLOR_YUV2RGBA_YVYU": case "COLOR_YUV2BGRA_YVYU":
|
||||
return [2, 4];
|
||||
case "COLOR_BGR2GRAY": case "COLOR_RGB2GRAY":
|
||||
case "COLOR_RGB2YUV_IYUV": case "COLOR_RGB2YUV_YV12":
|
||||
case "COLOR_BGR2YUV_IYUV": case "COLOR_BGR2YUV_YV12":
|
||||
return [3, 1];
|
||||
case "COLOR_BGR2BGR555": case "COLOR_BGR2BGR565":
|
||||
case "COLOR_RGB2BGR555": case "COLOR_RGB2BGR565":
|
||||
return [3, 2];
|
||||
case "COLOR_BGR2HLS": case "COLOR_BGR2HLS_FULL":
|
||||
case "COLOR_BGR2HSV": case "COLOR_BGR2HSV_FULL":
|
||||
case "COLOR_BGR2Lab": case "COLOR_BGR2Luv":
|
||||
case "COLOR_BGR2RGB": case "COLOR_BGR2XYZ":
|
||||
case "COLOR_BGR2YCrCb": case "COLOR_BGR2YUV":
|
||||
case "COLOR_HLS2BGR": case "COLOR_HLS2BGR_FULL":
|
||||
case "COLOR_HLS2RGB": case "COLOR_HLS2RGB_FULL":
|
||||
case "COLOR_HSV2BGR": case "COLOR_HSV2BGR_FULL":
|
||||
case "COLOR_HSV2RGB": case "COLOR_HSV2RGB_FULL":
|
||||
case "COLOR_Lab2BGR": case "COLOR_Lab2LBGR":
|
||||
case "COLOR_Lab2LRGB": case "COLOR_Lab2RGB":
|
||||
case "COLOR_LBGR2Lab": case "COLOR_LBGR2Luv":
|
||||
case "COLOR_LRGB2Lab": case "COLOR_LRGB2Luv":
|
||||
case "COLOR_Luv2BGR": case "COLOR_Luv2LBGR":
|
||||
case "COLOR_Luv2LRGB": case "COLOR_Luv2RGB":
|
||||
case "COLOR_RGB2HLS": case "COLOR_RGB2HLS_FULL":
|
||||
case "COLOR_RGB2HSV": case "COLOR_RGB2HSV_FULL":
|
||||
case "COLOR_RGB2Lab": case "COLOR_RGB2Luv":
|
||||
case "COLOR_RGB2XYZ": case "COLOR_RGB2YCrCb":
|
||||
case "COLOR_RGB2YUV": case "COLOR_XYZ2BGR":
|
||||
case "COLOR_XYZ2RGB": case "COLOR_YCrCb2BGR":
|
||||
case "COLOR_YCrCb2RGB": case "COLOR_YUV2BGR":
|
||||
case "COLOR_YUV2RGB":
|
||||
return [3, 3];
|
||||
case "COLOR_BGR2BGRA": case "COLOR_BGR2RGBA":
|
||||
case "CX_HLS2BGRA": case "CX_HLS2BGRA_FULL":
|
||||
case "CX_HLS2RGBA": case "CX_HLS2RGBA_FULL":
|
||||
case "CX_HSV2BGRA": case "CX_HSV2BGRA_FULL":
|
||||
case "CX_HSV2RGBA": case "CX_HSV2RGBA_FULL":
|
||||
case "CX_Lab2BGRA": case "CX_Lab2LBGRA":
|
||||
case "CX_Lab2LRGBA": case "CX_Lab2RGBA":
|
||||
case "CX_Luv2BGRA": case "CX_Luv2LBGRA":
|
||||
case "CX_Luv2LRGBA": case "CX_Luv2RGBA":
|
||||
case "CX_XYZ2BGRA": case "CX_XYZ2RGBA":
|
||||
case "CX_YCrCb2BGRA": case "CX_YCrCb2RGBA":
|
||||
case "CX_YUV2BGRA": case "CX_YUV2RGBA":
|
||||
return [3, 4];
|
||||
case "COLOR_BGRA2GRAY": case "COLOR_RGBA2GRAY":
|
||||
case "COLOR_RGBA2YUV_IYUV": case "COLOR_RGBA2YUV_YV12":
|
||||
case "COLOR_BGRA2YUV_IYUV": case "COLOR_BGRA2YUV_YV12":
|
||||
return [4, 1];
|
||||
case "COLOR_BGRA2BGR555": case "COLOR_BGRA2BGR565":
|
||||
case "COLOR_RGBA2BGR555": case "COLOR_RGBA2BGR565":
|
||||
return [4, 2];
|
||||
case "COLOR_BGRA2BGR": case "CX_BGRA2HLS":
|
||||
case "CX_BGRA2HLS_FULL": case "CX_BGRA2HSV":
|
||||
case "CX_BGRA2HSV_FULL": case "CX_BGRA2Lab":
|
||||
case "CX_BGRA2Luv": case "CX_BGRA2XYZ":
|
||||
case "CX_BGRA2YCrCb": case "CX_BGRA2YUV":
|
||||
case "CX_LBGRA2Lab": case "CX_LBGRA2Luv":
|
||||
case "CX_LRGBA2Lab": case "CX_LRGBA2Luv":
|
||||
case "COLOR_RGBA2BGR": case "CX_RGBA2HLS":
|
||||
case "CX_RGBA2HLS_FULL": case "CX_RGBA2HSV":
|
||||
case "CX_RGBA2HSV_FULL": case "CX_RGBA2Lab":
|
||||
case "CX_RGBA2Luv": case "CX_RGBA2XYZ":
|
||||
case "CX_RGBA2YCrCb": case "CX_RGBA2YUV":
|
||||
return [4, 3];
|
||||
case "COLOR_BGRA2RGBA":
|
||||
return [4, 4];
|
||||
default:
|
||||
console.error("Unknown conversion type");
|
||||
break;
|
||||
};
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
function getMatType(chPair) {
|
||||
let dataType = "8U"; // now just support "8U" data type, we can set it as a param to extend the data type later.
|
||||
let mat1Type, mat2Type;
|
||||
if (chPair[0] === 0) {
|
||||
mat1Type = `CV_${dataType}C`;
|
||||
} else {
|
||||
mat1Type = `CV_${dataType}C${chPair[0].toString()}`;
|
||||
}
|
||||
if (chPair[1] === 0) {
|
||||
mat2Type = `CV_${dataType}C`;
|
||||
} else {
|
||||
mat2Type = `CV_${dataType}C${chPair[1].toString()}`;
|
||||
}
|
||||
return [mat1Type, mat2Type];
|
||||
}
|
||||
|
||||
function addCvtColorCase(suite, type) {
|
||||
suite.add('cvtColor', function() {
|
||||
cv.cvtColor(mat1, mat2, mode, 0);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let matType = this.params.matType;
|
||||
let mode = cv[this.params.mode]%cv.COLOR_COLORCVT_MAX;
|
||||
let mat1 = new cv.Mat(size[1], size[0], cv[matType[0]]);
|
||||
let mat2 = new cv.Mat(size[1], size[0], cv[matType[1]]);
|
||||
},
|
||||
'teardown': function() {
|
||||
mat1.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addCvtModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for(let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let mode = combination[i][1];
|
||||
let chPair = getConversionInfo(mode);
|
||||
let matType = getMatType(chPair);
|
||||
let sizeArray;
|
||||
if (type == 0) {
|
||||
sizeArray = [size.width, size.height];
|
||||
} else {
|
||||
sizeArray = [size.width, size.height+size.height/2];
|
||||
}
|
||||
let params = {size:sizeArray, matType: matType, mode: mode};
|
||||
addKernelCase(suite, params, type, addCvtColorCase);
|
||||
};
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"mode", value:"", reg:["/CX\_[A-z]+2[A-z]+/", "/COLOR\_[A-z]+2[A-z]+/"], index:1});
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
|
||||
let locationList = decodeParams2Case(params, paramObjs,combinations);
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
if (first < 2) {
|
||||
addCvtModeCase(suite, [combinations[first][second]], 0);
|
||||
} else {
|
||||
addCvtModeCase(suite, [combinations[first][second]], 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addCvtModeCase(suite, combiCvtMode, 0);
|
||||
addCvtModeCase(suite, combiCvtModeBayer, 0);
|
||||
addCvtModeCase(suite, combiCvtMode2, 1);
|
||||
addCvtModeCase(suite, combiCvtMode3, 1);
|
||||
}
|
||||
setBenchmarkSuite(suite, "cvtcolor", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from CvtColor`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
// init
|
||||
let combinations = [combiCvtMode, combiCvtModeBayer, combiCvtMode2, combiCvtMode3];//, combiEdgeAwareBayer];
|
||||
|
||||
// set test filter params
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Dilate</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (1024x768, CV_8UC1)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_dilate.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,120 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const DilateSize = [cvSize.szQVGA, cvSize.szVGA, cvSize.szSVGA, cvSize.szXGA, cvSize.szSXGA];
|
||||
const DilateType = ["CV_8UC1", "CV_8UC4"];
|
||||
const combiDilate = combine(DilateSize, DilateType);
|
||||
|
||||
function addDialteCase(suite, type) {
|
||||
suite.add('dilate', function() {
|
||||
cv.dilate(src, dst, kernel);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let matType = cv[this.params.matType];
|
||||
let src = new cv.Mat(size, matType);
|
||||
let dst = new cv.Mat(size, matType);
|
||||
let kernel = new cv.Mat();
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
kernel.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addDilateModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let matType = combination[i][1];
|
||||
|
||||
let params = {size: size, matType:matType};
|
||||
addKernelCase(suite, params, type, addDialteCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[FSUfsu]C[0-9]/"], index:1});
|
||||
let locationList = decodeParams2Case(params, paramObjs, dilateCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addDilateModeCase(suite, [dilateCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addDilateModeCase(suite, combiDilate, 0);
|
||||
}
|
||||
setBenchmarkSuite(suite, "dilate", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from dilate`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let dilateCombinations = [combiDilate];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Erode</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (1024x768, CV_8UC1)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_erode.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,120 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const ErodeSize = [cvSize.szQVGA, cvSize.szVGA, cvSize.szSVGA, cvSize.szXGA, cvSize.szSXGA];
|
||||
const ErodeType = ["CV_8UC1", "CV_8UC4"];
|
||||
const combiErode = combine(ErodeSize, ErodeType);
|
||||
|
||||
function addErodeCase(suite, type) {
|
||||
suite.add('erode', function() {
|
||||
cv.erode(src, dst, kernel);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let matType = cv[this.params.matType];
|
||||
let src = new cv.Mat(size, matType);
|
||||
let dst = new cv.Mat(size, matType);
|
||||
let kernel = new cv.Mat();
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
kernel.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addErodeModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let matType = combination[i][1];
|
||||
|
||||
let params = {size: size, matType:matType};
|
||||
addKernelCase(suite, params, type, addErodeCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[FSUfsu]C[0-9]/"], index:1});
|
||||
let locationList = decodeParams2Case(params, paramObjs, erodeCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addErodeModeCase(suite, [erodeCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addErodeModeCase(suite, combiErode, 0);
|
||||
}
|
||||
setBenchmarkSuite(suite, "erode", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from erode`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let erodeCombinations = [combiErode];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Filter2D</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (320x240, 3, BORDER_CONSTANT)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_filter2D.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,130 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const Filter2dSize = [cvSize.szQVGA, cvSize.sz1080p];
|
||||
const Filter2dKsize = ["3", "5"];
|
||||
const Filter2dBorderMode = ["BORDER_CONSTANT", "BORDER_REPLICATE", "BORDER_REFLECT_101"];
|
||||
const DISABLED_Filter2dBorderMode = ["BORDER_CONSTANT", "BORDER_REPLICATE"];
|
||||
const combiFilter2dCase = combine(Filter2dSize, Filter2dKsize, Filter2dBorderMode);
|
||||
const combiDISABLEDFilter2dCase = combine(Filter2dSize, Filter2dKsize, DISABLED_Filter2dBorderMode);
|
||||
|
||||
function addFilter2dCase(suite, type) {
|
||||
suite.add('filter2d', function() {
|
||||
cv.filter2D(src, dst, cv.CV_8UC4, kernel, new cv.Point(1, 1), 0.0, borderMode);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let ksize = parseInt(this.params.ksize);
|
||||
let borderMode = cv[this.params.borderMode];
|
||||
|
||||
let src = new cv.Mat(size, cv.CV_8UC4);
|
||||
let dst = new cv.Mat(size, cv.CV_8UC4);
|
||||
let kernelElement = [];
|
||||
for (let i = 0; i < ksize*ksize; i++) {
|
||||
let randNum = Math.random();
|
||||
kernelElement.push(-3.0+randNum*13.0);
|
||||
}
|
||||
let kernel = cv.matFromArray(ksize, ksize, cv.CV_32FC1, kernelElement);
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addFilter2dModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let ksize = combination[i][1];
|
||||
let borderMode = combination[i][2];
|
||||
let params = {size: size, ksize: ksize, borderMode:borderMode};
|
||||
addKernelCase(suite, params, type, addFilter2dCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*[0-9],[\ ]*BORDER\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*[0-9],[\ ]*BORDER\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"ksize", value:"", reg:["/\\b[0-9]\\b/"], index:1});
|
||||
paramObjs.push({name:"borderMode", value: "", reg:["/BORDER\_\\w+/"], index:2});
|
||||
let locationList = decodeParams2Case(params, paramObjs,filter2dCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addFilter2dModeCase(suite, [filter2dCombinations[first][second]], 0);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addFilter2dModeCase(suite, combiFilter2dCase, 0);
|
||||
}
|
||||
setBenchmarkSuite(suite, "filter2d", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from Filter2d`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let filter2dCombinations = [combiFilter2dCase];//,combiDISABLEDFilter2dCase];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*[0-9],[\ ]*BORDER\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*[0-9],[\ ]*BORDER\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>gaussianBlur</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (1280x720, CV_8UC1, BORDER_REPLICATE)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_gaussianBlur.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,129 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const GaussianBlurSize = [cvSize.szODD, cvSize.szQVGA, cvSize.szVGA, cvSize.sz720p];
|
||||
const GaussianBlurType = ["CV_8UC1", "CV_8UC4", "CV_16UC1", "CV_16SC1", "CV_32FC1"];
|
||||
const BorderType3x3 = ["BORDER_REPLICATE", "BORDER_CONSTANT"];
|
||||
const BorderType3x3ROI = ["BORDER_REPLICATE", "BORDER_CONSTANT", "BORDER_REFLECT", "BORDER_REFLECT101"];
|
||||
|
||||
const combiGaussianBlurBorder3x3 = combine(GaussianBlurSize, GaussianBlurType, BorderType3x3);
|
||||
const combiGaussianBlurBorder3x3ROI = combine(GaussianBlurSize, GaussianBlurType, BorderType3x3ROI);
|
||||
|
||||
function addGaussianBlurCase(suite, type) {
|
||||
suite.add('gaussianBlur', function() {
|
||||
cv.GaussianBlur(src, dst, ksize, 1, 0, borderType);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let matType = cv[this.params.matType];
|
||||
let borderType = cv[this.params.borderType];
|
||||
let type = this.params.type;
|
||||
let src = new cv.Mat(size, matType);
|
||||
let dst = new cv.Mat(size, matType);
|
||||
let ksizeNum = this.params.ksize;
|
||||
let ksize = new cv.Size(ksizeNum, ksizeNum);
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addGaussianBlurModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let matType = combination[i][1];
|
||||
let borderType = combination[i][2];
|
||||
let ksizeArray = [3, 5];
|
||||
let params = {size: size, matType:matType, ksize: ksizeArray[type], borderType:borderType};
|
||||
addKernelCase(suite, params, type, addGaussianBlurCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*BORDER\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*BORDER\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[FSUfsu]C[0-9]/"], index:1});
|
||||
paramObjs.push({name:"borderMode", value: "", reg:["/BORDER\_\\w+/"], index:2});
|
||||
let locationList = decodeParams2Case(params, paramObjs,gaussianBlurCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addGaussianBlurModeCase(suite, [gaussianBlurCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addGaussianBlurModeCase(suite, combiGaussianBlurBorder3x3, 0);
|
||||
addGaussianBlurModeCase(suite, combiGaussianBlurBorder3x3ROI, 1);
|
||||
}
|
||||
setBenchmarkSuite(suite, "gaussianBlur", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from gaussianBlur`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let gaussianBlurCombinations = [combiGaussianBlurBorder3x3, combiGaussianBlurBorder3x3ROI];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*BORDER\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*BORDER\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>MedianBlur</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (1280x720, CV_8UC1, 3)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_medianBlur.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,121 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const MedianBlurSize = [cvSize.szODD, cvSize.szQVGA, cvSize.szVGA, cvSize.sz720p];
|
||||
const MedianBlurType = ["CV_8UC1", "CV_8UC4", "CV_16UC1", "CV_16SC1", "CV_32FC1"];
|
||||
const combiMedianBlur = combine(MedianBlurSize, MedianBlurType, [3,5]);
|
||||
|
||||
function addMedianBlurCase(suite, type) {
|
||||
suite.add('medianBlur', function() {
|
||||
cv.medianBlur(src, dst, ksize);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let matType = cv[this.params.matType];
|
||||
let ksize = this.params.ksize;
|
||||
let src = new cv.Mat(size, matType);
|
||||
let dst = new cv.Mat(size, matType);
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addMedianBlurModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let matType = combination[i][1];
|
||||
let ksize = combination[i][2];
|
||||
|
||||
let params = {size: size, matType:matType, ksize: ksize};
|
||||
addKernelCase(suite, params, type, addMedianBlurCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*(3|5)\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*(3|5)\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[FSUfsu]C[0-9]/"], index:1});
|
||||
paramObjs.push({name:"ksize", value: "", reg:["/\\b[0-9]\\b/"], index:2});
|
||||
let locationList = decodeParams2Case(params, paramObjs, medianBlurCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addMedianBlurModeCase(suite, [medianBlurCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addMedianBlurModeCase(suite, combiMedianBlur, 0);
|
||||
}
|
||||
setBenchmarkSuite(suite, "medianBlur", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from medianBlur`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let medianBlurCombinations = [combiMedianBlur];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*(3|5)\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*(3|5)\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>pyrDown</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (1920x1080, CV_8UC3)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_pyrDown.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,119 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const PyrDownSize = [cvSize.sz1080p, cvSize.sz720p, cvSize.szVGA, cvSize.szQVGA, cvSize.szODD];
|
||||
const PyrDownType = ["CV_8UC1", "CV_8UC3", "CV_8UC4", "CV_16SC1", "CV_16SC3", "CV_16SC4", "CV_32FC1", "CV_32FC3", "CV_32FC4"];
|
||||
|
||||
const combiPyrDown = combine(PyrDownSize, PyrDownType);
|
||||
|
||||
function addPryDownCase(suite, type) {
|
||||
suite.add('pyrDown', function() {
|
||||
cv.pyrDown(src, dst);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let matType = cv[this.params.matType];
|
||||
let src = new cv.Mat(size, matType);
|
||||
let dst = new cv.Mat((size.height + 1)/2, (size.height + 1)/2, matType)
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addPyrDownModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let matType = combination[i][1];
|
||||
|
||||
let params = {size: size, matType:matType};
|
||||
addKernelCase(suite, params, type, addPryDownCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[FSUfsu]C[0-9]/"], index:1});
|
||||
let locationList = decodeParams2Case(params, paramObjs, pyrDownCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addPyrDownModeCase(suite, [pyrDownCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addPyrDownModeCase(suite, combiPyrDown, 0);
|
||||
}
|
||||
setBenchmarkSuite(suite, "pyrDown", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from pyrDown`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let pyrDownCombinations = [combiPyrDown];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Remap</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (640x480, CV_16UC1, CV_16SC2, INTER_NEAREST)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_remap.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,185 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const RemapSize = [cvSize.szVGA, cvSize.sz1080p];
|
||||
const RemapSrcType = ["CV_16UC1", "CV_16SC1", "CV_32FC1"];
|
||||
const RemapType = ["CV_16SC2", "CV_32FC1", "CV_32FC2"];
|
||||
const InterType = ["INTER_NEAREST", "INTER_LINEAR", "INTER_CUBIC", "INTER_LANCZOS4"];
|
||||
const combiRemap = combine(RemapSize, RemapSrcType, RemapType, InterType);
|
||||
|
||||
function addRemapCase(suite, type) {
|
||||
suite.add('remap', function() {
|
||||
cv.remap(src, dst, map1, map2, interType);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let matType = cv[this.params.matType];
|
||||
let mapType = cv[this.params.mapType];
|
||||
let interType = cv[this.params.interType];
|
||||
|
||||
|
||||
let src = new cv.Mat(size, matType);
|
||||
let dst = new cv.Mat(size, matType);
|
||||
let map1 = new cv.Mat(size, mapType);
|
||||
let map2;
|
||||
if (mapType == cv.CV_32FC1) {
|
||||
map2 = new cv.Mat(size, mapType);
|
||||
} else if (interType != cv.INTER_NEAREST && mapType == cv.CV_16SC2) {
|
||||
map2 = new cv.Mat.zeros(size, cv.CV_16UC1);
|
||||
} else {
|
||||
map2 = new cv.Mat();
|
||||
}
|
||||
|
||||
for (let j = 0; j < map1.rows; j++) {
|
||||
for (let i = 0; i < map1.cols; i++) {
|
||||
let randNum = Math.random();
|
||||
let view, view1;
|
||||
switch(matType) {
|
||||
case cv.CV_16UC1:
|
||||
view = src.ushortPtr(j,i);
|
||||
view[0] = Math.floor(randNum*256);
|
||||
break;
|
||||
case cv.CV_16SC1:
|
||||
view = src.shortPtr(j,i);
|
||||
view[0] = Math.floor(randNum*256);
|
||||
break;
|
||||
case cv.CV_32FC1:
|
||||
view = src.floatPtr(j,i);
|
||||
view[0] = randNum*256;
|
||||
break;
|
||||
default:
|
||||
console.error("Unknown conversion type 1");
|
||||
break;
|
||||
}
|
||||
|
||||
switch(mapType) {
|
||||
case cv.CV_32FC1:
|
||||
view1 = map1.floatPtr(j,i);
|
||||
let view2 = map2.floatPtr(j,i);
|
||||
view1[0] = src.cols - i - 1;
|
||||
view2[0] = j;
|
||||
break;
|
||||
case cv.CV_32FC2:
|
||||
view1 = map1.floatPtr(j,i);
|
||||
view1[0] = src.cols - i - 1;
|
||||
view1[1] = j;
|
||||
break;
|
||||
case cv.CV_16SC2:
|
||||
view1 = map1.shortPtr(j,i);
|
||||
view1[0] = src.cols - i - 1;
|
||||
view1[1] = j;
|
||||
break;
|
||||
default:
|
||||
console.error("Unknown conversion type 2");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
map1.delete();
|
||||
map2.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addRemapModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let matType = combination[i][1];
|
||||
let mapType = combination[i][2];
|
||||
let interType = combination[i][3];
|
||||
|
||||
let params = {size: size, matType:matType, mapType:mapType, interType:interType};
|
||||
addKernelCase(suite, params, type, addRemapCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*CV\_\w+,[\ ]*INTER\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*CV\_\w+,[\ ]*INTER\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[FSUfsu]C[0-9]/"], index:1});
|
||||
paramObjs.push({name:"mapType", value:"", reg:["/CV\_[0-9]+[FSUfsu]C[0-9]/g"], index:2, loc:1});
|
||||
paramObjs.push({name:"interType", value: "", reg:["/INTER\_\\w+/"], index:3});
|
||||
let locationList = decodeParams2Case(params, paramObjs, remapCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addRemapModeCase(suite, [remapCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addRemapModeCase(suite, combiRemap, 0);
|
||||
}
|
||||
setBenchmarkSuite(suite, "remap", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from remap`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let remapCombinations = [combiRemap];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*CV\_\w+,[\ ]*INTER\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*CV\_\w+,[\ ]*INTER\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Resize</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (CV_8UC1,640x480,960x540)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_resize.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,169 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.fillGradient = HelpFunc.fillGradient;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const matTypesUpLinear = ['CV_8UC1', 'CV_8UC2', 'CV_8UC3', 'CV_8UC4'];
|
||||
const size1UpLinear = [cvSize.szVGA];
|
||||
const size2UpLinear = [cvSize.szqHD, cvSize.sz720p];
|
||||
const combiUpLinear = combine(matTypesUpLinear, size1UpLinear, size2UpLinear);
|
||||
|
||||
const combiDownLinear = [
|
||||
['CV_8UC1', cvSize.szVGA, cvSize.szQVGA],
|
||||
['CV_8UC2', cvSize.szVGA, cvSize.szQVGA],
|
||||
['CV_8UC3', cvSize.szVGA, cvSize.szQVGA],
|
||||
['CV_8UC4', cvSize.szVGA, cvSize.szQVGA],
|
||||
['CV_8UC1', cvSize.szqHD, cvSize.szVGA],
|
||||
['CV_8UC2', cvSize.szqHD, cvSize.szVGA],
|
||||
['CV_8UC3', cvSize.szqHD, cvSize.szVGA],
|
||||
['CV_8UC4', cvSize.szqHD, cvSize.szVGA],
|
||||
['CV_8UC1', cvSize.sz720p, cvSize.sz213x120],// face detection min_face_size = 20%
|
||||
['CV_8UC2', cvSize.sz720p, cvSize.sz213x120],// face detection min_face_size = 20%
|
||||
['CV_8UC3', cvSize.sz720p, cvSize.sz213x120],// face detection min_face_size = 20%
|
||||
['CV_8UC4', cvSize.sz720p, cvSize.sz213x120],// face detection min_face_size = 20%
|
||||
['CV_8UC1', cvSize.sz720p, cvSize.szVGA],
|
||||
['CV_8UC2', cvSize.sz720p, cvSize.szVGA],
|
||||
['CV_8UC3', cvSize.sz720p, cvSize.szVGA],
|
||||
['CV_8UC4', cvSize.sz720p, cvSize.szVGA],
|
||||
['CV_8UC1', cvSize.sz720p, cvSize.szQVGA],
|
||||
['CV_8UC2', cvSize.sz720p, cvSize.szQVGA],
|
||||
['CV_8UC3', cvSize.sz720p, cvSize.szQVGA],
|
||||
['CV_8UC4', cvSize.sz720p, cvSize.szQVGA]
|
||||
];
|
||||
|
||||
const matTypesAreaFast = ['CV_8UC1', 'CV_8UC3', 'CV_8UC4', 'CV_16UC1', 'CV_16UC3', 'CV_16UC4'];
|
||||
const sizesAreaFast = [cvSize.szVGA, cvSize.szqHD, cvSize.sz720p, cvSize.sz1080p];
|
||||
const scalesAreaFast = [2];
|
||||
const combiAreaFast = combine(matTypesAreaFast, sizesAreaFast, scalesAreaFast);
|
||||
|
||||
function addResizeCase(suite, type) {
|
||||
suite.add('resize', function() {
|
||||
if (type == "area") {
|
||||
cv.resize(src, dst, dst.size(), 0, 0, cv.INTER_AREA);
|
||||
} else {
|
||||
cv.resize(src, dst, to, 0, 0, cv.INTER_LINEAR_EXACT);
|
||||
}
|
||||
}, {
|
||||
'setup': function() {
|
||||
let from = this.params.from;
|
||||
let to = this.params.to;
|
||||
let matType = cv[this.params.matType];
|
||||
let src = new cv.Mat(from, matType);
|
||||
let type = this.params.modeType;
|
||||
let dst;
|
||||
if (type == "area") {
|
||||
dst = new cv.Mat(from.height/scale, from.width/scale, matType);
|
||||
} else {
|
||||
dst = new cv.Mat(to, matType);
|
||||
fillGradient(cv, src);
|
||||
}
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addResizeModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let matType = combination[i][0];
|
||||
let from = combination[i][1];
|
||||
let params;
|
||||
if (type == "area") {
|
||||
let scale = combination[i][2];
|
||||
params = { from: from, scale: scale, matType: matType, modeType: type };
|
||||
} else {
|
||||
let to = combination[i][2];
|
||||
params = { from: from, to: to, matType: matType, modeType: type};
|
||||
}
|
||||
addKernelCase(suite, params, type, addResizeCase)
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
if (/\(\w+,[\ ]*[0-9]+x[0-9]+,[\ ]*[0-9]+x[0-9]+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\(\w+,[\ ]*[0-9]+x[0-9]+,[\ ]*[0-9]+x[0-9]+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[A-z][A-z][0-9]/"], index:0});
|
||||
paramObjs.push({name:"size1", value:"", reg:[""], index:1});
|
||||
paramObjs.push({name:"size2", value:"", reg:[""], index:2});
|
||||
let locationList = decodeParams2Case(params, paramObjs,combinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addResizeModeCase(suite, [combinations[first][second]], "linear");
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addResizeModeCase(suite, combiUpLinear, "linear");
|
||||
addResizeModeCase(suite, combiDownLinear, "linear");
|
||||
}
|
||||
setBenchmarkSuite(suite, "resize", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from Resize`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
// init
|
||||
let combinations = [combiUpLinear, combiDownLinear];//, combiAreaFast];
|
||||
|
||||
// set test filter params
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\(\w+,[\ ]*[0-9]+x[0-9]+,[\ ]*[0-9]+x[0-9]+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\(\w+,[\ ]*[0-9]+x[0-9]+,[\ ]*[0-9]+x[0-9]+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Scharr</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (640x480, CV_16SC1, (0,1), BORDER_REPLICATE)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_scharr.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,159 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const ScharrSize = [cvSize.szODD, cvSize.szQVGA, cvSize.szVGA];
|
||||
const Scharrdxdy = ["(1,0)", "(0,1)"];
|
||||
const BorderType3x3 = ["BORDER_REPLICATE", "BORDER_CONSTANT"];
|
||||
const BorderType3x3ROI = ["BORDER_DEFAULT", "BORDER_REPLICATE|BORDER_ISOLATED", "BORDER_CONSTANT|BORDER_ISOLATED"];
|
||||
|
||||
const combiScharrBorder3x3 = combine(ScharrSize, ["CV_16SC1", "CV_32FC1"], Scharrdxdy, BorderType3x3);
|
||||
const combiScharrBorder3x3ROI = combine(ScharrSize, ["CV_16SC1", "CV_32FC1"], Scharrdxdy, BorderType3x3ROI);
|
||||
|
||||
function addScharrCase(suite, type) {
|
||||
suite.add('scharr', function() {
|
||||
cv.Scharr(src, dst, ddepth, dx, dy, 1, 0, borderType);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let ddepth = cv[this.params.ddepth];
|
||||
let dxdy = this.params.dxdy;
|
||||
let type = this.params.type;
|
||||
let src, dst;
|
||||
if (type == 0) {
|
||||
src = new cv.Mat(size[1], size[0], cv.CV_8U);
|
||||
dst = new cv.Mat(size[1], size[0], ddepth);
|
||||
} else {
|
||||
src = new cv.Mat(size[1]+10, size[0]+10, cv.CV_8U);
|
||||
dst = new cv.Mat(size[1]+10, size[0]+10, ddepth);
|
||||
src = src.colRange(5, size[0]+5);
|
||||
src = src.rowRange(5, size[1]+5);
|
||||
dst = dst.colRange(5, size[0]+5);
|
||||
dst = dst.rowRange(5, size[1]+5);
|
||||
}
|
||||
|
||||
let dx = parseInt(dxdy[1]);
|
||||
let dy = parseInt(dxdy[3]);
|
||||
let borderTypeArray = this.params.borderType;
|
||||
let borderType;
|
||||
if (borderTypeArray.length == 1) {
|
||||
borderType = cv[borderTypeArray[0]];
|
||||
} else {
|
||||
borderType = cv[borderTypeArray[0]] | cv[borderTypeArray[1]];
|
||||
}
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addScharrModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let ddepth = combination[i][1];
|
||||
let dxdy = combination[i][2];
|
||||
let borderType = combination[i][3];
|
||||
let sizeArray = [size.width, size.height];
|
||||
|
||||
let borderTypeArray = borderType.split("|");
|
||||
let params = {size: sizeArray, ddepth: ddepth, dxdy: dxdy, borderType:borderTypeArray, type:type};
|
||||
addKernelCase(suite, params, type, addScharrCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
let params = "";
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"ddepth", value:"", reg:["/CV\_[0-9]+[FSUfsu]C1/g"], index:1});
|
||||
paramObjs.push({name:"dxdy", value:"", reg:["/\\([0-2],[0-2]\\)/"], index:2});
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\)/g.test(paramsContent.toString())) {
|
||||
params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\)/g)[0];
|
||||
paramObjs.push({name:"boderType", value:"", reg:["/BORDER\_\\w+/"], index:3});
|
||||
} else if (/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\|\w+\)/g.test(paramsContent.toString())) {
|
||||
params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\|\w+\)/g)[0];
|
||||
paramObjs.push({name:"boderType", value:"", reg:["/BORDER\_\\w+\\|BORDER\_\\w+/"], index:3});
|
||||
}
|
||||
|
||||
if (params != ""){
|
||||
let locationList = decodeParams2Case(params, paramObjs,scharrCombinations);
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addScharrModeCase(suite, [scharrCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addScharrModeCase(suite, combiScharrBorder3x3, 0);
|
||||
addScharrModeCase(suite, combiScharrBorder3x3ROI, 1);
|
||||
}
|
||||
setBenchmarkSuite(suite, "scharr", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from Scharr`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let scharrCombinations = [combiScharrBorder3x3, combiScharrBorder3x3ROI];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\)/g)[0];
|
||||
} else if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\|\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\|\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Sobel</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (640x480, CV_16SC1, (0,1), BORDER_REPLICATE)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_sobel.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,173 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const SobelSize = [cvSize.szODD, cvSize.szQVGA, cvSize.szVGA];
|
||||
const Sobel3x3dxdy = ["(0,1)", "(1,0)", "(1,1)", "(0,2)", "(2,0)", "(2,2)"];
|
||||
const Sobeldxdy = ["(0,1)", "(1,0)", "(1,1)", "(0,2)", "(2,0)"];
|
||||
const BorderType3x3 = ["BORDER_REPLICATE", "BORDER_CONSTANT"];
|
||||
const BorderType3x3ROI = ["BORDER_DEFAULT", "BORDER_REPLICATE|BORDER_ISOLATED", "BORDER_CONSTANT|BORDER_ISOLATED"];
|
||||
const BorderType = ["BORDER_REPLICATE", "BORDER_CONSTANT", "BORDER_REFLECT", "BORDER_REFLECT101"];
|
||||
const BorderTypeROI = ["BORDER_DEFAULT", "BORDER_REPLICATE|BORDER_ISOLATED", "BORDER_CONSTANT|BORDER_ISOLATED", "BORDER_REFLECT|BORDER_ISOLATED", "BORDER_REFLECT101|BORDER_ISOLATED"]
|
||||
|
||||
const combiSobelBorder3x3 = combine(SobelSize, ["CV_16SC1", "CV_32FC1"], Sobel3x3dxdy, BorderType3x3);
|
||||
const combiSobelBorder3x3ROI = combine(SobelSize, ["CV_16SC1", "CV_32FC1"], Sobel3x3dxdy, BorderType3x3ROI);
|
||||
const combiSobelBorder5x5 = combine(SobelSize, ["CV_16SC1", "CV_32FC1"], Sobeldxdy, BorderType);
|
||||
const combiSobelBorder5x5ROI = combine(SobelSize, ["CV_16SC1", "CV_32FC1"], Sobeldxdy, BorderTypeROI);
|
||||
|
||||
function addSobelCase(suite, type) {
|
||||
suite.add('sobel', function() {
|
||||
cv.Sobel(src, dst, ddepth, dx, dy, ksize, 1, 0, borderType);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let size = this.params.size;
|
||||
let ddepth = cv[this.params.ddepth];
|
||||
let dxdy = this.params.dxdy;
|
||||
let ksize = this.params.ksize;
|
||||
let type = this.params.type;
|
||||
let src, dst;
|
||||
if (type %2 == 0) {
|
||||
src = new cv.Mat(size[1], size[0], cv.CV_8U);
|
||||
dst = new cv.Mat(size[1], size[0], ddepth);
|
||||
} else {
|
||||
src = new cv.Mat(size[1]+10, size[0]+10, cv.CV_8U);
|
||||
dst = new cv.Mat(size[1]+10, size[0]+10, ddepth);
|
||||
src = src.colRange(5, size[0]+5);
|
||||
src = src.rowRange(5, size[1]+5);
|
||||
dst = dst.colRange(5, size[0]+5);
|
||||
dst = dst.rowRange(5, size[1]+5);
|
||||
}
|
||||
|
||||
let dx = parseInt(dxdy[1]);
|
||||
let dy = parseInt(dxdy[3]);
|
||||
let borderTypeArray = this.params.borderType;
|
||||
let borderType;
|
||||
if (borderTypeArray.length == 1) {
|
||||
borderType = cv[borderTypeArray[0]];
|
||||
} else {
|
||||
borderType = cv[borderTypeArray[0]] | cv[borderTypeArray[1]];
|
||||
}
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addSobelModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let ddepth = combination[i][1];
|
||||
let dxdy = combination[i][2];
|
||||
let borderType = combination[i][3];
|
||||
let sizeArray = [size.width, size.height];
|
||||
let ksize;
|
||||
if (type < 2) {
|
||||
ksize = 3;
|
||||
} else {
|
||||
ksize = 5;
|
||||
}
|
||||
|
||||
let borderTypeArray = borderType.split("|");
|
||||
let params = {size: sizeArray, ddepth: ddepth, dxdy: dxdy, ksize:ksize, borderType:borderTypeArray, type:type};
|
||||
addKernelCase(suite, params, type, addSobelCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
let params = "";
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"ddepth", value:"", reg:["/CV\_[0-9]+[FSUfsu]C1/g"], index:1});
|
||||
paramObjs.push({name:"dxdy", value:"", reg:["/\\([0-2],[0-2]\\)/"], index:2});
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\)/g.test(paramsContent.toString())) {
|
||||
params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\)/g)[0];
|
||||
paramObjs.push({name:"boderType", value:"", reg:["/BORDER\_\\w+/"], index:3});
|
||||
} else if (/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\|\w+\)/g.test(paramsContent.toString())) {
|
||||
params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\|\w+\)/g)[0];
|
||||
paramObjs.push({name:"boderType", value:"", reg:["/BORDER\_\\w+\\|BORDER\_\\w+/"], index:3});
|
||||
}
|
||||
|
||||
if (params != ""){
|
||||
let locationList = decodeParams2Case(params, paramObjs,sobelCombinations);
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addSobelModeCase(suite, [sobelCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addSobelModeCase(suite, combiSobelBorder3x3, 0);
|
||||
addSobelModeCase(suite, combiSobelBorder3x3ROI, 1);
|
||||
addSobelModeCase(suite, combiSobelBorder5x5, 2);
|
||||
addSobelModeCase(suite, combiSobelBorder5x5ROI, 3);
|
||||
}
|
||||
setBenchmarkSuite(suite, "sobel", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from Sobel`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let sobelCombinations = [combiSobelBorder3x3, combiSobelBorder3x3ROI, combiSobelBorder5x5, combiSobelBorder5x5ROI];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\)/g)[0];
|
||||
} else if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\|\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\([0-2],[0-2]\),[\ ]*\w+\|\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>Threshold</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (1920x1080, CV_8UC1, THRESH_BINARY)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_threshold.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,161 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase;
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const typicalMatSizes = [cvSize.szVGA, cvSize.sz720p, cvSize.sz1080p, cvSize.szODD];
|
||||
const matTypes = ['CV_8UC1', 'CV_16SC1', 'CV_32FC1', 'CV_64FC1'];
|
||||
const threshTypes = ['THRESH_BINARY', 'THRESH_BINARY_INV', 'THRESH_TRUNC', 'THRESH_TOZERO', 'THRESH_TOZERO_INV'];
|
||||
|
||||
const combiSizeMatTypeThreshType = combine(typicalMatSizes, matTypes, threshTypes);
|
||||
const combiSizeOnly = combine(typicalMatSizes, ['CV_8UC1'], ['THRESH_BINARY|THRESH_OTSU']);
|
||||
|
||||
|
||||
function addThresholdCase(suite, type) {
|
||||
suite.add('threshold', function() {
|
||||
if (type == "sizeonly") {
|
||||
cv.threshold(src, dst, threshold, thresholdMax, cv.THRESH_BINARY|cv.THRESH_OTSU);
|
||||
} else {
|
||||
cv.threshold(src, dst, threshold, thresholdMax, threshType);
|
||||
}
|
||||
}, {
|
||||
'setup': function() {
|
||||
let matSize = this.params.matSize;
|
||||
let type = this.params.modeType;
|
||||
let src, dst, matType, threshType;
|
||||
if (type == "sizeonly") {
|
||||
src = new cv.Mat(matSize, cv.CV_8UC1);
|
||||
dst = new cv.Mat(matSize, cv.CV_8UC1);
|
||||
} else {
|
||||
matType = cv[this.params.matType];
|
||||
threshType = cv[this.params.threshType];
|
||||
src = new cv.Mat(matSize, matType);
|
||||
dst = new cv.Mat(matSize, matType);
|
||||
}
|
||||
let threshold = 127.0;
|
||||
let thresholdMax = 210.0;
|
||||
let srcView = src.data;
|
||||
srcView[0] = 0;
|
||||
srcView[1] = 100;
|
||||
srcView[2] = 200;
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addThresholdModecase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let matSize = combination[i][0];
|
||||
let matType = 'CV_8UC1';
|
||||
let threshType = 'THRESH_BINARY|THRESH_OTSU';
|
||||
if (type != "sizeonly") {
|
||||
matType = combination[i][1];
|
||||
threshType = combination[i][2];
|
||||
}
|
||||
let params = {matSize: matSize, matType: matType, threshType: threshType, modeType: type};
|
||||
addKernelCase(suite, params, type, addThresholdCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
let params = "";
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*THRESH\_\w+\)/g.test(paramsContent.toString())) {
|
||||
params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*THRESH\_\w+\)/g)[0];
|
||||
paramObjs.push({name:"matType", value:"", reg:["/CV\_[0-9]+[A-z][A-z][0-9]/"], index:1});
|
||||
paramObjs.push({name:"threshType", value:"", reg:["/THRESH\_[A-z]+\_?[A-z]*/"], index:2});
|
||||
} else if (/[\ ]*[0-9]+x[0-9]+[\ ]*/g.test(paramsContent.toString())) {
|
||||
params = paramsContent.toString().match(/[\ ]*[0-9]+x[0-9]+[\ ]*/g)[0];
|
||||
paramObjs.push({name:"matType", value:"CV_8UC1", reg:[""], index:1});
|
||||
paramObjs.push({name:"threshType", value:"THRESH_BINARY|THRESH_OTSU", reg:[""], index:2});
|
||||
}
|
||||
|
||||
if(params != ""){
|
||||
let locationList = decodeParams2Case(params, paramObjs,combinations);
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
if (first == 0) {
|
||||
addThresholdModecase(suite, [combinations[first][second]], "normal");
|
||||
} else {
|
||||
addThresholdModecase(suite, [combinations[first][second]], "sizeonly");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addThresholdModecase(suite, combiSizeMatTypeThreshType, "normal");
|
||||
addThresholdModecase(suite, combiSizeOnly, "sizeonly");
|
||||
}
|
||||
setBenchmarkSuite(suite, "threshold", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from Threshold`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
// init
|
||||
let combinations = [combiSizeMatTypeThreshType, combiSizeOnly];
|
||||
|
||||
// set test filter params
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*THRESH\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*CV\_\w+,[\ ]*THRESH\_\w+\)/g)[0];
|
||||
} else if (/--test_param_filter=[\ ]*[0-9]+x[0-9]+[\ ]*/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/[\ ]*[0-9]+x[0-9]+[\ ]*/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>warpAffine</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (640x480, INTER_NEAREST, BORDER_CONSTANT)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_warpAffine.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,135 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.fillGradient = HelpFunc.fillGradient;
|
||||
global.smoothBorder = HelpFunc.smoothBorder;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const WarpAffineSize = [cvSize.szVGA, cvSize.sz720p, cvSize.sz1080p];
|
||||
const InterType = ["INTER_NEAREST", "INTER_LINEAR"];
|
||||
const BorderMode = ["BORDER_CONSTANT", "BORDER_REPLICATE"]
|
||||
const combiWarpAffine = combine(WarpAffineSize, InterType, BorderMode);
|
||||
|
||||
function addWarpAffineCase(suite, type) {
|
||||
suite.add('warpAffine', function() {
|
||||
cv.warpAffine(src, dst, warpMat, sz, interType, borderMode, borderColor);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let sz = this.params.size;
|
||||
let interType = cv[this.params.interType];
|
||||
let borderMode = cv[this.params.borderMode];
|
||||
let srcSize = new cv.Size(512, 512);
|
||||
|
||||
let borderColor = new cv.Scalar.all(150);
|
||||
let src = new cv.Mat(srcSize, cv.CV_8UC4);
|
||||
let dst = new cv.Mat(sz, cv.CV_8UC4);
|
||||
fillGradient(cv, src);
|
||||
if (borderMode == cv.BORDER_CONSTANT) {
|
||||
smoothBorder(cv, src, borderMode, 1);
|
||||
}
|
||||
|
||||
let point = new cv.Point(src.cols/2.0, src.rows/2.0);
|
||||
let warpMat = cv.getRotationMatrix2D(point, 30.0, 2.2);
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
warpMat.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addWarpAffineModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let interType = combination[i][1];
|
||||
let borderMode = combination[i][2];
|
||||
|
||||
let params = {size: size, interType:interType, borderMode:borderMode};
|
||||
addKernelCase(suite, params, type, addWarpAffineCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*INTER\_\w+,[\ ]*BORDER\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*INTER\_\w+,[\ ]*BORDER\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"interType", value: "", reg:["/INTER\_\\w+/"], index:1});
|
||||
paramObjs.push({name:"borderMode", value: "", reg:["/BORDER\_\\w+/"], index:2});
|
||||
let locationList = decodeParams2Case(params, paramObjs, warpAffineCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addWarpAffineModeCase(suite, [warpAffineCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addWarpAffineModeCase(suite, combiWarpAffine, 0);
|
||||
}
|
||||
setBenchmarkSuite(suite, "warpAffine", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from warpAffine`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let warpAffineCombinations = [combiWarpAffine];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*INTER\_\w+,[\ ]*BORDER\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*INTER\_\w+,[\ ]*BORDER\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenCV.js Performance Test</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<style>
|
||||
body {
|
||||
font-size: 13px;
|
||||
}
|
||||
.top-margin {
|
||||
margin-top:10px;
|
||||
}
|
||||
h1, h4 {
|
||||
margin: 24px 0 0;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.0em;
|
||||
}
|
||||
h4 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
pre {
|
||||
font-family: 'Consolas', 'Monaco', monospace, serif;
|
||||
font-size: 12px;
|
||||
tab-size: 2;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1>OpenCV.js Performance Test</h1>
|
||||
<div>
|
||||
<h4>Modules</h4>
|
||||
<h7>Image Processing</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Kernels</h4>
|
||||
<h7>warpPerspective</h7>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Parameters Filter</h4>
|
||||
<input type="text" id="params" min="1" size="40" placeholder="default: run all the case"/> for example: (640x480, INTER_NEAREST, BORDER_CONSTANT)
|
||||
</div>
|
||||
<div class='row labels-wrapper' id='labelitem'></div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="runButton" class="btn btn-primary disabled" disabled="disabled">Loading</button>
|
||||
(It will take several minutes)</div>
|
||||
<div class="row top-margin">
|
||||
</div>
|
||||
<div>
|
||||
<pre id="log"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/2.1.4/benchmark.js"></script>
|
||||
<script src="../../opencv.js" type="text/javascript"></script>
|
||||
<script src="../base.js"></script>
|
||||
<script src="../perf_helpfunc.js"></script>
|
||||
<script src="./perf_warpPerspective.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,148 @@
|
||||
var isNodeJs = (typeof window) === 'undefined'? true : false;
|
||||
|
||||
if (isNodeJs) {
|
||||
var Benchmark = require('benchmark');
|
||||
var cv = require('../../opencv');
|
||||
var HelpFunc = require('../perf_helpfunc');
|
||||
var Base = require('../base');
|
||||
} else {
|
||||
var paramsElement = document.getElementById('params');
|
||||
var runButton = document.getElementById('runButton');
|
||||
var logElement = document.getElementById('log');
|
||||
}
|
||||
|
||||
function perf() {
|
||||
|
||||
console.log('opencv.js loaded');
|
||||
if (isNodeJs) {
|
||||
global.cv = cv;
|
||||
global.fillGradient = HelpFunc.fillGradient;
|
||||
global.smoothBorder = HelpFunc.smoothBorder;
|
||||
global.combine = HelpFunc.combine;
|
||||
global.log = HelpFunc.log;
|
||||
global.decodeParams2Case = HelpFunc.decodeParams2Case;
|
||||
global.setBenchmarkSuite = HelpFunc.setBenchmarkSuite;
|
||||
global.addKernelCase = HelpFunc.addKernelCase
|
||||
global.cvSize = Base.getCvSize();
|
||||
} else {
|
||||
enableButton();
|
||||
cvSize = getCvSize();
|
||||
}
|
||||
let totalCaseNum, currentCaseId;
|
||||
|
||||
const WarpPersSize = [cvSize.szVGA, cvSize.sz720p, cvSize.sz1080p];
|
||||
const InterType = ["INTER_NEAREST", "INTER_LINEAR"];
|
||||
const BorderMode = ["BORDER_CONSTANT", "BORDER_REPLICATE"]
|
||||
const combiWarpPers = combine(WarpPersSize, InterType, BorderMode);
|
||||
|
||||
function addWarpPerspectiveCase(suite, type) {
|
||||
suite.add('warpPerspective', function() {
|
||||
cv.warpPerspective(src, dst, warpMat, sz, interType, borderMode, borderColor);
|
||||
}, {
|
||||
'setup': function() {
|
||||
let sz = this.params.size;
|
||||
let interType = cv[this.params.interType];
|
||||
let borderMode = cv[this.params.borderMode];
|
||||
let srcSize = new cv.Size(512, 512);
|
||||
|
||||
let borderColor = new cv.Scalar.all(150);
|
||||
let src = new cv.Mat(srcSize, cv.CV_8UC4);
|
||||
let dst = new cv.Mat(sz, cv.CV_8UC4);
|
||||
fillGradient(cv, src);
|
||||
if (borderMode == cv.BORDER_CONSTANT) {
|
||||
smoothBorder(cv, src, borderMode, 1);
|
||||
}
|
||||
|
||||
let rotMat = cv.getRotationMatrix2D(new cv.Point(src.cols/2.0, src.rows/2.0), 30.0, 2.2);
|
||||
let warpMat = new cv.Mat(3, 3, cv.CV_64FC1);
|
||||
|
||||
for(r=0; r<2; r++) {
|
||||
for(c=0; c<3; c++) {
|
||||
view = warpMat.doublePtr(r,c)
|
||||
view[0] = rotMat.doubleAt(r, c);
|
||||
}
|
||||
}
|
||||
view = warpMat.doublePtr(2,0);
|
||||
view[0] = 0.3/sz.width;
|
||||
view = warpMat.doublePtr(2,1);
|
||||
view[0] = 0.3/sz.height;
|
||||
view = warpMat.doublePtr(2,2);
|
||||
view[0] = 1;
|
||||
},
|
||||
'teardown': function() {
|
||||
src.delete();
|
||||
dst.delete();
|
||||
warpMat.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addWarpPerspectiveModeCase(suite, combination, type) {
|
||||
totalCaseNum += combination.length;
|
||||
for (let i = 0; i < combination.length; ++i) {
|
||||
let size = combination[i][0];
|
||||
let interType = combination[i][1];
|
||||
let borderMode = combination[i][2];
|
||||
|
||||
let params = {size: size, interType:interType, borderMode:borderMode};
|
||||
addKernelCase(suite, params, type, addWarpPerspectiveCase);
|
||||
}
|
||||
}
|
||||
|
||||
function genBenchmarkCase(paramsContent) {
|
||||
let suite = new Benchmark.Suite;
|
||||
totalCaseNum = 0;
|
||||
currentCaseId = 0;
|
||||
|
||||
if (/\([0-9]+x[0-9]+,[\ ]*INTER\_\w+,[\ ]*BORDER\_\w+\)/g.test(paramsContent.toString())) {
|
||||
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*INTER\_\w+,[\ ]*BORDER\_\w+\)/g)[0];
|
||||
let paramObjs = [];
|
||||
paramObjs.push({name:"size", value:"", reg:[""], index:0});
|
||||
paramObjs.push({name:"interType", value: "", reg:["/INTER\_\\w+/"], index:1});
|
||||
paramObjs.push({name:"borderMode", value: "", reg:["/BORDER\_\\w+/"], index:2});
|
||||
let locationList = decodeParams2Case(params, paramObjs, warpPersCombinations);
|
||||
|
||||
for (let i = 0; i < locationList.length; i++){
|
||||
let first = locationList[i][0];
|
||||
let second = locationList[i][1];
|
||||
addWarpPerspectiveModeCase(suite, [warpPersCombinations[first][second]], first);
|
||||
}
|
||||
} else {
|
||||
log("no filter or getting invalid params, run all the cases");
|
||||
addWarpPerspectiveModeCase(suite, combiWarpPers, 0);
|
||||
}
|
||||
setBenchmarkSuite(suite, "warpPerspective", currentCaseId);
|
||||
log(`Running ${totalCaseNum} tests from warpPerspective`);
|
||||
suite.run({ 'async': true }); // run the benchmark
|
||||
}
|
||||
|
||||
let warpPersCombinations = [combiWarpPers];
|
||||
|
||||
if (isNodeJs) {
|
||||
const args = process.argv.slice(2);
|
||||
let paramsContent = '';
|
||||
if (/--test_param_filter=\([0-9]+x[0-9]+,[\ ]*INTER\_\w+,[\ ]*BORDER\_\w+\)/g.test(args.toString())) {
|
||||
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*INTER\_\w+,[\ ]*BORDER\_\w+\)/g)[0];
|
||||
}
|
||||
genBenchmarkCase(paramsContent);
|
||||
} else {
|
||||
runButton.onclick = function() {
|
||||
let paramsContent = paramsElement.value;
|
||||
genBenchmarkCase(paramsContent);
|
||||
if (totalCaseNum !== 0) {
|
||||
disableButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
if (cv instanceof Promise) {
|
||||
cv = await cv;
|
||||
perf();
|
||||
} else {
|
||||
cv.onRuntimeInitialized = perf;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,780 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu
|
||||
//
|
||||
// LICENSE AGREEMENT
|
||||
// Copyright (c) 2015 The Regents of the University of California (Regents)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the University nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//M*/
|
||||
|
||||
#include <emscripten/bind.h>
|
||||
|
||||
@INCLUDES@
|
||||
#include "../../../modules/core/src/parallel_impl.hpp"
|
||||
|
||||
#ifdef TEST_WASM_INTRIN
|
||||
#include "../../../modules/core/include/opencv2/core/hal/intrin.hpp"
|
||||
#include "../../../modules/core/include/opencv2/core/utils/trace.hpp"
|
||||
#include "../../../modules/ts/include/opencv2/ts/ts_gtest.h"
|
||||
namespace cv {
|
||||
namespace hal {
|
||||
#include "../../../modules/core/test/test_intrin_utils.hpp"
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace emscripten;
|
||||
using namespace cv;
|
||||
|
||||
using namespace cv::segmentation; // FIXIT
|
||||
|
||||
#ifdef HAVE_OPENCV_OBJDETECT
|
||||
using namespace cv::aruco;
|
||||
typedef aruco::DetectorParameters aruco_DetectorParameters;
|
||||
typedef QRCodeDetectorAruco::Params QRCodeDetectorAruco_Params;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_DNN
|
||||
using namespace cv::dnn;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_FEATURES2D
|
||||
typedef SimpleBlobDetector::Params SimpleBlobDetector_Params;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_VIDEO
|
||||
typedef TrackerMIL::Params TrackerMIL_Params;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_XIMGPROC
|
||||
typedef ximgproc::EdgeDrawing::Params EdgeDrawing_Params;
|
||||
#endif
|
||||
|
||||
// HACK: JS generator ommits namespace for parameter types for some reason. Added typedef to handle std::string correctly
|
||||
typedef std::string string;
|
||||
|
||||
namespace binding_utils
|
||||
{
|
||||
template<typename classT, typename enumT>
|
||||
static inline typename std::underlying_type<enumT>::type classT::* underlying_ptr(enumT classT::* enum_ptr)
|
||||
{
|
||||
return reinterpret_cast<typename std::underlying_type<enumT>::type classT::*>(enum_ptr);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
emscripten::val matData(const cv::Mat& mat)
|
||||
{
|
||||
return emscripten::val(emscripten::memory_view<T>((mat.total()*mat.elemSize())/sizeof(T),
|
||||
(T*)mat.data));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
emscripten::val matPtr(const cv::Mat& mat, int i)
|
||||
{
|
||||
return emscripten::val(emscripten::memory_view<T>(mat.step1(0), mat.ptr<T>(i)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
emscripten::val matPtr(const cv::Mat& mat, int i, int j)
|
||||
{
|
||||
return emscripten::val(emscripten::memory_view<T>(mat.step1(1), mat.ptr<T>(i,j)));
|
||||
}
|
||||
|
||||
cv::Mat* createMat(int rows, int cols, int type, intptr_t data, size_t step)
|
||||
{
|
||||
return new cv::Mat(rows, cols, type, reinterpret_cast<void*>(data), step);
|
||||
}
|
||||
|
||||
static emscripten::val getMatSize(const cv::Mat& mat)
|
||||
{
|
||||
emscripten::val size = emscripten::val::array();
|
||||
for (int i = 0; i < mat.dims; i++) {
|
||||
size.call<void>("push", mat.size[i]);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static emscripten::val getMatStep(const cv::Mat& mat)
|
||||
{
|
||||
emscripten::val step = emscripten::val::array();
|
||||
for (int i = 0; i < mat.dims; i++) {
|
||||
step.call<void>("push", mat.step[i]);
|
||||
}
|
||||
return step;
|
||||
}
|
||||
|
||||
static Mat matEye(int rows, int cols, int type)
|
||||
{
|
||||
return Mat(cv::Mat::eye(rows, cols, type));
|
||||
}
|
||||
|
||||
static Mat matEye(Size size, int type)
|
||||
{
|
||||
return Mat(cv::Mat::eye(size, type));
|
||||
}
|
||||
|
||||
void convertTo(const Mat& obj, Mat& m, int rtype, double alpha, double beta)
|
||||
{
|
||||
obj.convertTo(m, rtype, alpha, beta);
|
||||
}
|
||||
|
||||
void convertTo(const Mat& obj, Mat& m, int rtype)
|
||||
{
|
||||
obj.convertTo(m, rtype);
|
||||
}
|
||||
|
||||
void convertTo(const Mat& obj, Mat& m, int rtype, double alpha)
|
||||
{
|
||||
obj.convertTo(m, rtype, alpha);
|
||||
}
|
||||
|
||||
Size matSize(const cv::Mat& mat)
|
||||
{
|
||||
return mat.size();
|
||||
}
|
||||
|
||||
cv::Mat matZeros(int arg0, int arg1, int arg2)
|
||||
{
|
||||
return cv::Mat::zeros(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
cv::Mat matZeros(cv::Size arg0, int arg1)
|
||||
{
|
||||
return cv::Mat::zeros(arg0,arg1);
|
||||
}
|
||||
|
||||
cv::Mat matOnes(int arg0, int arg1, int arg2)
|
||||
{
|
||||
return cv::Mat::ones(arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
cv::Mat matOnes(cv::Size arg0, int arg1)
|
||||
{
|
||||
return cv::Mat::ones(arg0, arg1);
|
||||
}
|
||||
|
||||
double matDot(const cv::Mat& obj, const Mat& mat)
|
||||
{
|
||||
return obj.dot(mat);
|
||||
}
|
||||
|
||||
Mat matMul(const cv::Mat& obj, const Mat& mat, double scale)
|
||||
{
|
||||
return Mat(obj.mul(mat, scale));
|
||||
}
|
||||
|
||||
Mat matT(const cv::Mat& obj)
|
||||
{
|
||||
return Mat(obj.t());
|
||||
}
|
||||
|
||||
Mat matInv(const cv::Mat& obj, int type)
|
||||
{
|
||||
return Mat(obj.inv(type));
|
||||
}
|
||||
|
||||
void matCopyTo(const cv::Mat& obj, cv::Mat& mat)
|
||||
{
|
||||
return obj.copyTo(mat);
|
||||
}
|
||||
|
||||
void matCopyTo(const cv::Mat& obj, cv::Mat& mat, const cv::Mat& mask)
|
||||
{
|
||||
return obj.copyTo(mat, mask);
|
||||
}
|
||||
|
||||
Mat matDiag(const cv::Mat& obj, int d)
|
||||
{
|
||||
return obj.diag(d);
|
||||
}
|
||||
|
||||
Mat matDiag(const cv::Mat& obj)
|
||||
{
|
||||
return obj.diag();
|
||||
}
|
||||
|
||||
void matSetTo(cv::Mat& obj, const cv::Scalar& s)
|
||||
{
|
||||
obj.setTo(s);
|
||||
}
|
||||
|
||||
void matSetTo(cv::Mat& obj, const cv::Scalar& s, const cv::Mat& mask)
|
||||
{
|
||||
obj.setTo(s, mask);
|
||||
}
|
||||
|
||||
emscripten::val rotatedRectPoints(const cv::RotatedRect& obj)
|
||||
{
|
||||
cv::Point2f points[4];
|
||||
obj.points(points);
|
||||
emscripten::val pointsArray = emscripten::val::array();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
pointsArray.call<void>("push", points[i]);
|
||||
}
|
||||
return pointsArray;
|
||||
}
|
||||
|
||||
Rect rotatedRectBoundingRect(const cv::RotatedRect& obj)
|
||||
{
|
||||
return obj.boundingRect();
|
||||
}
|
||||
|
||||
Rect2f rotatedRectBoundingRect2f(const cv::RotatedRect& obj)
|
||||
{
|
||||
return obj.boundingRect2f();
|
||||
}
|
||||
|
||||
int cvMatDepth(int flags)
|
||||
{
|
||||
return CV_MAT_DEPTH(flags);
|
||||
}
|
||||
|
||||
class MinMaxLoc
|
||||
{
|
||||
public:
|
||||
double minVal;
|
||||
double maxVal;
|
||||
Point minLoc;
|
||||
Point maxLoc;
|
||||
};
|
||||
|
||||
MinMaxLoc minMaxLoc(const cv::Mat& src, const cv::Mat& mask)
|
||||
{
|
||||
MinMaxLoc result;
|
||||
cv::minMaxLoc(src, &result.minVal, &result.maxVal, &result.minLoc, &result.maxLoc, mask);
|
||||
return result;
|
||||
}
|
||||
|
||||
MinMaxLoc minMaxLoc_1(const cv::Mat& src)
|
||||
{
|
||||
MinMaxLoc result;
|
||||
cv::minMaxLoc(src, &result.minVal, &result.maxVal, &result.minLoc, &result.maxLoc);
|
||||
return result;
|
||||
}
|
||||
|
||||
class Circle
|
||||
{
|
||||
public:
|
||||
Point2f center;
|
||||
float radius;
|
||||
};
|
||||
|
||||
#ifdef HAVE_OPENCV_IMGPROC
|
||||
Circle minEnclosingCircle(const cv::Mat& points)
|
||||
{
|
||||
Circle circle;
|
||||
cv::minEnclosingCircle(points, circle.center, circle.radius);
|
||||
return circle;
|
||||
}
|
||||
|
||||
int floodFill_withRect_helper(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5, Scalar arg6 = Scalar(), Scalar arg7 = Scalar(), int arg8 = 4)
|
||||
{
|
||||
cv::Rect rect;
|
||||
|
||||
int rc = cv::floodFill(arg1, arg2, arg3, arg4, &rect, arg6, arg7, arg8);
|
||||
|
||||
arg5.set("x", emscripten::val(rect.x));
|
||||
arg5.set("y", emscripten::val(rect.y));
|
||||
arg5.set("width", emscripten::val(rect.width));
|
||||
arg5.set("height", emscripten::val(rect.height));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int floodFill_wrapper(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5, Scalar arg6, Scalar arg7, int arg8) {
|
||||
return floodFill_withRect_helper(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
||||
}
|
||||
|
||||
int floodFill_wrapper_1(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5, Scalar arg6, Scalar arg7) {
|
||||
return floodFill_withRect_helper(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
}
|
||||
|
||||
int floodFill_wrapper_2(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5, Scalar arg6) {
|
||||
return floodFill_withRect_helper(arg1, arg2, arg3, arg4, arg5, arg6);
|
||||
}
|
||||
|
||||
int floodFill_wrapper_3(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4, emscripten::val arg5) {
|
||||
return floodFill_withRect_helper(arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
|
||||
int floodFill_wrapper_4(cv::Mat& arg1, cv::Mat& arg2, Point arg3, Scalar arg4) {
|
||||
return cv::floodFill(arg1, arg2, arg3, arg4);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_VIDEO
|
||||
emscripten::val CamShiftWrapper(const cv::Mat& arg1, Rect& arg2, TermCriteria arg3)
|
||||
{
|
||||
RotatedRect rotatedRect = cv::CamShift(arg1, arg2, arg3);
|
||||
emscripten::val result = emscripten::val::array();
|
||||
result.call<void>("push", rotatedRect);
|
||||
result.call<void>("push", arg2);
|
||||
return result;
|
||||
}
|
||||
|
||||
emscripten::val meanShiftWrapper(const cv::Mat& arg1, Rect& arg2, TermCriteria arg3)
|
||||
{
|
||||
int n = cv::meanShift(arg1, arg2, arg3);
|
||||
emscripten::val result = emscripten::val::array();
|
||||
result.call<void>("push", n);
|
||||
result.call<void>("push", arg2);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Tracker_init_wrapper(cv::Tracker& arg0, const cv::Mat& arg1, const Rect& arg2)
|
||||
{
|
||||
return arg0.init(arg1, arg2);
|
||||
}
|
||||
|
||||
emscripten::val Tracker_update_wrapper(cv::Tracker& arg0, const cv::Mat& arg1)
|
||||
{
|
||||
Rect rect;
|
||||
bool update = arg0.update(arg1, rect);
|
||||
|
||||
emscripten::val result = emscripten::val::array();
|
||||
result.call<void>("push", update);
|
||||
result.call<void>("push", rect);
|
||||
return result;
|
||||
}
|
||||
#endif // HAVE_OPENCV_VIDEO
|
||||
|
||||
std::string getExceptionMsg(const cv::Exception& e) {
|
||||
return e.msg;
|
||||
}
|
||||
|
||||
void setExceptionMsg(cv::Exception& e, std::string msg) {
|
||||
e.msg = msg;
|
||||
return;
|
||||
}
|
||||
|
||||
cv::Exception exceptionFromPtr(intptr_t ptr) {
|
||||
return *reinterpret_cast<cv::Exception*>(ptr);
|
||||
}
|
||||
|
||||
std::string getBuildInformation() {
|
||||
return cv::getBuildInformation();
|
||||
}
|
||||
|
||||
#ifdef TEST_WASM_INTRIN
|
||||
void test_hal_intrin_uint8() {
|
||||
cv::hal::test_hal_intrin_uint8();
|
||||
}
|
||||
void test_hal_intrin_int8() {
|
||||
cv::hal::test_hal_intrin_int8();
|
||||
}
|
||||
void test_hal_intrin_uint16() {
|
||||
cv::hal::test_hal_intrin_uint16();
|
||||
}
|
||||
void test_hal_intrin_int16() {
|
||||
cv::hal::test_hal_intrin_int16();
|
||||
}
|
||||
void test_hal_intrin_uint32() {
|
||||
cv::hal::test_hal_intrin_uint32();
|
||||
}
|
||||
void test_hal_intrin_int32() {
|
||||
cv::hal::test_hal_intrin_int32();
|
||||
}
|
||||
void test_hal_intrin_uint64() {
|
||||
cv::hal::test_hal_intrin_uint64();
|
||||
}
|
||||
void test_hal_intrin_int64() {
|
||||
cv::hal::test_hal_intrin_int64();
|
||||
}
|
||||
void test_hal_intrin_float32() {
|
||||
cv::hal::test_hal_intrin_float32();
|
||||
}
|
||||
void test_hal_intrin_float64() {
|
||||
cv::hal::test_hal_intrin_float64();
|
||||
}
|
||||
void test_hal_intrin_all() {
|
||||
cv::hal::test_hal_intrin_uint8();
|
||||
cv::hal::test_hal_intrin_int8();
|
||||
cv::hal::test_hal_intrin_uint16();
|
||||
cv::hal::test_hal_intrin_int16();
|
||||
cv::hal::test_hal_intrin_uint32();
|
||||
cv::hal::test_hal_intrin_int32();
|
||||
cv::hal::test_hal_intrin_uint64();
|
||||
cv::hal::test_hal_intrin_int64();
|
||||
cv::hal::test_hal_intrin_float32();
|
||||
cv::hal::test_hal_intrin_float64();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(binding_utils)
|
||||
{
|
||||
register_vector<int>("IntVector");
|
||||
register_vector<char>("CharVector");
|
||||
register_vector<float>("FloatVector");
|
||||
register_vector<double>("DoubleVector");
|
||||
register_vector<std::string>("StringVector");
|
||||
register_vector<cv::Point>("PointVector");
|
||||
register_vector<cv::Point2f>("Point2fVector");
|
||||
register_vector<cv::Point3_<float>>("Point3fVector");
|
||||
register_vector<cv::Mat>("MatVector");
|
||||
register_vector<cv::Rect>("RectVector");
|
||||
register_vector<cv::KeyPoint>("KeyPointVector");
|
||||
register_vector<cv::DMatch>("DMatchVector");
|
||||
register_vector<std::vector<char>>("CharVectorVector");
|
||||
register_vector<std::vector<cv::DMatch>>("DMatchVectorVector");
|
||||
register_vector<std::vector<cv::KeyPoint>>("KeyPointVectorVector");
|
||||
register_vector<std::vector<cv::Point>>("PointVectorVector");
|
||||
|
||||
|
||||
emscripten::class_<cv::Mat>("Mat")
|
||||
.constructor<>()
|
||||
.constructor<const Mat&>()
|
||||
.constructor<Size, int>()
|
||||
.constructor<int, int, int>()
|
||||
.constructor<int, int, int, const Scalar&>()
|
||||
.constructor(&binding_utils::createMat, allow_raw_pointers())
|
||||
|
||||
.class_function("eye", select_overload<Mat(Size, int)>(&binding_utils::matEye))
|
||||
.class_function("eye", select_overload<Mat(int, int, int)>(&binding_utils::matEye))
|
||||
.class_function("ones", select_overload<Mat(Size, int)>(&binding_utils::matOnes))
|
||||
.class_function("ones", select_overload<Mat(int, int, int)>(&binding_utils::matOnes))
|
||||
.class_function("zeros", select_overload<Mat(Size, int)>(&binding_utils::matZeros))
|
||||
.class_function("zeros", select_overload<Mat(int, int, int)>(&binding_utils::matZeros))
|
||||
|
||||
.property("rows", &cv::Mat::rows)
|
||||
.property("cols", &cv::Mat::cols)
|
||||
.property("matSize", &binding_utils::getMatSize)
|
||||
.property("step", &binding_utils::getMatStep)
|
||||
.property("data", &binding_utils::matData<unsigned char>)
|
||||
.property("data8S", &binding_utils::matData<char>)
|
||||
.property("data16U", &binding_utils::matData<unsigned short>)
|
||||
.property("data16S", &binding_utils::matData<short>)
|
||||
.property("data32S", &binding_utils::matData<int>)
|
||||
.property("data32F", &binding_utils::matData<float>)
|
||||
.property("data64F", &binding_utils::matData<double>)
|
||||
|
||||
.function("elemSize", select_overload<size_t()const>(&cv::Mat::elemSize))
|
||||
.function("elemSize1", select_overload<size_t()const>(&cv::Mat::elemSize1))
|
||||
.function("channels", select_overload<int()const>(&cv::Mat::channels))
|
||||
.function("convertTo", select_overload<void(const Mat&, Mat&, int, double, double)>(&binding_utils::convertTo))
|
||||
.function("convertTo", select_overload<void(const Mat&, Mat&, int)>(&binding_utils::convertTo))
|
||||
.function("convertTo", select_overload<void(const Mat&, Mat&, int, double)>(&binding_utils::convertTo))
|
||||
.function("total", select_overload<size_t()const>(&cv::Mat::total))
|
||||
.function("row", select_overload<Mat(int)const>(&cv::Mat::row))
|
||||
.function("create", select_overload<void(int, int, int)>(&cv::Mat::create))
|
||||
.function("create", select_overload<void(Size, int)>(&cv::Mat::create))
|
||||
.function("rowRange", select_overload<Mat(int, int)const>(&cv::Mat::rowRange))
|
||||
.function("rowRange", select_overload<Mat(const Range&)const>(&cv::Mat::rowRange))
|
||||
.function("copyTo", select_overload<void(const Mat&, Mat&)>(&binding_utils::matCopyTo))
|
||||
.function("copyTo", select_overload<void(const Mat&, Mat&, const Mat&)>(&binding_utils::matCopyTo))
|
||||
.function("type", select_overload<int()const>(&cv::Mat::type))
|
||||
.function("empty", select_overload<bool()const>(&cv::Mat::empty))
|
||||
.function("colRange", select_overload<Mat(int, int)const>(&cv::Mat::colRange))
|
||||
.function("colRange", select_overload<Mat(const Range&)const>(&cv::Mat::colRange))
|
||||
.function("step1", select_overload<size_t(int)const>(&cv::Mat::step1))
|
||||
.function("mat_clone", select_overload<Mat()const>(&cv::Mat::clone))
|
||||
.function("depth", select_overload<int()const>(&cv::Mat::depth))
|
||||
.function("col", select_overload<Mat(int)const>(&cv::Mat::col))
|
||||
.function("dot", select_overload<double(const Mat&, const Mat&)>(&binding_utils::matDot))
|
||||
.function("mul", select_overload<Mat(const Mat&, const Mat&, double)>(&binding_utils::matMul))
|
||||
.function("inv", select_overload<Mat(const Mat&, int)>(&binding_utils::matInv))
|
||||
.function("t", select_overload<Mat(const Mat&)>(&binding_utils::matT))
|
||||
.function("roi", select_overload<Mat(const Rect&)const>(&cv::Mat::operator()))
|
||||
.function("diag", select_overload<Mat(const Mat&, int)>(&binding_utils::matDiag))
|
||||
.function("diag", select_overload<Mat(const Mat&)>(&binding_utils::matDiag))
|
||||
.function("isContinuous", select_overload<bool()const>(&cv::Mat::isContinuous))
|
||||
.function("setTo", select_overload<void(Mat&, const Scalar&)>(&binding_utils::matSetTo))
|
||||
.function("setTo", select_overload<void(Mat&, const Scalar&, const Mat&)>(&binding_utils::matSetTo))
|
||||
.function("size", select_overload<Size(const Mat&)>(&binding_utils::matSize))
|
||||
|
||||
.function("ptr", select_overload<val(const Mat&, int)>(&binding_utils::matPtr<unsigned char>))
|
||||
.function("ptr", select_overload<val(const Mat&, int, int)>(&binding_utils::matPtr<unsigned char>))
|
||||
.function("ucharPtr", select_overload<val(const Mat&, int)>(&binding_utils::matPtr<unsigned char>))
|
||||
.function("ucharPtr", select_overload<val(const Mat&, int, int)>(&binding_utils::matPtr<unsigned char>))
|
||||
.function("charPtr", select_overload<val(const Mat&, int)>(&binding_utils::matPtr<char>))
|
||||
.function("charPtr", select_overload<val(const Mat&, int, int)>(&binding_utils::matPtr<char>))
|
||||
.function("shortPtr", select_overload<val(const Mat&, int)>(&binding_utils::matPtr<short>))
|
||||
.function("shortPtr", select_overload<val(const Mat&, int, int)>(&binding_utils::matPtr<short>))
|
||||
.function("ushortPtr", select_overload<val(const Mat&, int)>(&binding_utils::matPtr<unsigned short>))
|
||||
.function("ushortPtr", select_overload<val(const Mat&, int, int)>(&binding_utils::matPtr<unsigned short>))
|
||||
.function("intPtr", select_overload<val(const Mat&, int)>(&binding_utils::matPtr<int>))
|
||||
.function("intPtr", select_overload<val(const Mat&, int, int)>(&binding_utils::matPtr<int>))
|
||||
.function("floatPtr", select_overload<val(const Mat&, int)>(&binding_utils::matPtr<float>))
|
||||
.function("floatPtr", select_overload<val(const Mat&, int, int)>(&binding_utils::matPtr<float>))
|
||||
.function("doublePtr", select_overload<val(const Mat&, int)>(&binding_utils::matPtr<double>))
|
||||
.function("doublePtr", select_overload<val(const Mat&, int, int)>(&binding_utils::matPtr<double>))
|
||||
|
||||
.function("charAt", select_overload<char&(int)>(&cv::Mat::at<char>))
|
||||
.function("charAt", select_overload<char&(int, int)>(&cv::Mat::at<char>))
|
||||
.function("charAt", select_overload<char&(int, int, int)>(&cv::Mat::at<char>))
|
||||
.function("ucharAt", select_overload<unsigned char&(int)>(&cv::Mat::at<unsigned char>))
|
||||
.function("ucharAt", select_overload<unsigned char&(int, int)>(&cv::Mat::at<unsigned char>))
|
||||
.function("ucharAt", select_overload<unsigned char&(int, int, int)>(&cv::Mat::at<unsigned char>))
|
||||
.function("shortAt", select_overload<short&(int)>(&cv::Mat::at<short>))
|
||||
.function("shortAt", select_overload<short&(int, int)>(&cv::Mat::at<short>))
|
||||
.function("shortAt", select_overload<short&(int, int, int)>(&cv::Mat::at<short>))
|
||||
.function("ushortAt", select_overload<unsigned short&(int)>(&cv::Mat::at<unsigned short>))
|
||||
.function("ushortAt", select_overload<unsigned short&(int, int)>(&cv::Mat::at<unsigned short>))
|
||||
.function("ushortAt", select_overload<unsigned short&(int, int, int)>(&cv::Mat::at<unsigned short>))
|
||||
.function("intAt", select_overload<int&(int)>(&cv::Mat::at<int>) )
|
||||
.function("intAt", select_overload<int&(int, int)>(&cv::Mat::at<int>) )
|
||||
.function("intAt", select_overload<int&(int, int, int)>(&cv::Mat::at<int>) )
|
||||
.function("floatAt", select_overload<float&(int)>(&cv::Mat::at<float>))
|
||||
.function("floatAt", select_overload<float&(int, int)>(&cv::Mat::at<float>))
|
||||
.function("floatAt", select_overload<float&(int, int, int)>(&cv::Mat::at<float>))
|
||||
.function("doubleAt", select_overload<double&(int, int, int)>(&cv::Mat::at<double>))
|
||||
.function("doubleAt", select_overload<double&(int)>(&cv::Mat::at<double>))
|
||||
.function("doubleAt", select_overload<double&(int, int)>(&cv::Mat::at<double>));
|
||||
|
||||
emscripten::value_object<cv::Range>("Range")
|
||||
.field("start", &cv::Range::start)
|
||||
.field("end", &cv::Range::end);
|
||||
|
||||
emscripten::value_object<cv::TermCriteria>("TermCriteria")
|
||||
.field("type", &cv::TermCriteria::type)
|
||||
.field("maxCount", &cv::TermCriteria::maxCount)
|
||||
.field("epsilon", &cv::TermCriteria::epsilon);
|
||||
|
||||
#define EMSCRIPTEN_CV_SIZE(type) \
|
||||
emscripten::value_object<type>(#type) \
|
||||
.field("width", &type::width) \
|
||||
.field("height", &type::height);
|
||||
|
||||
EMSCRIPTEN_CV_SIZE(Size)
|
||||
EMSCRIPTEN_CV_SIZE(Size2f)
|
||||
|
||||
#define EMSCRIPTEN_CV_POINT(type) \
|
||||
emscripten::value_object<type>(#type) \
|
||||
.field("x", &type::x) \
|
||||
.field("y", &type::y); \
|
||||
|
||||
EMSCRIPTEN_CV_POINT(Point)
|
||||
EMSCRIPTEN_CV_POINT(Point2f)
|
||||
EMSCRIPTEN_CV_POINT(Point3f)
|
||||
|
||||
#define EMSCRIPTEN_CV_RECT(type, name) \
|
||||
emscripten::value_object<cv::Rect_<type>> (name) \
|
||||
.field("x", &cv::Rect_<type>::x) \
|
||||
.field("y", &cv::Rect_<type>::y) \
|
||||
.field("width", &cv::Rect_<type>::width) \
|
||||
.field("height", &cv::Rect_<type>::height);
|
||||
|
||||
EMSCRIPTEN_CV_RECT(int, "Rect")
|
||||
EMSCRIPTEN_CV_RECT(float, "Rect2f")
|
||||
EMSCRIPTEN_CV_RECT(double, "Rect2d")
|
||||
|
||||
emscripten::value_object<cv::RotatedRect>("RotatedRect")
|
||||
.field("center", &cv::RotatedRect::center)
|
||||
.field("size", &cv::RotatedRect::size)
|
||||
.field("angle", &cv::RotatedRect::angle);
|
||||
|
||||
emscripten::value_object<cv::KeyPoint>("KeyPoint")
|
||||
.field("angle", &cv::KeyPoint::angle)
|
||||
.field("class_id", &cv::KeyPoint::class_id)
|
||||
.field("octave", &cv::KeyPoint::octave)
|
||||
.field("pt", &cv::KeyPoint::pt)
|
||||
.field("response", &cv::KeyPoint::response)
|
||||
.field("size", &cv::KeyPoint::size);
|
||||
|
||||
emscripten::value_object<cv::DMatch>("DMatch")
|
||||
.field("queryIdx", &cv::DMatch::queryIdx)
|
||||
.field("trainIdx", &cv::DMatch::trainIdx)
|
||||
.field("imgIdx", &cv::DMatch::imgIdx)
|
||||
.field("distance", &cv::DMatch::distance);
|
||||
|
||||
emscripten::value_array<cv::Scalar_<double>> ("Scalar")
|
||||
.element(emscripten::index<0>())
|
||||
.element(emscripten::index<1>())
|
||||
.element(emscripten::index<2>())
|
||||
.element(emscripten::index<3>());
|
||||
|
||||
emscripten::value_object<binding_utils::MinMaxLoc>("MinMaxLoc")
|
||||
.field("minVal", &binding_utils::MinMaxLoc::minVal)
|
||||
.field("maxVal", &binding_utils::MinMaxLoc::maxVal)
|
||||
.field("minLoc", &binding_utils::MinMaxLoc::minLoc)
|
||||
.field("maxLoc", &binding_utils::MinMaxLoc::maxLoc);
|
||||
|
||||
emscripten::value_object<cv::Exception>("Exception")
|
||||
.field("code", &cv::Exception::code)
|
||||
.field("msg", &binding_utils::getExceptionMsg, &binding_utils::setExceptionMsg);
|
||||
|
||||
emscripten::value_object<binding_utils::Circle>("Circle")
|
||||
.field("center", &binding_utils::Circle::center)
|
||||
.field("radius", &binding_utils::Circle::radius);
|
||||
|
||||
function("boxPoints", select_overload<emscripten::val(const cv::RotatedRect&)>(&binding_utils::rotatedRectPoints));
|
||||
function("rotatedRectPoints", select_overload<emscripten::val(const cv::RotatedRect&)>(&binding_utils::rotatedRectPoints));
|
||||
function("rotatedRectBoundingRect", select_overload<Rect(const cv::RotatedRect&)>(&binding_utils::rotatedRectBoundingRect));
|
||||
function("rotatedRectBoundingRect2f", select_overload<Rect2f(const cv::RotatedRect&)>(&binding_utils::rotatedRectBoundingRect2f));
|
||||
function("exceptionFromPtr", &binding_utils::exceptionFromPtr, allow_raw_pointers());
|
||||
function("minMaxLoc", select_overload<binding_utils::MinMaxLoc(const cv::Mat&, const cv::Mat&)>(&binding_utils::minMaxLoc));
|
||||
function("minMaxLoc", select_overload<binding_utils::MinMaxLoc(const cv::Mat&)>(&binding_utils::minMaxLoc_1));
|
||||
function("CV_MAT_DEPTH", &binding_utils::cvMatDepth);
|
||||
function("getBuildInformation", &binding_utils::getBuildInformation);
|
||||
|
||||
#ifdef HAVE_OPENCV_IMGPROC
|
||||
emscripten::value_object<cv::Moments >("Moments")
|
||||
.field("m00", &cv::Moments::m00)
|
||||
.field("m10", &cv::Moments::m10)
|
||||
.field("m01", &cv::Moments::m01)
|
||||
.field("m20", &cv::Moments::m20)
|
||||
.field("m11", &cv::Moments::m11)
|
||||
.field("m02", &cv::Moments::m02)
|
||||
.field("m30", &cv::Moments::m30)
|
||||
.field("m21", &cv::Moments::m21)
|
||||
.field("m12", &cv::Moments::m12)
|
||||
.field("m03", &cv::Moments::m03)
|
||||
.field("mu20", &cv::Moments::mu20)
|
||||
.field("mu11", &cv::Moments::mu11)
|
||||
.field("mu02", &cv::Moments::mu02)
|
||||
.field("mu30", &cv::Moments::mu30)
|
||||
.field("mu21", &cv::Moments::mu21)
|
||||
.field("mu12", &cv::Moments::mu12)
|
||||
.field("mu03", &cv::Moments::mu03)
|
||||
.field("nu20", &cv::Moments::nu20)
|
||||
.field("nu11", &cv::Moments::nu11)
|
||||
.field("nu02", &cv::Moments::nu02)
|
||||
.field("nu30", &cv::Moments::nu30)
|
||||
.field("nu21", &cv::Moments::nu21)
|
||||
.field("nu12", &cv::Moments::nu12)
|
||||
.field("nu03", &cv::Moments::nu03);
|
||||
|
||||
function("minEnclosingCircle", select_overload<binding_utils::Circle(const cv::Mat&)>(&binding_utils::minEnclosingCircle));
|
||||
function("floodFill", select_overload<int(cv::Mat&, cv::Mat&, Point, Scalar, emscripten::val, Scalar, Scalar, int)>(&binding_utils::floodFill_wrapper));
|
||||
function("floodFill", select_overload<int(cv::Mat&, cv::Mat&, Point, Scalar, emscripten::val, Scalar, Scalar)>(&binding_utils::floodFill_wrapper_1));
|
||||
function("floodFill", select_overload<int(cv::Mat&, cv::Mat&, Point, Scalar, emscripten::val, Scalar)>(&binding_utils::floodFill_wrapper_2));
|
||||
function("floodFill", select_overload<int(cv::Mat&, cv::Mat&, Point, Scalar, emscripten::val)>(&binding_utils::floodFill_wrapper_3));
|
||||
function("floodFill", select_overload<int(cv::Mat&, cv::Mat&, Point, Scalar)>(&binding_utils::floodFill_wrapper_4));
|
||||
function("morphologyDefaultBorderValue", &cv::morphologyDefaultBorderValue);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCV_VIDEO
|
||||
function("CamShift", select_overload<emscripten::val(const cv::Mat&, Rect&, TermCriteria)>(&binding_utils::CamShiftWrapper));
|
||||
function("meanShift", select_overload<emscripten::val(const cv::Mat&, Rect&, TermCriteria)>(&binding_utils::meanShiftWrapper));
|
||||
|
||||
emscripten::class_<cv::Tracker >("Tracker")
|
||||
.function("init", select_overload<void(cv::Tracker&,const cv::Mat&,const Rect&)>(&binding_utils::Tracker_init_wrapper), pure_virtual())
|
||||
.function("update", select_overload<emscripten::val(cv::Tracker&,const cv::Mat&)>(&binding_utils::Tracker_update_wrapper), pure_virtual());
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PTHREADS_PF
|
||||
function("parallel_pthreads_set_threads_num", &cv::parallel_pthreads_set_threads_num);
|
||||
function("parallel_pthreads_get_threads_num", &cv::parallel_pthreads_get_threads_num);
|
||||
#endif
|
||||
|
||||
#ifdef TEST_WASM_INTRIN
|
||||
function("test_hal_intrin_uint8", &binding_utils::test_hal_intrin_uint8);
|
||||
function("test_hal_intrin_int8", &binding_utils::test_hal_intrin_int8);
|
||||
function("test_hal_intrin_uint16", &binding_utils::test_hal_intrin_uint16);
|
||||
function("test_hal_intrin_int16", &binding_utils::test_hal_intrin_int16);
|
||||
function("test_hal_intrin_uint32", &binding_utils::test_hal_intrin_uint32);
|
||||
function("test_hal_intrin_int32", &binding_utils::test_hal_intrin_int32);
|
||||
function("test_hal_intrin_uint64", &binding_utils::test_hal_intrin_uint64);
|
||||
function("test_hal_intrin_int64", &binding_utils::test_hal_intrin_int64);
|
||||
function("test_hal_intrin_float32", &binding_utils::test_hal_intrin_float32);
|
||||
function("test_hal_intrin_float64", &binding_utils::test_hal_intrin_float64);
|
||||
function("test_hal_intrin_all", &binding_utils::test_hal_intrin_all);
|
||||
#endif
|
||||
|
||||
constant("CV_8UC1", CV_8UC1);
|
||||
constant("CV_8UC2", CV_8UC2);
|
||||
constant("CV_8UC3", CV_8UC3);
|
||||
constant("CV_8UC4", CV_8UC4);
|
||||
|
||||
constant("CV_8SC1", CV_8SC1);
|
||||
constant("CV_8SC2", CV_8SC2);
|
||||
constant("CV_8SC3", CV_8SC3);
|
||||
constant("CV_8SC4", CV_8SC4);
|
||||
|
||||
constant("CV_16UC1", CV_16UC1);
|
||||
constant("CV_16UC2", CV_16UC2);
|
||||
constant("CV_16UC3", CV_16UC3);
|
||||
constant("CV_16UC4", CV_16UC4);
|
||||
|
||||
constant("CV_16SC1", CV_16SC1);
|
||||
constant("CV_16SC2", CV_16SC2);
|
||||
constant("CV_16SC3", CV_16SC3);
|
||||
constant("CV_16SC4", CV_16SC4);
|
||||
|
||||
constant("CV_32SC1", CV_32SC1);
|
||||
constant("CV_32SC2", CV_32SC2);
|
||||
constant("CV_32SC3", CV_32SC3);
|
||||
constant("CV_32SC4", CV_32SC4);
|
||||
|
||||
constant("CV_32FC1", CV_32FC1);
|
||||
constant("CV_32FC2", CV_32FC2);
|
||||
constant("CV_32FC3", CV_32FC3);
|
||||
constant("CV_32FC4", CV_32FC4);
|
||||
|
||||
constant("CV_64FC1", CV_64FC1);
|
||||
constant("CV_64FC2", CV_64FC2);
|
||||
constant("CV_64FC3", CV_64FC3);
|
||||
constant("CV_64FC4", CV_64FC4);
|
||||
|
||||
constant("CV_8U", CV_8U);
|
||||
constant("CV_8S", CV_8S);
|
||||
constant("CV_16U", CV_16U);
|
||||
constant("CV_16S", CV_16S);
|
||||
constant("CV_32S", CV_32S);
|
||||
constant("CV_32F", CV_32F);
|
||||
constant("CV_64F", CV_64F);
|
||||
|
||||
constant("INT_MIN", INT_MIN);
|
||||
constant("INT_MAX", INT_MAX);
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
|
||||
if (typeof Module.FS === 'undefined' && typeof FS !== 'undefined') {
|
||||
Module.FS = FS;
|
||||
}
|
||||
|
||||
if (typeof cv === 'undefined') {
|
||||
var cv = Module;
|
||||
}
|
||||
|
||||
Module['imread'] = function(imageSource) {
|
||||
var img = null;
|
||||
if (typeof imageSource === 'string') {
|
||||
img = document.getElementById(imageSource);
|
||||
} else {
|
||||
img = imageSource;
|
||||
}
|
||||
var canvas = null;
|
||||
var ctx = null;
|
||||
if (img instanceof HTMLImageElement) {
|
||||
canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height);
|
||||
} else if (img instanceof HTMLCanvasElement || img instanceof OffscreenCanvas) {
|
||||
canvas = img;
|
||||
ctx = canvas.getContext('2d');
|
||||
} else {
|
||||
throw new Error('Please input the valid canvas or img id.');
|
||||
}
|
||||
|
||||
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
return cv.matFromImageData(imgData);
|
||||
};
|
||||
|
||||
Module['imshow'] = function(canvasSource, mat) {
|
||||
var canvas = null;
|
||||
if (typeof canvasSource === 'string') {
|
||||
canvas = document.getElementById(canvasSource);
|
||||
} else {
|
||||
canvas = canvasSource;
|
||||
}
|
||||
if (!(canvas instanceof HTMLCanvasElement)) {
|
||||
throw new Error('Please input the valid canvas element or id.');
|
||||
}
|
||||
if (!(mat instanceof cv.Mat)) {
|
||||
throw new Error('Please input the valid cv.Mat instance.');
|
||||
}
|
||||
|
||||
// convert the mat type to cv.CV_8U
|
||||
var img = new cv.Mat();
|
||||
var depth = mat.type()%8;
|
||||
var scale = depth <= cv.CV_8S? 1.0 : (depth <= cv.CV_32S? 1.0/256.0 : 255.0);
|
||||
var shift = (depth === cv.CV_8S || depth === cv.CV_16S)? 128.0 : 0.0;
|
||||
mat.convertTo(img, cv.CV_8U, scale, shift);
|
||||
|
||||
// convert the img type to cv.CV_8UC4
|
||||
switch (img.type()) {
|
||||
case cv.CV_8UC1:
|
||||
cv.cvtColor(img, img, cv.COLOR_GRAY2RGBA);
|
||||
break;
|
||||
case cv.CV_8UC3:
|
||||
cv.cvtColor(img, img, cv.COLOR_RGB2RGBA);
|
||||
break;
|
||||
case cv.CV_8UC4:
|
||||
break;
|
||||
default:
|
||||
throw new Error('Bad number of channels (Source image must have 1, 3 or 4 channels)');
|
||||
}
|
||||
var imgData = new ImageData(new Uint8ClampedArray(img.data), img.cols, img.rows);
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
canvas.width = imgData.width;
|
||||
canvas.height = imgData.height;
|
||||
ctx.putImageData(imgData, 0, 0);
|
||||
img.delete();
|
||||
};
|
||||
|
||||
Module['VideoCapture'] = function(videoSource) {
|
||||
var video = null;
|
||||
if (typeof videoSource === 'string') {
|
||||
video = document.getElementById(videoSource);
|
||||
} else {
|
||||
video = videoSource;
|
||||
}
|
||||
if (!(video instanceof HTMLVideoElement)) {
|
||||
throw new Error('Please input the valid video element or id.');
|
||||
}
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = video.width;
|
||||
canvas.height = video.height;
|
||||
var ctx = canvas.getContext('2d');
|
||||
this.video = video;
|
||||
this.read = function(frame) {
|
||||
if (!(frame instanceof cv.Mat)) {
|
||||
throw new Error('Please input the valid cv.Mat instance.');
|
||||
}
|
||||
if (frame.type() !== cv.CV_8UC4) {
|
||||
throw new Error('Bad type of input mat: the type should be cv.CV_8UC4.');
|
||||
}
|
||||
if (frame.cols !== video.width || frame.rows !== video.height) {
|
||||
throw new Error('Bad size of input mat: the size should be same as the video.');
|
||||
}
|
||||
ctx.drawImage(video, 0, 0, video.width, video.height);
|
||||
frame.data.set(ctx.getImageData(0, 0, video.width, video.height).data);
|
||||
};
|
||||
};
|
||||
|
||||
function Range(start, end) {
|
||||
this.start = typeof(start) === 'undefined' ? 0 : start;
|
||||
this.end = typeof(end) === 'undefined' ? 0 : end;
|
||||
}
|
||||
|
||||
Module['Range'] = Range;
|
||||
|
||||
function Point(x, y) {
|
||||
this.x = typeof(x) === 'undefined' ? 0 : x;
|
||||
this.y = typeof(y) === 'undefined' ? 0 : y;
|
||||
}
|
||||
|
||||
Module['Point'] = Point;
|
||||
|
||||
function Size(width, height) {
|
||||
this.width = typeof(width) === 'undefined' ? 0 : width;
|
||||
this.height = typeof(height) === 'undefined' ? 0 : height;
|
||||
}
|
||||
|
||||
Module['Size'] = Size;
|
||||
|
||||
function Rect() {
|
||||
switch (arguments.length) {
|
||||
case 0: {
|
||||
// new cv.Rect()
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
// new cv.Rect(rect)
|
||||
var rect = arguments[0];
|
||||
this.x = rect.x;
|
||||
this.y = rect.y;
|
||||
this.width = rect.width;
|
||||
this.height = rect.height;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// new cv.Rect(point, size)
|
||||
var point = arguments[0];
|
||||
var size = arguments[1];
|
||||
this.x = point.x;
|
||||
this.y = point.y;
|
||||
this.width = size.width;
|
||||
this.height = size.height;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
// new cv.Rect(x, y, width, height)
|
||||
this.x = arguments[0];
|
||||
this.y = arguments[1];
|
||||
this.width = arguments[2];
|
||||
this.height = arguments[3];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error('Invalid arguments');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Module['Rect'] = Rect;
|
||||
|
||||
function RotatedRect() {
|
||||
switch (arguments.length) {
|
||||
case 0: {
|
||||
this.center = {x: 0, y: 0};
|
||||
this.size = {width: 0, height: 0};
|
||||
this.angle = 0;
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
this.center = arguments[0];
|
||||
this.size = arguments[1];
|
||||
this.angle = arguments[2];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error('Invalid arguments');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RotatedRect.points = function(obj) {
|
||||
return Module.rotatedRectPoints(obj);
|
||||
};
|
||||
|
||||
RotatedRect.boundingRect = function(obj) {
|
||||
return Module.rotatedRectBoundingRect(obj);
|
||||
};
|
||||
|
||||
RotatedRect.boundingRect2f = function(obj) {
|
||||
return Module.rotatedRectBoundingRect2f(obj);
|
||||
};
|
||||
|
||||
Module['RotatedRect'] = RotatedRect;
|
||||
|
||||
function Scalar(v0, v1, v2, v3) {
|
||||
this.push(typeof(v0) === 'undefined' ? 0 : v0);
|
||||
this.push(typeof(v1) === 'undefined' ? 0 : v1);
|
||||
this.push(typeof(v2) === 'undefined' ? 0 : v2);
|
||||
this.push(typeof(v3) === 'undefined' ? 0 : v3);
|
||||
}
|
||||
|
||||
Scalar.prototype = new Array; // eslint-disable-line no-array-constructor
|
||||
|
||||
Scalar.all = function(v) {
|
||||
return Scalar(v, v, v, v);
|
||||
};
|
||||
|
||||
Module['Scalar'] = Scalar;
|
||||
|
||||
function MinMaxLoc() {
|
||||
switch (arguments.length) {
|
||||
case 0: {
|
||||
this.minVal = 0;
|
||||
this.maxVal = 0;
|
||||
this.minLoc = Point(0, 0);
|
||||
this.maxLoc = Point(0, 0);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
this.minVal = arguments[0];
|
||||
this.maxVal = arguments[1];
|
||||
this.minLoc = arguments[2];
|
||||
this.maxLoc = arguments[3];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error('Invalid arguments');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Module['MinMaxLoc'] = MinMaxLoc;
|
||||
|
||||
function Circle() {
|
||||
switch (arguments.length) {
|
||||
case 0: {
|
||||
this.center = Point(0, 0);
|
||||
this.radius = 0;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
this.center = arguments[0];
|
||||
this.radius = arguments[1];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error('Invalid arguments');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Module['Circle'] = Circle;
|
||||
|
||||
function TermCriteria() {
|
||||
switch (arguments.length) {
|
||||
case 0: {
|
||||
this.type = 0;
|
||||
this.maxCount = 0;
|
||||
this.epsilon = 0;
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
this.type = arguments[0];
|
||||
this.maxCount = arguments[1];
|
||||
this.epsilon = arguments[2];
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error('Invalid arguments');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Module['TermCriteria'] = TermCriteria;
|
||||
|
||||
Module['matFromArray'] = function(rows, cols, type, array) {
|
||||
var mat = new cv.Mat(rows, cols, type);
|
||||
switch (type) {
|
||||
case cv.CV_8U:
|
||||
case cv.CV_8UC1:
|
||||
case cv.CV_8UC2:
|
||||
case cv.CV_8UC3:
|
||||
case cv.CV_8UC4: {
|
||||
mat.data.set(array);
|
||||
break;
|
||||
}
|
||||
case cv.CV_8S:
|
||||
case cv.CV_8SC1:
|
||||
case cv.CV_8SC2:
|
||||
case cv.CV_8SC3:
|
||||
case cv.CV_8SC4: {
|
||||
mat.data8S.set(array);
|
||||
break;
|
||||
}
|
||||
case cv.CV_16U:
|
||||
case cv.CV_16UC1:
|
||||
case cv.CV_16UC2:
|
||||
case cv.CV_16UC3:
|
||||
case cv.CV_16UC4: {
|
||||
mat.data16U.set(array);
|
||||
break;
|
||||
}
|
||||
case cv.CV_16S:
|
||||
case cv.CV_16SC1:
|
||||
case cv.CV_16SC2:
|
||||
case cv.CV_16SC3:
|
||||
case cv.CV_16SC4: {
|
||||
mat.data16S.set(array);
|
||||
break;
|
||||
}
|
||||
case cv.CV_32S:
|
||||
case cv.CV_32SC1:
|
||||
case cv.CV_32SC2:
|
||||
case cv.CV_32SC3:
|
||||
case cv.CV_32SC4: {
|
||||
mat.data32S.set(array);
|
||||
break;
|
||||
}
|
||||
case cv.CV_32F:
|
||||
case cv.CV_32FC1:
|
||||
case cv.CV_32FC2:
|
||||
case cv.CV_32FC3:
|
||||
case cv.CV_32FC4: {
|
||||
mat.data32F.set(array);
|
||||
break;
|
||||
}
|
||||
case cv.CV_64F:
|
||||
case cv.CV_64FC1:
|
||||
case cv.CV_64FC2:
|
||||
case cv.CV_64FC3:
|
||||
case cv.CV_64FC4: {
|
||||
mat.data64F.set(array);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error('Type is unsupported');
|
||||
}
|
||||
}
|
||||
return mat;
|
||||
};
|
||||
|
||||
Module['matFromImageData'] = function(imageData) {
|
||||
var mat = new cv.Mat(imageData.height, imageData.width, cv.CV_8UC4);
|
||||
mat.data.set(imageData.data);
|
||||
return mat;
|
||||
};
|
||||
// Add Symbol.dispose support for using declaration in TypeScript 5.2+ and future JS
|
||||
if (
|
||||
typeof Symbol !== "undefined" &&
|
||||
Symbol.dispose &&
|
||||
typeof cv !== "undefined" &&
|
||||
cv.Mat &&
|
||||
typeof cv.Mat.prototype.delete === "function"
|
||||
) {
|
||||
cv.Mat.prototype[Symbol.dispose] = cv.Mat.prototype.delete;
|
||||
// Optionally repeat for other types that require manual cleanup:
|
||||
if (cv.UMat) cv.UMat.prototype[Symbol.dispose] = cv.UMat.prototype.delete;
|
||||
// Add more as OpenCV gains new manual-cleanup classes
|
||||
}
|
||||
|
||||
// Override Emscripten's shallow clone() with OpenCV's deep copy mat_clone()
|
||||
// This restores the expected behavior where clone() performs a deep copy.
|
||||
// Background: Emscripten 3.1.71+ added ClassHandle.clone() which only does shallow copy.
|
||||
// See: https://github.com/opencv/opencv/pull/26643
|
||||
// See: https://github.com/opencv/opencv/issues/27572
|
||||
var _opencv_onRuntimeInitialized_backup = Module['onRuntimeInitialized'];
|
||||
Module['onRuntimeInitialized'] = function() {
|
||||
if (_opencv_onRuntimeInitialized_backup) {
|
||||
_opencv_onRuntimeInitialized_backup();
|
||||
}
|
||||
if (typeof cv !== 'undefined' && cv.Mat &&
|
||||
typeof cv.Mat.prototype.mat_clone === 'function') {
|
||||
cv.Mat.prototype.clone = cv.Mat.prototype.mat_clone;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,101 @@
|
||||
async function loadOpenCV(paths, onloadCallback) {
|
||||
let OPENCV_URL = "";
|
||||
let asmPath = "";
|
||||
let wasmPath = "";
|
||||
let simdPath = "";
|
||||
let threadsPath = "";
|
||||
let threadsSimdPath = "";
|
||||
|
||||
if(!(paths instanceof Object)) {
|
||||
throw new Error("The first input should be a object that points the path to the OpenCV.js");
|
||||
}
|
||||
|
||||
if ("asm" in paths) {
|
||||
asmPath = paths["asm"];
|
||||
}
|
||||
|
||||
if ("wasm" in paths) {
|
||||
wasmPath = paths["wasm"];
|
||||
}
|
||||
|
||||
if ("threads" in paths) {
|
||||
threadsPath = paths["threads"];
|
||||
}
|
||||
|
||||
if ("simd" in paths) {
|
||||
simdPath = paths["simd"];
|
||||
}
|
||||
|
||||
if ("threadsSimd" in paths) {
|
||||
threadsSimdPath = paths["threadsSimd"];
|
||||
}
|
||||
|
||||
let wasmSupported = !(typeof WebAssembly === 'undefined');
|
||||
if (!wasmSupported && OPENCV_URL === "" && asmPath != "") {
|
||||
OPENCV_URL = asmPath;
|
||||
console.log("The OpenCV.js for Asm.js is loaded now");
|
||||
} else if (!wasmSupported && asmPath == ""){
|
||||
throw new Error("The browser supports the Asm.js only, but the path of OpenCV.js for Asm.js is empty");
|
||||
}
|
||||
|
||||
let simdSupported = wasmSupported ? await wasmFeatureDetect.simd() : false;
|
||||
let threadsSupported = wasmSupported ? await wasmFeatureDetect.threads() : false;
|
||||
|
||||
if (simdSupported && threadsSupported && threadsSimdPath != "") {
|
||||
OPENCV_URL = threadsSimdPath;
|
||||
console.log("The OpenCV.js with simd and threads optimization is loaded now");
|
||||
} else if (simdSupported && simdPath != "") {
|
||||
if (threadsSupported && threadsSimdPath === "") {
|
||||
console.log("The browser supports simd and threads, but the path of OpenCV.js with simd and threads optimization is empty");
|
||||
}
|
||||
OPENCV_URL = simdPath;
|
||||
console.log("The OpenCV.js with simd optimization is loaded now.");
|
||||
} else if (threadsSupported && threadsPath != "") {
|
||||
if (simdSupported && threadsSimdPath === "") {
|
||||
console.log("The browser supports simd and threads, but the path of OpenCV.js with simd and threads optimization is empty");
|
||||
}
|
||||
OPENCV_URL = threadsPath;
|
||||
console.log("The OpenCV.js with threads optimization is loaded now");
|
||||
} else if (wasmSupported && wasmPath != "") {
|
||||
if(simdSupported && threadsSupported) {
|
||||
console.log("The browser supports simd and threads, but the path of OpenCV.js with simd and threads optimization is empty");
|
||||
}
|
||||
|
||||
if (simdSupported) {
|
||||
console.log("The browser supports simd optimization, but the path of OpenCV.js with simd optimization is empty");
|
||||
}
|
||||
|
||||
if (threadsSupported) {
|
||||
console.log("The browser supports threads optimization, but the path of OpenCV.js with threads optimization is empty");
|
||||
}
|
||||
|
||||
OPENCV_URL = wasmPath;
|
||||
console.log("The OpenCV.js for wasm is loaded now");
|
||||
} else if (wasmSupported) {
|
||||
console.log("The browser supports wasm, but the path of OpenCV.js for wasm is empty");
|
||||
|
||||
if (asmPath != "") {
|
||||
OPENCV_URL = asmPath;
|
||||
console.log("The OpenCV.js for Asm.js is loaded as fallback.");
|
||||
}
|
||||
}
|
||||
|
||||
if (OPENCV_URL === "") {
|
||||
throw new Error("No available OpenCV.js, please check your paths");
|
||||
}
|
||||
|
||||
let script = document.createElement('script');
|
||||
script.setAttribute('async', '');
|
||||
script.setAttribute('type', 'text/javascript');
|
||||
script.addEventListener('load', () => {
|
||||
onloadCallback();
|
||||
});
|
||||
script.addEventListener('error', () => {
|
||||
console.log('Failed to load opencv.js');
|
||||
});
|
||||
script.src = OPENCV_URL;
|
||||
let node = document.getElementsByTagName('script')[0];
|
||||
if (node.src != OPENCV_URL) {
|
||||
node.parentNode.insertBefore(script, node);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
###############################################################################
|
||||
#
|
||||
# IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
#
|
||||
# By downloading, copying, installing or using the software you agree to this license.
|
||||
# If you do not agree to this license, do not download, install,
|
||||
# copy or use the software.
|
||||
#
|
||||
#
|
||||
# License Agreement
|
||||
# For Open Source Computer Vision Library
|
||||
#
|
||||
# Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
# Third party copyrights are property of their respective owners.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# * Redistribution's of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * The name of the copyright holders may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# This software is provided by the copyright holders and contributors "as is" and
|
||||
# any express or implied warranties, including, but not limited to, the implied
|
||||
# warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
# In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
# indirect, incidental, special, exemplary, or consequential damages
|
||||
# (including, but not limited to, procurement of substitute goods or services;
|
||||
# loss of use, data, or profits; or business interruption) however caused
|
||||
# and on any theory of liability, whether in contract, strict liability,
|
||||
# or tort (including negligence or otherwise) arising in any way out of
|
||||
# the use of this software, even if advised of the possibility of such damage.
|
||||
#
|
||||
|
||||
###############################################################################
|
||||
# AUTHOR: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu
|
||||
#
|
||||
# LICENSE AGREEMENT
|
||||
# Copyright (c) 2015, 2015 The Regents of the University of California (Regents)
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of the University nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
###############################################################################
|
||||
import os, sys, re, json, shutil
|
||||
from subprocess import Popen, PIPE, STDOUT
|
||||
|
||||
PY3 = sys.version_info >= (3, 0)
|
||||
|
||||
def make_umd(opencvjs, cvjs):
|
||||
with open(opencvjs, 'r+b') as src:
|
||||
content = src.read()
|
||||
if PY3: # content is bytes
|
||||
content = content.decode('utf-8')
|
||||
with open(cvjs, 'w+b') as dst:
|
||||
# inspired by https://github.com/umdjs/umd/blob/95563fd6b46f06bda0af143ff67292e7f6ede6b7/templates/returnExportsGlobal.js
|
||||
dst.write(("""
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(function () {
|
||||
return (root.cv = factory());
|
||||
});
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node. Does not work with strict CommonJS, but
|
||||
// only CommonJS-like environments that support module.exports,
|
||||
// like Node.
|
||||
module.exports = factory();
|
||||
} else if (typeof window === 'object') {
|
||||
// Browser globals
|
||||
root.cv = factory();
|
||||
} else if (typeof importScripts === 'function') {
|
||||
// Web worker
|
||||
root.cv = factory();
|
||||
} else {
|
||||
// Other shells, e.g. d8
|
||||
root.cv = factory();
|
||||
}
|
||||
}(this, function () {
|
||||
%s
|
||||
if (typeof Module === 'undefined')
|
||||
Module = {};
|
||||
return cv(Module);
|
||||
}));
|
||||
""" % (content)).lstrip().encode('utf-8'))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) > 2:
|
||||
opencvjs = sys.argv[1]
|
||||
cvjs = sys.argv[2]
|
||||
if not os.path.isfile(opencvjs):
|
||||
print('opencv.js file not found! Have you compiled the opencv_js module?')
|
||||
exit()
|
||||
make_umd(opencvjs, cvjs);
|
||||
@@ -0,0 +1,19 @@
|
||||
// This file is part of OpenCV project.
|
||||
// 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.
|
||||
|
||||
QUnit.test("init_cv", (assert) => {
|
||||
if (cv instanceof Promise) {
|
||||
const done = assert.async();
|
||||
cv.then((ready_cv) => {
|
||||
cv = ready_cv;
|
||||
done();
|
||||
});
|
||||
} else if (cv.getBuildInformation === undefined) {
|
||||
const done = assert.async();
|
||||
cv['onRuntimeInitialized'] = () => {
|
||||
done();
|
||||
}
|
||||
}
|
||||
assert.ok(true);
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "opencv_js_tests",
|
||||
"description": "Tests for opencv js bindings",
|
||||
"version": "1.0.1",
|
||||
"dependencies": {
|
||||
"ansi-colors": "^4.1.1",
|
||||
"cli-table": "0.3.6",
|
||||
"minimist": "^1.2.0",
|
||||
"node-qunit": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "latest",
|
||||
"eslint-config-google": "latest"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node tests.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opencv/opencv.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "Apache 2.0 License",
|
||||
"bugs": {
|
||||
"url": "https://github.com/opencv/opencv/issues"
|
||||
},
|
||||
"homepage": "https://github.com/opencv/opencv"
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
try {
|
||||
require('puppeteer')
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"\nFATAL ERROR:" +
|
||||
"\n Package 'puppeteer' is not available." +
|
||||
"\n Run 'npm install --no-save puppeteer' before running this script" +
|
||||
"\n * You may use PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 environment variable to avoid automatic Chromium downloading" +
|
||||
"\n (specify own Chromium/Chrome version through PUPPETEER_EXECUTABLE_PATH=`which google-chrome` environment variable)" +
|
||||
"\n");
|
||||
process.exit(1);
|
||||
}
|
||||
const puppeteer = require('puppeteer')
|
||||
const colors = require("ansi-colors")
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const http = require("http");
|
||||
|
||||
run_main(require('minimist')(process.argv.slice(2)));
|
||||
|
||||
async function run_main(o = {}) {
|
||||
try {
|
||||
await main(o);
|
||||
console.magenta("FATAL: Unexpected exit!");
|
||||
process.exit(1);
|
||||
} catch (e) {
|
||||
console.error(colors.magenta("FATAL: Unexpected exception!"));
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function main(o = {}) {
|
||||
o = Object.assign({}, {
|
||||
buildFolder: __dirname,
|
||||
port: 8080,
|
||||
debug: false,
|
||||
noHeadless: false,
|
||||
serverPrefix: `http://localhost`,
|
||||
noExit: false,
|
||||
screenshot: undefined,
|
||||
help: false,
|
||||
noTryCatch: false,
|
||||
maxBlockDuration: 30000
|
||||
}, o)
|
||||
if (typeof o.screenshot == 'string' && o.screenshot == 'false') {
|
||||
console.log(colors.red('ERROR: misused screenshot option, use --no-screenshot instead'));
|
||||
}
|
||||
if (o.noExit) {
|
||||
o.maxBlockDuration = 999999999
|
||||
}
|
||||
o.debug && console.log('Current Options', o);
|
||||
if (o.help) {
|
||||
printHelpAndExit();
|
||||
}
|
||||
const serverAddress = `${o.serverPrefix}:${o.port}`
|
||||
const url = `${serverAddress}/tests.html${o.noTryCatch ? '?notrycatch=1' : ''}`;
|
||||
if (!fs.existsSync(o.buildFolder)) {
|
||||
console.error(`Expected folder "${o.buildFolder}" to exists. Aborting`);
|
||||
}
|
||||
o.debug && debug('Server Listening at ' + url);
|
||||
const server = await staticServer(o.buildFolder, o.port, m => debug, m => error);
|
||||
o.debug && debug(`Browser launching ${!o.noHeadless ? 'headless' : 'not headless'}`);
|
||||
const browser = await puppeteer.launch({ headless: !o.noHeadless });
|
||||
const page = await browser.newPage();
|
||||
page.on('console', e => {
|
||||
locationMsg = formatMessage(`${e.location().url}:${e.location().lineNumber}:${e.location().columnNumber}`);
|
||||
if (e.type() === 'error') {
|
||||
console.log(colors.red(formatMessage('' + e.text(), `-- ERROR:${locationMsg}: `, )));
|
||||
}
|
||||
else if (o.debug) {
|
||||
o.debug && console.log(colors.grey(formatMessage('' + e.text(), `-- ${locationMsg}: `)));
|
||||
}
|
||||
});
|
||||
o.debug && debug(`Opening page address ${url}`);
|
||||
await page.goto(url);
|
||||
await page.waitForFunction(() => (document.querySelector(`#qunit-testresult`) && document.querySelector(`#qunit-testresult`).textContent || '').trim().toLowerCase().startsWith('tests completed'));
|
||||
const text = await getText(`#qunit-testresult`);
|
||||
if (!text) {
|
||||
return await fail(`An error occurred extracting test results. Check the build folder ${o.buildFolder} is correct and has build with tests enabled.`);
|
||||
}
|
||||
o.debug && debug(colors.blackBright("* UserAgent: " + await getText('#qunit-userAgent')));
|
||||
const testFailed = !text.includes(' 0 failed');
|
||||
if (testFailed && !o.debug) {
|
||||
process.stdout.write(colors.grey("* Use '--debug' parameter to see details of failed tests.\n"));
|
||||
}
|
||||
if (o.screenshot || (o.screenshot === undefined && testFailed)) {
|
||||
await page.screenshot({ path: 'screenshot.png', fullPage: 'true' });
|
||||
process.stdout.write(colors.grey(`* Screenshot taken: ${o.buildFolder}/screenshot.png\n`));
|
||||
}
|
||||
if (testFailed) {
|
||||
const report = await failReport();
|
||||
process.stdout.write(`
|
||||
${colors.red.bold.underline('Failed tests ! :(')}
|
||||
|
||||
${colors.redBright(colors.symbols.cross + ' ' + report.join(`\n${colors.symbols.cross} `))}
|
||||
|
||||
${colors.redBright(`=== Summary ===\n${text}`)}
|
||||
`);
|
||||
}
|
||||
else {
|
||||
process.stdout.write(colors.green(`
|
||||
${colors.symbols.check} No Errors :)
|
||||
|
||||
=== Summary ===\n${text}
|
||||
`));
|
||||
}
|
||||
if (o.noExit) {
|
||||
while (true) {
|
||||
await new Promise(r => setTimeout(r, 5000));
|
||||
}
|
||||
}
|
||||
await server && server.close();
|
||||
await browser.close();
|
||||
process.exit(testFailed ? 1 : 0);
|
||||
|
||||
async function getText(s) {
|
||||
return await page.evaluate((s) => (document.querySelector(s) && document.querySelector(s).innerText) || ''.trim(), s);
|
||||
}
|
||||
async function failReport() {
|
||||
const failures = await page.evaluate(() => Array.from(document.querySelectorAll('#qunit-tests .fail')).filter(e => e.querySelector('.module-name')).map(e => ({
|
||||
moduleName: e.querySelector('.module-name') && e.querySelector('.module-name').textContent,
|
||||
testName: e.querySelector('.test-name') && e.querySelector('.test-name').textContent,
|
||||
expected: e.querySelector('.test-expected pre') && e.querySelector('.test-expected pre').textContent,
|
||||
actual: e.querySelector('.test-actual pre') && e.querySelector('.test-actual pre').textContent,
|
||||
code: e.querySelector('.test-source') && e.querySelector('.test-source').textContent.replace("Source: at ", ""),
|
||||
})));
|
||||
return failures.map(f => `${f.moduleName}: ${f.testName} (${formatMessage(f.code)})`);
|
||||
}
|
||||
async function fail(s) {
|
||||
await failReport();
|
||||
process.stdout.write(colors.red(s) + '\n');
|
||||
if (o.screenshot || o.screenshot === undefined) {
|
||||
await page.screenshot({ path: 'screenshot.png', fullPage: 'true' });
|
||||
process.stdout.write(colors.grey(`* Screenshot taken: ${o.buildFolder}/screenshot.png\n`));
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
async function debug(s) {
|
||||
process.stdout.write(s + '\n');
|
||||
}
|
||||
async function error(s) {
|
||||
process.stdout.write(s + '\n');
|
||||
}
|
||||
function formatMessage(message, prefix) {
|
||||
prefix = prefix || '';
|
||||
return prefix + ('' + message).split('\n').map(l => l.replace(serverAddress, o.buildFolder)).join('\n' + prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function printHelpAndExit() {
|
||||
console.log(`
|
||||
Usage:
|
||||
|
||||
# First, remember to build opencv.js with tests enabled:
|
||||
${colors.blueBright(`python ./platforms/js/build_js.py build_js --build_test`)}
|
||||
|
||||
# Install the tool locally (needed only once) and run it
|
||||
${colors.blueBright(`cd build_js/bin`)}
|
||||
${colors.blueBright(`npm install`)}
|
||||
${colors.blueBright(`node run_puppeteer`)}
|
||||
|
||||
By default will run a headless browser silently printing a small report in the terminal.
|
||||
But it could used to debug the tests in the browser, take screenshots, global tool or
|
||||
targeting external servers exposing the tests.
|
||||
|
||||
TIP: you could install the tool globally (npm install --global build_js/bin) to execute it from any local folder.
|
||||
|
||||
# Options
|
||||
|
||||
* port?: number. Default 8080
|
||||
* buildFolder?: string. Default __dirname (this folder)
|
||||
* debug?: boolean. Default false
|
||||
* noHeadless?: boolean. Default false
|
||||
* serverPrefix?: string . Default http://localhost
|
||||
* help?: boolean
|
||||
* screenshot?: boolean . Make screenshot on failure by default. Use --no-screenshot to disable screenshots completely.
|
||||
* noExit?: boolean default false. If true it will keep running the server - together with noHeadless you can debug in the browser.
|
||||
* noTryCatch?: boolean will disable Qunit tryCatch - so exceptions are dump to stdout rather than in the browser.
|
||||
* maxBlockDuration: QUnit timeout. If noExit is given then is infinity.
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
async function staticServer(basePath, port, onFound, onNotFound) {
|
||||
return new Promise(async (resolve) => {
|
||||
const server = http.createServer((req, res) => {
|
||||
var url = resolveUrl(req.url);
|
||||
onFound && onFound(url);
|
||||
var stream = fs.createReadStream(path.join(basePath, url || ''));
|
||||
stream.on('error', function () {
|
||||
onNotFound && onNotFound(url);
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
});
|
||||
stream.pipe(res);
|
||||
}).listen(port);
|
||||
server.on('listening', () => {
|
||||
resolve(server);
|
||||
});
|
||||
});
|
||||
function resolveUrl(url = '') {
|
||||
var i = url.indexOf('?');
|
||||
if (i != -1) {
|
||||
url = url.substr(0, i);
|
||||
}
|
||||
i = url.indexOf('#');
|
||||
if (i != -1) {
|
||||
url = url.substr(0, i);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// This file is part of OpenCV project.
|
||||
// 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.
|
||||
|
||||
QUnit.module('Camera Calibration and 3D Reconstruction', {});
|
||||
|
||||
QUnit.test('constants', function(assert) {
|
||||
assert.strictEqual(typeof cv.LMEDS, 'number');
|
||||
assert.strictEqual(typeof cv.RANSAC, 'number');
|
||||
assert.strictEqual(typeof cv.RHO, 'number');
|
||||
});
|
||||
|
||||
QUnit.test('findHomography', function(assert) {
|
||||
let srcPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [
|
||||
56,
|
||||
65,
|
||||
368,
|
||||
52,
|
||||
28,
|
||||
387,
|
||||
389,
|
||||
390,
|
||||
]);
|
||||
let dstPoints = cv.matFromArray(4, 1, cv.CV_32FC2, [
|
||||
0,
|
||||
0,
|
||||
300,
|
||||
0,
|
||||
0,
|
||||
300,
|
||||
300,
|
||||
300,
|
||||
]);
|
||||
|
||||
const mat = cv.findHomography(srcPoints, dstPoints);
|
||||
|
||||
assert.ok(mat instanceof cv.Mat);
|
||||
});
|
||||
|
||||
QUnit.test('Rodrigues', function(assert) {
|
||||
// Converts a rotation matrix to a rotation vector and vice versa
|
||||
// data64F is the output array
|
||||
const rvec0 = cv.matFromArray(1, 3, cv.CV_64F, [1,1,1]);
|
||||
let rMat0 = new cv.Mat();
|
||||
let rvec1 = new cv.Mat();
|
||||
|
||||
// Args: input Mat, output Mat. The function mutates the output Mat, so the function does not return anything.
|
||||
// cv.Rodrigues (InputArray=src, OutputArray=dst, jacobian=0)
|
||||
// https://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#void%20Rodrigues(InputArray%20src,%20OutputArray%20dst,%20OutputArray%20jacobian)
|
||||
// vec to Mat, starting number is 3 long and each element is 1.
|
||||
cv.Rodrigues(rvec0, rMat0);
|
||||
|
||||
assert.ok(rMat0.data64F.length == 9);
|
||||
assert.ok(0.23 > rMat0.data64F[0] > 0.22);
|
||||
|
||||
// convert Mat to Vec, should be same as what we started with, 3 long and each item should be a 1.
|
||||
cv.Rodrigues(rMat0, rvec1);
|
||||
|
||||
assert.ok(rvec1.data64F.length == 3);
|
||||
assert.ok(1.01 > rvec1.data64F[0] > 0.9);
|
||||
// Answer should be around 1: 0.9999999999999999
|
||||
});
|
||||
|
||||
QUnit.test('estimateAffine2D', function(assert) {
|
||||
const inputs = cv.matFromArray(4, 1, cv.CV_32FC2, [
|
||||
1, 1,
|
||||
80, 0,
|
||||
0, 80,
|
||||
80, 80
|
||||
]);
|
||||
const outputs = cv.matFromArray(4, 1, cv.CV_32FC2, [
|
||||
21, 51,
|
||||
70, 77,
|
||||
40, 40,
|
||||
10, 70
|
||||
]);
|
||||
const M = cv.estimateAffine2D(inputs, outputs);
|
||||
assert.ok(M instanceof cv.Mat);
|
||||
assert.deepEqual(Array.from(M.data), [
|
||||
23, 55, 97, 126, 87, 139, 227, 63, 0, 0,
|
||||
0, 0, 0, 0, 232, 191, 71, 246, 12, 68,
|
||||
165, 35, 53, 64, 99, 56, 27, 66, 14, 254,
|
||||
212, 63, 103, 102, 102, 102, 102, 102, 182, 191,
|
||||
195, 252, 174, 22, 55, 97, 73, 64
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,408 @@
|
||||
// This file is part of OpenCV project.
|
||||
// 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.
|
||||
|
||||
QUnit.module('Core', {});
|
||||
|
||||
QUnit.test('test_operations_on_arrays', function(assert) {
|
||||
// Transpose
|
||||
{
|
||||
let mat1 = cv.Mat.eye(9, 7, cv.CV_8UC3);
|
||||
let mat2 = new cv.Mat();
|
||||
|
||||
cv.transpose(mat1, mat2);
|
||||
|
||||
// Verify result.
|
||||
let size = mat2.size();
|
||||
assert.equal(mat2.channels(), 3);
|
||||
assert.equal(size.height, 7);
|
||||
assert.equal(size.width, 9);
|
||||
}
|
||||
|
||||
// Concat
|
||||
{
|
||||
let mat = cv.Mat.ones({height: 10, width: 5}, cv.CV_8UC3);
|
||||
let mat2 = cv.Mat.eye({height: 10, width: 5}, cv.CV_8UC3);
|
||||
let mat3 = cv.Mat.eye({height: 10, width: 5}, cv.CV_8UC3);
|
||||
|
||||
let out = new cv.Mat();
|
||||
let input = new cv.MatVector();
|
||||
input.push_back(mat);
|
||||
input.push_back(mat2);
|
||||
input.push_back(mat3);
|
||||
|
||||
cv.vconcat(input, out);
|
||||
|
||||
// Verify result.
|
||||
let size = out.size();
|
||||
assert.equal(out.channels(), 3);
|
||||
assert.equal(size.height, 30);
|
||||
assert.equal(size.width, 5);
|
||||
assert.equal(out.elemSize1(), 1);
|
||||
|
||||
cv.hconcat(input, out);
|
||||
|
||||
// Verify result.
|
||||
size = out.size();
|
||||
assert.equal(out.channels(), 3);
|
||||
assert.equal(size.height, 10);
|
||||
assert.equal(size.width, 15);
|
||||
assert.equal(out.elemSize1(), 1);
|
||||
|
||||
input.delete();
|
||||
out.delete();
|
||||
}
|
||||
|
||||
// Min, Max
|
||||
{
|
||||
let data1 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
let data2 = new Uint8Array([0, 4, 0, 8, 0, 12, 0, 16, 0]);
|
||||
|
||||
let expectedMin = new Uint8Array([0, 2, 0, 4, 0, 6, 0, 8, 0]);
|
||||
let expectedMax = new Uint8Array([1, 4, 3, 8, 5, 12, 7, 16, 9]);
|
||||
|
||||
let dataPtr = cv._malloc(3*3*1);
|
||||
let dataPtr2 = cv._malloc(3*3*1);
|
||||
|
||||
let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1);
|
||||
dataHeap.set(new Uint8Array(data1.buffer));
|
||||
|
||||
let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1);
|
||||
dataHeap2.set(new Uint8Array(data2.buffer));
|
||||
|
||||
let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0);
|
||||
let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0);
|
||||
let mat3 = new cv.Mat();
|
||||
|
||||
cv.min(mat1, mat2, mat3);
|
||||
|
||||
// Verify result.
|
||||
let size = mat2.size();
|
||||
assert.equal(mat2.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
|
||||
assert.deepEqual(mat3.data, expectedMin);
|
||||
|
||||
cv.max(mat1, mat2, mat3);
|
||||
|
||||
// Verify result.
|
||||
size = mat2.size();
|
||||
assert.equal(mat2.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
|
||||
assert.deepEqual(mat3.data, expectedMax);
|
||||
|
||||
cv._free(dataPtr);
|
||||
cv._free(dataPtr2);
|
||||
}
|
||||
|
||||
// Bitwise operations
|
||||
{
|
||||
let data1 = new Uint8Array([0, 1, 2, 4, 8, 16, 32, 64, 128]);
|
||||
let data2 = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255]);
|
||||
|
||||
let expectedAnd = new Uint8Array([0, 1, 2, 4, 8, 16, 32, 64, 128]);
|
||||
let expectedOr = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255]);
|
||||
let expectedXor = new Uint8Array([255, 254, 253, 251, 247, 239, 223, 191, 127]);
|
||||
|
||||
let expectedNot = new Uint8Array([255, 254, 253, 251, 247, 239, 223, 191, 127]);
|
||||
|
||||
let dataPtr = cv._malloc(3*3*1);
|
||||
let dataPtr2 = cv._malloc(3*3*1);
|
||||
|
||||
let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1);
|
||||
dataHeap.set(new Uint8Array(data1.buffer));
|
||||
|
||||
let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1);
|
||||
dataHeap2.set(new Uint8Array(data2.buffer));
|
||||
|
||||
let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0);
|
||||
let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0);
|
||||
let mat3 = new cv.Mat();
|
||||
let none = new cv.Mat();
|
||||
|
||||
cv.bitwise_not(mat1, mat3, none);
|
||||
|
||||
// Verify result.
|
||||
let size = mat3.size();
|
||||
assert.equal(mat3.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
|
||||
assert.deepEqual(mat3.data, expectedNot);
|
||||
|
||||
cv.bitwise_and(mat1, mat2, mat3, none);
|
||||
|
||||
// Verify result.
|
||||
size = mat3.size();
|
||||
assert.equal(mat3.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
|
||||
assert.deepEqual(mat3.data, expectedAnd);
|
||||
|
||||
cv.bitwise_or(mat1, mat2, mat3, none);
|
||||
|
||||
// Verify result.
|
||||
size = mat3.size();
|
||||
assert.equal(mat3.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
|
||||
assert.deepEqual(mat3.data, expectedOr);
|
||||
|
||||
cv.bitwise_xor(mat1, mat2, mat3, none);
|
||||
|
||||
// Verify result.
|
||||
size = mat3.size();
|
||||
assert.equal(mat3.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
|
||||
assert.deepEqual(mat3.data, expectedXor);
|
||||
|
||||
cv._free(dataPtr);
|
||||
cv._free(dataPtr2);
|
||||
}
|
||||
|
||||
// Arithmetic operations
|
||||
{
|
||||
let data1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
let data2 = new Uint8Array([0, 2, 4, 6, 8, 10, 12, 14, 16]);
|
||||
let data3 = new Uint8Array([0, 1, 0, 1, 0, 1, 0, 1, 0]);
|
||||
|
||||
// |data1 - data2|
|
||||
let expectedAbsDiff = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
let expectedAdd = new Uint8Array([0, 3, 6, 9, 12, 15, 18, 21, 24]);
|
||||
|
||||
const alpha = 4;
|
||||
const beta = -1;
|
||||
const gamma = 3;
|
||||
// 4*data1 - data2 + 3
|
||||
let expectedWeightedAdd = new Uint8Array([3, 5, 7, 9, 11, 13, 15, 17, 19]);
|
||||
|
||||
let dataPtr = cv._malloc(3*3*1);
|
||||
let dataPtr2 = cv._malloc(3*3*1);
|
||||
let dataPtr3 = cv._malloc(3*3*1);
|
||||
|
||||
let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 3*3*1);
|
||||
dataHeap.set(new Uint8Array(data1.buffer));
|
||||
let dataHeap2 = new Uint8Array(cv.HEAPU8.buffer, dataPtr2, 3*3*1);
|
||||
dataHeap2.set(new Uint8Array(data2.buffer));
|
||||
let dataHeap3 = new Uint8Array(cv.HEAPU8.buffer, dataPtr3, 3*3*1);
|
||||
dataHeap3.set(new Uint8Array(data3.buffer));
|
||||
|
||||
let mat1 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr, 0);
|
||||
let mat2 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr2, 0);
|
||||
let mat3 = new cv.Mat(3, 3, cv.CV_8UC1, dataPtr3, 0);
|
||||
|
||||
let dst = new cv.Mat();
|
||||
let none = new cv.Mat();
|
||||
|
||||
cv.absdiff(mat1, mat2, dst);
|
||||
|
||||
// Verify result.
|
||||
let size = dst.size();
|
||||
assert.equal(dst.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
|
||||
assert.deepEqual(dst.data, expectedAbsDiff);
|
||||
|
||||
cv.add(mat1, mat2, dst, none, -1);
|
||||
|
||||
// Verify result.
|
||||
size = dst.size();
|
||||
assert.equal(dst.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
assert.deepEqual(dst.data, expectedAdd);
|
||||
|
||||
cv.addWeighted(mat1, alpha, mat2, beta, gamma, dst, -1);
|
||||
|
||||
// Verify result.
|
||||
size = dst.size();
|
||||
assert.equal(dst.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
assert.deepEqual(dst.data, expectedWeightedAdd);
|
||||
|
||||
// default parameter
|
||||
cv.addWeighted(mat1, alpha, mat2, beta, gamma, dst);
|
||||
|
||||
// Verify result.
|
||||
size = dst.size();
|
||||
assert.equal(dst.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
|
||||
assert.deepEqual(dst.data, expectedWeightedAdd);
|
||||
|
||||
mat1.delete();
|
||||
mat2.delete();
|
||||
mat3.delete();
|
||||
dst.delete();
|
||||
none.delete();
|
||||
}
|
||||
|
||||
// Invert
|
||||
{
|
||||
let inv1 = new cv.Mat();
|
||||
let inv2 = new cv.Mat();
|
||||
let inv3 = new cv.Mat();
|
||||
let inv4 = new cv.Mat();
|
||||
|
||||
let data1 = new Float32Array([1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1]);
|
||||
let data2 = new Float32Array([0, 0, 0,
|
||||
0, 5, 0,
|
||||
0, 0, 0]);
|
||||
let data3 = new Float32Array([1, 1, 1, 0,
|
||||
0, 3, 1, 2,
|
||||
2, 3, 1, 0,
|
||||
1, 0, 2, 1]);
|
||||
let data4 = new Float32Array([1, 4, 5,
|
||||
4, 2, 2,
|
||||
5, 2, 2]);
|
||||
|
||||
let expected1 = new Float32Array([1, 0, 0,
|
||||
0, 1, 0,
|
||||
0, 0, 1]);
|
||||
// Inverse does not exist!
|
||||
let expected3 = new Float32Array([-3, -1/2, 3/2, 1,
|
||||
1, 1/4, -1/4, -1/2,
|
||||
3, 1/4, -5/4, -1/2,
|
||||
-3, 0, 1, 1]);
|
||||
let expected4 = new Float32Array([0, -1, 1,
|
||||
-1, 23/2, -9,
|
||||
1, -9, 7]);
|
||||
|
||||
let dataPtr1 = cv._malloc(3*3*4);
|
||||
let dataPtr2 = cv._malloc(3*3*4);
|
||||
let dataPtr3 = cv._malloc(4*4*4);
|
||||
let dataPtr4 = cv._malloc(3*3*4);
|
||||
|
||||
let dataHeap = new Float32Array(cv.HEAP32.buffer, dataPtr1, 3*3);
|
||||
dataHeap.set(new Float32Array(data1.buffer));
|
||||
let dataHeap2 = new Float32Array(cv.HEAP32.buffer, dataPtr2, 3*3);
|
||||
dataHeap2.set(new Float32Array(data2.buffer));
|
||||
let dataHeap3 = new Float32Array(cv.HEAP32.buffer, dataPtr3, 4*4);
|
||||
dataHeap3.set(new Float32Array(data3.buffer));
|
||||
let dataHeap4 = new Float32Array(cv.HEAP32.buffer, dataPtr4, 3*3);
|
||||
dataHeap4.set(new Float32Array(data4.buffer));
|
||||
|
||||
let mat1 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr1, 0);
|
||||
let mat2 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr2, 0);
|
||||
let mat3 = new cv.Mat(4, 4, cv.CV_32FC1, dataPtr3, 0);
|
||||
let mat4 = new cv.Mat(3, 3, cv.CV_32FC1, dataPtr4, 0);
|
||||
|
||||
QUnit.assert.deepEqualWithTolerance = function( value, expected, tolerance ) {
|
||||
for (let i = 0; i < value.length; i= i+1) {
|
||||
this.pushResult( {
|
||||
result: Math.abs(value[i]-expected[i]) < tolerance,
|
||||
actual: value[i],
|
||||
expected: expected[i],
|
||||
} );
|
||||
}
|
||||
};
|
||||
|
||||
cv.invert(mat1, inv1, 0);
|
||||
|
||||
// Verify result.
|
||||
let size = inv1.size();
|
||||
assert.equal(inv1.channels(), 1);
|
||||
assert.equal(size.height, 3);
|
||||
assert.equal(size.width, 3);
|
||||
assert.deepEqualWithTolerance(inv1.data32F, expected1, 0.0001);
|
||||
|
||||
cv.invert(mat2, inv2, 0);
|
||||
|
||||
// Verify result.
|
||||
assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001);
|
||||
|
||||
cv.invert(mat3, inv3, 0);
|
||||
|
||||
// Verify result.
|
||||
size = inv3.size();
|
||||
assert.equal(inv3.channels(), 1);
|
||||
assert.equal(size.height, 4);
|
||||
assert.equal(size.width, 4);
|
||||
assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001);
|
||||
|
||||
cv.invert(mat3, inv3, 1);
|
||||
|
||||
// Verify result.
|
||||
assert.deepEqualWithTolerance(inv3.data32F, expected3, 0.0001);
|
||||
|
||||
cv.invert(mat4, inv4, 2);
|
||||
|
||||
// Verify result.
|
||||
assert.deepEqualWithTolerance(inv4.data32F, expected4, 0.0001);
|
||||
|
||||
cv.invert(mat4, inv4, 3);
|
||||
|
||||
// Verify result.
|
||||
assert.deepEqualWithTolerance(inv4.data32F, expected4, 0.0001);
|
||||
|
||||
mat1.delete();
|
||||
mat2.delete();
|
||||
mat3.delete();
|
||||
mat4.delete();
|
||||
inv1.delete();
|
||||
inv2.delete();
|
||||
inv3.delete();
|
||||
inv4.delete();
|
||||
}
|
||||
|
||||
//Rotate
|
||||
{
|
||||
let dst = new cv.Mat();
|
||||
let src = cv.matFromArray(3, 2, cv.CV_8U, [1,2,3,4,5,6]);
|
||||
|
||||
cv.rotate(src, dst, cv.ROTATE_90_CLOCKWISE);
|
||||
|
||||
let size = dst.size();
|
||||
assert.equal(size.height, 2, "ROTATE_HEIGHT");
|
||||
assert.equal(size.width, 3, "ROTATE_WIGTH");
|
||||
|
||||
let expected = new Uint8Array([5,3,1,6,4,2]);
|
||||
|
||||
assert.deepEqual(dst.data, expected);
|
||||
|
||||
dst.delete();
|
||||
src.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_LUT', function(assert) {
|
||||
{
|
||||
let src = cv.matFromArray(3, 3, cv.CV_8UC1, [255, 128, 0, 0, 128, 255, 1, 2, 254]);
|
||||
let lutTable = [];
|
||||
for (let i = 0; i < 256; i++)
|
||||
{
|
||||
lutTable[i] = 255 - i;
|
||||
}
|
||||
let lut = cv.matFromArray(1, 256, cv.CV_8UC1, lutTable);
|
||||
let dst = new cv.Mat();
|
||||
|
||||
cv.LUT(src, lut, dst);
|
||||
|
||||
// Verify result.
|
||||
assert.equal(dst.ucharAt(0), 0);
|
||||
assert.equal(dst.ucharAt(1), 127);
|
||||
assert.equal(dst.ucharAt(2), 255);
|
||||
assert.equal(dst.ucharAt(3), 255);
|
||||
assert.equal(dst.ucharAt(4), 127);
|
||||
assert.equal(dst.ucharAt(5), 0);
|
||||
assert.equal(dst.ucharAt(6), 254);
|
||||
assert.equal(dst.ucharAt(7), 253);
|
||||
assert.equal(dst.ucharAt(8), 1);
|
||||
|
||||
src.delete();
|
||||
lut.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,119 @@
|
||||
// This file is part of OpenCV project.
|
||||
// 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.
|
||||
|
||||
function generateTestFrame(width, height) {
|
||||
let w = width || 200;
|
||||
let h = height || 200;
|
||||
let img = new cv.Mat(h, w, cv.CV_8UC1, new cv.Scalar(0, 0, 0, 0));
|
||||
let s = new cv.Scalar(255, 255, 255, 255);
|
||||
let s128 = new cv.Scalar(128, 128, 128, 128);
|
||||
let rect = new cv.Rect(w / 4, h / 4, w / 2, h / 2);
|
||||
img.roi(rect).setTo(s);
|
||||
img.roi(new cv.Rect(w / 2 - w / 8, h / 2 - h / 8, w / 4, h / 4)).setTo(s128);
|
||||
cv.rectangle(img, new cv.Point(w / 8, h / 8), new cv.Point(w - w / 8, h - h / 8), s, 5);
|
||||
cv.rectangle(img, new cv.Point(w / 5, h / 5), new cv.Point(w - w / 5, h - h / 5), s128, 3);
|
||||
cv.line(img, new cv.Point(-w, 0), new cv.Point(w / 2, h / 2), s128, 5);
|
||||
cv.line(img, new cv.Point(2*w, 0), new cv.Point(w / 2, h / 2), s, 5);
|
||||
return img;
|
||||
}
|
||||
|
||||
QUnit.module('Features2D', {});
|
||||
QUnit.test('Detectors', function(assert) {
|
||||
let image = generateTestFrame();
|
||||
|
||||
let kp = new cv.KeyPointVector();
|
||||
|
||||
let orb = new cv.ORB();
|
||||
orb.detect(image, kp);
|
||||
assert.equal(kp.size(), 68, 'ORB');
|
||||
|
||||
let mser = new cv.MSER();
|
||||
mser.detect(image, kp);
|
||||
assert.equal(kp.size(), 7, 'MSER');
|
||||
|
||||
let brisk = new cv.BRISK();
|
||||
brisk.detect(image, kp);
|
||||
assert.equal(kp.size(), 187, 'BRISK');
|
||||
|
||||
let ffd = new cv.FastFeatureDetector();
|
||||
ffd.detect(image, kp);
|
||||
assert.equal(kp.size(), 12, 'FastFeatureDetector');
|
||||
|
||||
let afd = new cv.AgastFeatureDetector();
|
||||
afd.detect(image, kp);
|
||||
assert.equal(kp.size(), 67, 'AgastFeatureDetector');
|
||||
|
||||
let gftt = new cv.GFTTDetector();
|
||||
gftt.detect(image, kp);
|
||||
assert.equal(kp.size(), 168, 'GFTTDetector');
|
||||
|
||||
let kaze = new cv.KAZE();
|
||||
kaze.detect(image, kp);
|
||||
assert.equal(kp.size(), 159, 'KAZE');
|
||||
|
||||
let akaze = new cv.AKAZE();
|
||||
akaze.detect(image, kp);
|
||||
assert.equal(kp.size(), 52, 'AKAZE');
|
||||
});
|
||||
|
||||
QUnit.test('SimpleBlobDetector', function(assert) {
|
||||
let image = generateTestFrame();
|
||||
|
||||
let kp = new cv.KeyPointVector();
|
||||
let sbd = new cv.SimpleBlobDetector();
|
||||
sbd.detect(image, kp);
|
||||
assert.equal(kp.size(), 0);
|
||||
});
|
||||
|
||||
QUnit.test('BFMatcher', function(assert) {
|
||||
// Generate key points.
|
||||
let image = generateTestFrame();
|
||||
|
||||
let kp = new cv.KeyPointVector();
|
||||
let descriptors = new cv.Mat();
|
||||
let orb = new cv.ORB();
|
||||
orb.detectAndCompute(image, new cv.Mat(), kp, descriptors);
|
||||
|
||||
assert.equal(kp.size(), 68);
|
||||
|
||||
// Run a matcher.
|
||||
let dm = new cv.DMatchVector();
|
||||
let matcher = new cv.BFMatcher();
|
||||
matcher.match(descriptors, descriptors, dm);
|
||||
|
||||
assert.equal(dm.size(), 68);
|
||||
});
|
||||
|
||||
QUnit.test('Drawing', function(assert) {
|
||||
// Generate key points.
|
||||
let image = generateTestFrame();
|
||||
|
||||
let kp = new cv.KeyPointVector();
|
||||
let descriptors = new cv.Mat();
|
||||
let orb = new cv.ORB();
|
||||
orb.detectAndCompute(image, new cv.Mat(), kp, descriptors);
|
||||
assert.equal(kp.size(), 68);
|
||||
|
||||
let dst = new cv.Mat();
|
||||
cv.drawKeypoints(image, kp, dst);
|
||||
assert.equal(dst.rows, image.rows);
|
||||
assert.equal(dst.cols, image.cols);
|
||||
|
||||
// Run a matcher.
|
||||
let dm = new cv.DMatchVector();
|
||||
let matcher = new cv.BFMatcher();
|
||||
matcher.match(descriptors, descriptors, dm);
|
||||
assert.equal(dm.size(), 68);
|
||||
|
||||
cv.drawMatches(image, kp, image, kp, dm, dst);
|
||||
assert.equal(dst.rows, image.rows);
|
||||
assert.equal(dst.cols, 2 * image.cols);
|
||||
|
||||
dm = new cv.DMatchVectorVector();
|
||||
matcher.knnMatch(descriptors, descriptors, dm, 2);
|
||||
assert.equal(dm.size(), 68);
|
||||
cv.drawMatchesKnn(image, kp, image, kp, dm, dst);
|
||||
assert.equal(dst.rows, image.rows);
|
||||
assert.equal(dst.cols, 2 * image.cols);
|
||||
});
|
||||
@@ -0,0 +1,781 @@
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu
|
||||
//
|
||||
// LICENSE AGREEMENT
|
||||
// Copyright (c) 2015 The Regents of the University of California (Regents)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the University nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
QUnit.module('Image Processing', {});
|
||||
|
||||
QUnit.test('applyColorMap', function(assert) {
|
||||
{
|
||||
let src = cv.matFromArray(2, 1, cv.CV_8U, [50,100]);
|
||||
cv.applyColorMap(src, src, cv.COLORMAP_BONE);
|
||||
|
||||
// Verify result.
|
||||
let expected = new Uint8Array([60,44,44,119,89,87]);
|
||||
|
||||
assert.deepEqual(src.data, expected);
|
||||
src.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('blendLinear', function(assert) {
|
||||
{
|
||||
let src1 = cv.matFromArray(2, 1, cv.CV_8U, [50,100]);
|
||||
let src2 = cv.matFromArray(2, 1, cv.CV_8U, [200,20]);
|
||||
let weights1 = cv.matFromArray(2, 1, cv.CV_32F, [0.4,0.5]);
|
||||
let weights2 = cv.matFromArray(2, 1, cv.CV_32F, [0.6,0.5]);
|
||||
let dst = new cv.Mat();
|
||||
cv.blendLinear(src1, src2, weights1, weights2, dst);
|
||||
|
||||
// Verify result.
|
||||
let expected = new Uint8Array([140,60]);
|
||||
|
||||
assert.deepEqual(dst.data, expected);
|
||||
src1.delete();
|
||||
src2.delete();
|
||||
weights1.delete();
|
||||
weights2.delete();
|
||||
dst.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('createHanningWindow', function(assert) {
|
||||
{
|
||||
let dst = new cv.Mat();
|
||||
cv.createHanningWindow(dst, new cv.Size(5, 3), cv.CV_32F);
|
||||
|
||||
// Verify result.
|
||||
let expected = cv.matFromArray(3, 5, cv.CV_32F, [0.,0.,0.,0.,0.,0.,0.70710677,1.,0.70710677,0.,0.,0.,0.,0.,0.]);
|
||||
|
||||
assert.deepEqual(dst.data, expected.data);
|
||||
dst.delete();
|
||||
expected.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_imgProc', function(assert) {
|
||||
// calcHist
|
||||
{
|
||||
let vec1 = new cv.Mat.ones(new cv.Size(20, 20), cv.CV_8UC1); // eslint-disable-line new-cap
|
||||
let source = new cv.MatVector();
|
||||
source.push_back(vec1);
|
||||
let channels = [0];
|
||||
let histSize = [256];
|
||||
let ranges =[0, 256];
|
||||
|
||||
let hist = new cv.Mat();
|
||||
let mask = new cv.Mat();
|
||||
let binSize = cv._malloc(4);
|
||||
let binView = new Int32Array(cv.HEAP8.buffer, binSize);
|
||||
binView[0] = 10;
|
||||
cv.calcHist(source, channels, mask, hist, histSize, ranges, false);
|
||||
|
||||
// hist should contains a N X 1 array.
|
||||
let size = hist.size();
|
||||
assert.equal(size.height, 256);
|
||||
assert.equal(size.width, 1);
|
||||
|
||||
// default parameters
|
||||
cv.calcHist(source, channels, mask, hist, histSize, ranges);
|
||||
size = hist.size();
|
||||
assert.equal(size.height, 256);
|
||||
assert.equal(size.width, 1);
|
||||
|
||||
// Do we need to verify data in histogram?
|
||||
// let dataView = hist.data;
|
||||
|
||||
// Free resource
|
||||
cv._free(binSize);
|
||||
mask.delete();
|
||||
hist.delete();
|
||||
}
|
||||
|
||||
// cvtColor
|
||||
{
|
||||
let source = new cv.Mat(10, 10, cv.CV_8UC3);
|
||||
let dest = new cv.Mat();
|
||||
|
||||
cv.cvtColor(source, dest, cv.COLOR_BGR2GRAY, 0);
|
||||
assert.equal(dest.channels(), 1);
|
||||
|
||||
cv.cvtColor(source, dest, cv.COLOR_BGR2GRAY);
|
||||
assert.equal(dest.channels(), 1);
|
||||
|
||||
cv.cvtColor(source, dest, cv.COLOR_BGR2BGRA, 0);
|
||||
assert.equal(dest.channels(), 4);
|
||||
|
||||
cv.cvtColor(source, dest, cv.COLOR_BGR2BGRA);
|
||||
assert.equal(dest.channels(), 4);
|
||||
|
||||
dest.delete();
|
||||
source.delete();
|
||||
}
|
||||
|
||||
// equalizeHist
|
||||
{
|
||||
let source = new cv.Mat(10, 10, cv.CV_8UC1);
|
||||
let dest = new cv.Mat();
|
||||
|
||||
cv.equalizeHist(source, dest);
|
||||
|
||||
// eualizeHist changes the content of a image, but does not alter meta data
|
||||
// of it.
|
||||
assert.equal(source.channels(), dest.channels());
|
||||
assert.equal(source.type(), dest.type());
|
||||
|
||||
dest.delete();
|
||||
source.delete();
|
||||
}
|
||||
|
||||
// floodFill
|
||||
{
|
||||
let center = new cv.Point(5, 5);
|
||||
let rect = new cv.Rect(0, 0, 0, 0);
|
||||
let img = new cv.Mat.zeros(10, 10, cv.CV_8UC1);
|
||||
let color = new cv.Scalar (255);
|
||||
cv.circle(img, center, 3, color, 1);
|
||||
|
||||
let edge = new cv.Mat();
|
||||
cv.Canny(img, edge, 100, 255);
|
||||
cv.copyMakeBorder(edge, edge, 1, 1, 1, 1, cv.BORDER_REPLICATE);
|
||||
|
||||
let expected_img_data = new Uint8Array([
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 255, 255, 255, 255, 0, 0,
|
||||
0, 0, 0, 255, 0, 255, 0, 255, 0, 0,
|
||||
0, 0, 255, 255, 255, 255, 0, 0, 255, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 255, 255, 0, 255, 255, 0, 0,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
|
||||
let img_elem = 10*10*1;
|
||||
let expected_img_data_ptr = cv._malloc(img_elem);
|
||||
let expected_img_data_heap = new Uint8Array(cv.HEAPU8.buffer,
|
||||
expected_img_data_ptr,
|
||||
img_elem);
|
||||
expected_img_data_heap.set(new Uint8Array(expected_img_data.buffer));
|
||||
|
||||
let expected_img = new cv.Mat( 10, 10, cv.CV_8UC1, expected_img_data_ptr, 0);
|
||||
|
||||
let expected_rect = new cv.Rect(3,3,3,3);
|
||||
|
||||
let compare_result = new cv.Mat(10, 10, cv.CV_8UC1);
|
||||
|
||||
cv.floodFill(img, edge, center, color, rect);
|
||||
|
||||
cv.compare (img, expected_img, compare_result, cv.CMP_EQ);
|
||||
|
||||
// expect every pixels are the same.
|
||||
assert.equal (cv.countNonZero(compare_result), img.total());
|
||||
assert.equal (rect.x, expected_rect.x);
|
||||
assert.equal (rect.y, expected_rect.y);
|
||||
assert.equal (rect.width, expected_rect.width);
|
||||
assert.equal (rect.height, expected_rect.height);
|
||||
|
||||
img.delete();
|
||||
edge.delete();
|
||||
expected_img.delete();
|
||||
compare_result.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('Drawing Functions', function(assert) {
|
||||
// fillPoly
|
||||
{
|
||||
let img_width = 6;
|
||||
let img_height = 6;
|
||||
|
||||
let img = new cv.Mat.zeros(img_height, img_width, cv.CV_8UC1);
|
||||
|
||||
let npts = 4;
|
||||
let square_point_data = new Uint8Array([
|
||||
1, 1,
|
||||
4, 1,
|
||||
4, 4,
|
||||
1, 4]);
|
||||
let square_points = cv.matFromArray(npts, 1, cv.CV_32SC2, square_point_data);
|
||||
let pts = new cv.MatVector();
|
||||
pts.push_back (square_points);
|
||||
let color = new cv.Scalar (255);
|
||||
|
||||
let expected_img_data = new Uint8Array([
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 0, 0, 0]);
|
||||
let expected_img = cv.matFromArray(img_height, img_width, cv.CV_8UC1, expected_img_data);
|
||||
|
||||
cv.fillPoly(img, pts, color);
|
||||
|
||||
let compare_result = new cv.Mat(img_height, img_width, cv.CV_8UC1);
|
||||
|
||||
cv.compare (img, expected_img, compare_result, cv.CMP_EQ);
|
||||
|
||||
// expect every pixels are the same.
|
||||
assert.equal (cv.countNonZero(compare_result), img.total());
|
||||
|
||||
img.delete();
|
||||
square_points.delete();
|
||||
pts.delete();
|
||||
expected_img.delete();
|
||||
compare_result.delete();
|
||||
}
|
||||
|
||||
// fillConvexPoly
|
||||
{
|
||||
let img_width = 6;
|
||||
let img_height = 6;
|
||||
|
||||
let img = new cv.Mat.zeros(img_height, img_width, cv.CV_8UC1);
|
||||
|
||||
let npts = 4;
|
||||
let square_point_data = new Uint8Array([
|
||||
1, 1,
|
||||
4, 1,
|
||||
4, 4,
|
||||
1, 4]);
|
||||
let square_points = cv.matFromArray(npts, 1, cv.CV_32SC2, square_point_data);
|
||||
let color = new cv.Scalar (255);
|
||||
|
||||
let expected_img_data = new Uint8Array([
|
||||
0, 0, 0, 0, 0, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 255, 255, 255, 255, 0,
|
||||
0, 0, 0, 0, 0, 0]);
|
||||
let expected_img = cv.matFromArray(img_height, img_width, cv.CV_8UC1, expected_img_data);
|
||||
|
||||
cv.fillConvexPoly(img, square_points, color);
|
||||
|
||||
let compare_result = new cv.Mat(img_height, img_width, cv.CV_8UC1);
|
||||
|
||||
cv.compare (img, expected_img, compare_result, cv.CMP_EQ);
|
||||
|
||||
// expect every pixels are the same.
|
||||
assert.equal (cv.countNonZero(compare_result), img.total());
|
||||
|
||||
img.delete();
|
||||
square_points.delete();
|
||||
expected_img.delete();
|
||||
compare_result.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_segmentation', function(assert) {
|
||||
const THRESHOLD = 127.0;
|
||||
const THRESHOLD_MAX = 210.0;
|
||||
|
||||
// threshold
|
||||
{
|
||||
let source = new cv.Mat(1, 5, cv.CV_8UC1);
|
||||
let sourceView = source.data;
|
||||
sourceView[0] = 0; // < threshold
|
||||
sourceView[1] = 100; // < threshold
|
||||
sourceView[2] = 200; // > threshold
|
||||
|
||||
let dest = new cv.Mat();
|
||||
|
||||
cv.threshold(source, dest, THRESHOLD, THRESHOLD_MAX, cv.THRESH_BINARY);
|
||||
|
||||
let destView = dest.data;
|
||||
assert.equal(destView[0], 0);
|
||||
assert.equal(destView[1], 0);
|
||||
assert.equal(destView[2], THRESHOLD_MAX);
|
||||
}
|
||||
|
||||
// adaptiveThreshold
|
||||
{
|
||||
let source = cv.Mat.zeros(1, 5, cv.CV_8UC1);
|
||||
let sourceView = source.data;
|
||||
sourceView[0] = 50;
|
||||
sourceView[1] = 150;
|
||||
sourceView[2] = 200;
|
||||
|
||||
let dest = new cv.Mat();
|
||||
const C = 0;
|
||||
const blockSize = 3;
|
||||
cv.adaptiveThreshold(source, dest, THRESHOLD_MAX,
|
||||
cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, blockSize, C);
|
||||
|
||||
let destView = dest.data;
|
||||
assert.equal(destView[0], 0);
|
||||
assert.equal(destView[1], THRESHOLD_MAX);
|
||||
assert.equal(destView[2], THRESHOLD_MAX);
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_shape', function(assert) {
|
||||
// moments
|
||||
{
|
||||
let points = new cv.Mat(1, 4, cv.CV_32SC2);
|
||||
let data32S = points.data32S;
|
||||
data32S[0]=50;
|
||||
data32S[1]=56;
|
||||
data32S[2]=53;
|
||||
data32S[3]=53;
|
||||
data32S[4]=46;
|
||||
data32S[5]=54;
|
||||
data32S[6]=49;
|
||||
data32S[7]=51;
|
||||
|
||||
let m = cv.moments(points, false);
|
||||
let area = cv.contourArea(points, false);
|
||||
|
||||
assert.equal(m.m00, 0);
|
||||
assert.equal(m.m01, 0);
|
||||
assert.equal(m.m10, 0);
|
||||
assert.equal(area, 0);
|
||||
|
||||
// default parameters
|
||||
m = cv.moments(points);
|
||||
area = cv.contourArea(points);
|
||||
assert.equal(m.m00, 0);
|
||||
assert.equal(m.m01, 0);
|
||||
assert.equal(m.m10, 0);
|
||||
assert.equal(area, 0);
|
||||
|
||||
points.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_min_enclosing', function(assert) {
|
||||
// minEnclosingCircle
|
||||
{
|
||||
let points = new cv.Mat(4, 1, cv.CV_32FC2);
|
||||
|
||||
points.data32F[0] = 0;
|
||||
points.data32F[1] = 0;
|
||||
points.data32F[2] = 1;
|
||||
points.data32F[3] = 0;
|
||||
points.data32F[4] = 1;
|
||||
points.data32F[5] = 1;
|
||||
points.data32F[6] = 0;
|
||||
points.data32F[7] = 1;
|
||||
|
||||
let circle = cv.minEnclosingCircle(points);
|
||||
|
||||
assert.deepEqual(circle.center, {x: 0.5, y: 0.5});
|
||||
assert.ok(Math.abs(circle.radius - Math.sqrt(2) / 2) < 0.001);
|
||||
|
||||
points.delete();
|
||||
}
|
||||
|
||||
// minEnclosingTriangle
|
||||
{
|
||||
let dst = cv.Mat.zeros(80, 80, cv.CV_8U);
|
||||
let contours = new cv.MatVector();
|
||||
let hierarchy = new cv.Mat();
|
||||
let triangle = new cv.Mat();
|
||||
|
||||
cv.drawMarker(dst, new cv.Point(40, 40), new cv.Scalar(255));
|
||||
cv.findContoursLinkRuns(dst,contours,hierarchy);
|
||||
cv.minEnclosingTriangle(contours.get(0),triangle);
|
||||
|
||||
// Verify result.
|
||||
const triangleData = triangle.data32F;
|
||||
assert.deepEqual(triangleData[0], triangleData[4]);
|
||||
assert.deepEqual(triangleData[1], 20);
|
||||
assert.deepEqual(triangleData[2], 30);
|
||||
assert.deepEqual(triangleData[3], 40);
|
||||
assert.deepEqual(triangleData[5], 60);
|
||||
|
||||
dst.delete();
|
||||
contours.delete();
|
||||
hierarchy.delete();
|
||||
triangle.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_filter', function(assert) {
|
||||
// blur
|
||||
{
|
||||
let mat1 = cv.Mat.ones(5, 5, cv.CV_8UC3);
|
||||
let mat2 = new cv.Mat();
|
||||
|
||||
cv.blur(mat1, mat2, {height: 3, width: 3}, {x: -1, y: -1}, cv.BORDER_DEFAULT);
|
||||
|
||||
// Verify result.
|
||||
let size = mat2.size();
|
||||
assert.equal(mat2.channels(), 3);
|
||||
assert.equal(size.height, 5);
|
||||
assert.equal(size.width, 5);
|
||||
|
||||
cv.blur(mat1, mat2, {height: 3, width: 3}, {x: -1, y: -1});
|
||||
|
||||
// Verify result.
|
||||
size = mat2.size();
|
||||
assert.equal(mat2.channels(), 3);
|
||||
assert.equal(size.height, 5);
|
||||
assert.equal(size.width, 5);
|
||||
|
||||
cv.blur(mat1, mat2, {height: 3, width: 3});
|
||||
|
||||
// Verify result.
|
||||
size = mat2.size();
|
||||
assert.equal(mat2.channels(), 3);
|
||||
assert.equal(size.height, 5);
|
||||
assert.equal(size.width, 5);
|
||||
|
||||
mat1.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
|
||||
// GaussianBlur
|
||||
{
|
||||
let mat1 = cv.Mat.ones(7, 7, cv.CV_8UC1);
|
||||
let mat2 = new cv.Mat();
|
||||
|
||||
cv.GaussianBlur(mat1, mat2, new cv.Size(3, 3), 0, 0, // eslint-disable-line new-cap
|
||||
cv.BORDER_DEFAULT);
|
||||
|
||||
// Verify result.
|
||||
let size = mat2.size();
|
||||
assert.equal(mat2.channels(), 1);
|
||||
assert.equal(size.height, 7);
|
||||
assert.equal(size.width, 7);
|
||||
mat1.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
|
||||
// spatialGradient
|
||||
{
|
||||
let src = cv.matFromArray(4, 4, cv.CV_8U, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]);
|
||||
let dx = new cv.Mat();
|
||||
let dy = new cv.Mat();
|
||||
cv.spatialGradient(src, dx, dy);
|
||||
|
||||
// Verify result.
|
||||
let expected_dx = new cv.Mat();
|
||||
let expected_dy = new cv.Mat();
|
||||
cv.Sobel(src, expected_dx, cv.CV_16SC1, 1, 0, 3);
|
||||
cv.Sobel(src, expected_dy, cv.CV_16SC1, 0, 1, 3);
|
||||
|
||||
assert.deepEqual(dx.data, expected_dx.data);
|
||||
assert.deepEqual(dy.data, expected_dy.data);
|
||||
|
||||
src.delete();
|
||||
dx.delete();
|
||||
dy.delete();
|
||||
expected_dx.delete();
|
||||
expected_dy.delete();
|
||||
}
|
||||
|
||||
// sqrBoxFilter
|
||||
{
|
||||
let src = cv.matFromArray(2, 3, cv.CV_8U, [1,2,1,1,2,1]);
|
||||
let dst = new cv.Mat();
|
||||
cv.sqrBoxFilter(src, dst, cv.CV_32F, new cv.Size(3, 3));
|
||||
|
||||
// Verify result.
|
||||
let expected = cv.matFromArray(2, 3, cv.CV_32F,[3.0,2.0,3.0,3.0,2.0,3.0]);
|
||||
|
||||
assert.deepEqual(dst.data, expected.data);
|
||||
src.delete();
|
||||
dst.delete();
|
||||
expected.delete();
|
||||
}
|
||||
|
||||
// stackBlur
|
||||
{
|
||||
let src = cv.matFromArray(2, 3, cv.CV_8U, [10,25,30,45,50,60]);
|
||||
cv.stackBlur(src, src, new cv.Size(3, 3));
|
||||
|
||||
// Verify result.
|
||||
let expected = new Uint8Array([14,22,29,46,51,58]);
|
||||
|
||||
assert.deepEqual(src.data, expected);
|
||||
src.delete();
|
||||
}
|
||||
|
||||
// medianBlur
|
||||
{
|
||||
let mat1 = cv.Mat.ones(9, 9, cv.CV_8UC3);
|
||||
let mat2 = new cv.Mat();
|
||||
|
||||
cv.medianBlur(mat1, mat2, 3);
|
||||
|
||||
// Verify result.
|
||||
let size = mat2.size();
|
||||
|
||||
assert.equal(mat2.channels(), 3);
|
||||
assert.equal(size.height, 9);
|
||||
assert.equal(size.width, 9);
|
||||
mat1.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
|
||||
// bilateralFilter
|
||||
{
|
||||
let mat1 = cv.Mat.ones(11, 11, cv.CV_8UC3);
|
||||
let mat2 = new cv.Mat();
|
||||
|
||||
cv.bilateralFilter(mat1, mat2, 3, 6, 1.5, cv.BORDER_DEFAULT);
|
||||
|
||||
// Verify result.
|
||||
let size = mat2.size();
|
||||
assert.equal(mat2.channels(), 3);
|
||||
assert.equal(size.height, 11);
|
||||
assert.equal(size.width, 11);
|
||||
|
||||
// default parameters
|
||||
cv.bilateralFilter(mat1, mat2, 3, 6, 1.5);
|
||||
// Verify result.
|
||||
size = mat2.size();
|
||||
assert.equal(mat2.channels(), 3);
|
||||
assert.equal(size.height, 11);
|
||||
assert.equal(size.width, 11);
|
||||
|
||||
mat1.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_watershed', function(assert) {
|
||||
{
|
||||
let mat = cv.Mat.ones(11, 11, cv.CV_8UC3);
|
||||
let out = new cv.Mat(11, 11, cv.CV_32SC1);
|
||||
|
||||
cv.watershed(mat, out);
|
||||
|
||||
// Verify result.
|
||||
let size = out.size();
|
||||
assert.equal(out.channels(), 1);
|
||||
assert.equal(size.height, 11);
|
||||
assert.equal(size.width, 11);
|
||||
assert.equal(out.elemSize1(), 4);
|
||||
|
||||
mat.delete();
|
||||
out.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_distanceTransform', function(assert) {
|
||||
{
|
||||
let mat = cv.Mat.ones(11, 11, cv.CV_8UC1);
|
||||
let out = new cv.Mat(11, 11, cv.CV_32FC1);
|
||||
let labels = new cv.Mat(11, 11, cv.CV_32FC1);
|
||||
const maskSize = 3;
|
||||
cv.distanceTransform(mat, out, cv.DIST_L2, maskSize, cv.CV_32F);
|
||||
|
||||
// Verify result.
|
||||
let size = out.size();
|
||||
assert.equal(out.channels(), 1);
|
||||
assert.equal(size.height, 11);
|
||||
assert.equal(size.width, 11);
|
||||
assert.equal(out.elemSize1(), 4);
|
||||
|
||||
cv.distanceTransformWithLabels(mat, out, labels, cv.DIST_L2, maskSize,
|
||||
cv.DIST_LABEL_CCOMP);
|
||||
|
||||
// Verify result.
|
||||
size = out.size();
|
||||
assert.equal(out.channels(), 1);
|
||||
assert.equal(size.height, 11);
|
||||
assert.equal(size.width, 11);
|
||||
assert.equal(out.elemSize1(), 4);
|
||||
|
||||
size = labels.size();
|
||||
assert.equal(labels.channels(), 1);
|
||||
assert.equal(size.height, 11);
|
||||
assert.equal(size.width, 11);
|
||||
assert.equal(labels.elemSize1(), 4);
|
||||
|
||||
mat.delete();
|
||||
out.delete();
|
||||
labels.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_integral', function(assert) {
|
||||
{
|
||||
let mat = cv.Mat.eye({height: 100, width: 100}, cv.CV_8UC3);
|
||||
let sum = new cv.Mat();
|
||||
let sqSum = new cv.Mat();
|
||||
let title = new cv.Mat();
|
||||
|
||||
cv.integral(mat, sum, -1);
|
||||
|
||||
// Verify result.
|
||||
let size = sum.size();
|
||||
assert.equal(sum.channels(), 3);
|
||||
assert.equal(size.height, 100+1);
|
||||
assert.equal(size.width, 100+1);
|
||||
|
||||
cv.integral2(mat, sum, sqSum, -1, -1);
|
||||
// Verify result.
|
||||
size = sum.size();
|
||||
assert.equal(sum.channels(), 3);
|
||||
assert.equal(size.height, 100+1);
|
||||
assert.equal(size.width, 100+1);
|
||||
|
||||
size = sqSum.size();
|
||||
assert.equal(sqSum.channels(), 3);
|
||||
assert.equal(size.height, 100+1);
|
||||
assert.equal(size.width, 100+1);
|
||||
|
||||
mat.delete();
|
||||
sum.delete();
|
||||
sqSum.delete();
|
||||
title.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_rotatedRectangleIntersection', function(assert) {
|
||||
{
|
||||
let dst = cv.Mat.zeros(80, 80, cv.CV_8U);
|
||||
let contours = new cv.MatVector();
|
||||
let hierarchy = new cv.Mat();
|
||||
let intersectionPoints = new cv.Mat();
|
||||
|
||||
cv.drawMarker(dst, new cv.Point(40, 40), new cv.Scalar(255));
|
||||
cv.findContoursLinkRuns(dst,contours,hierarchy);
|
||||
let rr1 = cv.minAreaRect(contours.get(0));
|
||||
let rr2 = cv.minAreaRect(contours.get(0));
|
||||
let rr3 = new cv.RotatedRect({x: 40, y: 40}, {height: 10, width: 20}, 45);
|
||||
|
||||
let intersectionType = cv.rotatedRectangleIntersection(rr1, rr2, intersectionPoints);
|
||||
|
||||
// Verify result.
|
||||
assert.deepEqual(intersectionType, cv.INTERSECT_FULL);
|
||||
intersectionPoints.convertTo(intersectionPoints, cv.CV_32S);
|
||||
let intersectionPointsData = intersectionPoints.data32S;
|
||||
assert.deepEqual(intersectionPointsData[0], 40);
|
||||
assert.deepEqual(intersectionPointsData[1], 50);
|
||||
assert.deepEqual(intersectionPointsData[2], 30);
|
||||
assert.deepEqual(intersectionPointsData[3], 40);
|
||||
assert.deepEqual(intersectionPointsData[4], 40);
|
||||
assert.deepEqual(intersectionPointsData[5], 30);
|
||||
assert.deepEqual(intersectionPointsData[6], 50);
|
||||
assert.deepEqual(intersectionPointsData[7], 40);
|
||||
|
||||
intersectionType = cv.rotatedRectangleIntersection(rr1, rr3, intersectionPoints);
|
||||
|
||||
// Verify result.
|
||||
assert.deepEqual(intersectionType, cv.INTERSECT_PARTIAL);
|
||||
intersectionPoints.convertTo(intersectionPoints, cv.CV_32S);
|
||||
intersectionPointsData = intersectionPoints.data32S;
|
||||
assert.deepEqual(intersectionPointsData[0], 39);
|
||||
assert.deepEqual(intersectionPointsData[1], 31);
|
||||
assert.deepEqual(intersectionPointsData[2], 49);
|
||||
assert.deepEqual(intersectionPointsData[3], 41);
|
||||
assert.deepEqual(intersectionPointsData[4], 41);
|
||||
assert.deepEqual(intersectionPointsData[5], 49);
|
||||
assert.deepEqual(intersectionPointsData[6], 31);
|
||||
assert.deepEqual(intersectionPointsData[7], 39);
|
||||
|
||||
dst.delete();
|
||||
contours.delete();
|
||||
hierarchy.delete();
|
||||
intersectionPoints.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('warpPolar', function(assert) {
|
||||
const lines = new cv.Mat(255, 255, cv.CV_8U, new cv.Scalar(0));
|
||||
for (let r = 0; r < lines.rows; r++) {
|
||||
lines.row(r).setTo(new cv.Scalar(r));
|
||||
}
|
||||
cv.warpPolar(lines, lines, { width: 5, height: 5 }, new cv.Point(2, 2), 3,
|
||||
cv.INTER_CUBIC | cv.WARP_FILL_OUTLIERS | cv.WARP_INVERSE_MAP);
|
||||
assert.ok(lines instanceof cv.Mat);
|
||||
assert.deepEqual(Array.from(lines.data), [
|
||||
159, 172, 191, 210, 223,
|
||||
146, 159, 191, 223, 236,
|
||||
128, 128, 0, 0, 0,
|
||||
109, 96, 64, 32, 19,
|
||||
96, 83, 64, 45, 32
|
||||
]);
|
||||
});
|
||||
|
||||
QUnit.test('IntelligentScissorsMB', function(assert) {
|
||||
const lines = new cv.Mat(50, 100, cv.CV_8U, new cv.Scalar(0));
|
||||
lines.row(10).setTo(new cv.Scalar(255));
|
||||
assert.ok(lines instanceof cv.Mat);
|
||||
|
||||
let tool = new cv.segmentation_IntelligentScissorsMB();
|
||||
tool.applyImage(lines);
|
||||
assert.ok(lines instanceof cv.Mat);
|
||||
lines.delete();
|
||||
|
||||
tool.buildMap(new cv.Point(10, 10));
|
||||
|
||||
let contour = new cv.Mat();
|
||||
tool.getContour(new cv.Point(50, 10), contour);
|
||||
assert.equal(contour.type(), cv.CV_32SC2);
|
||||
assert.ok(contour.total() == 41, contour.total());
|
||||
|
||||
tool.getContour(new cv.Point(80, 10), contour);
|
||||
assert.equal(contour.type(), cv.CV_32SC2);
|
||||
assert.ok(contour.total() == 71, contour.total());
|
||||
});
|
||||
@@ -0,0 +1,982 @@
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu
|
||||
//
|
||||
// LICENSE AGREEMENT
|
||||
// Copyright (c) 2015 The Regents of the University of California (Regents)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the University nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
QUnit.module('CoreMat', {});
|
||||
|
||||
QUnit.test('test_mat_creation', function(assert) {
|
||||
// Mat constructors.
|
||||
// Mat::Mat(int rows, int cols, int type)
|
||||
{
|
||||
let mat = new cv.Mat(10, 20, cv.CV_8UC3);
|
||||
|
||||
assert.equal(mat.type(), cv.CV_8UC3);
|
||||
assert.equal(mat.depth(), cv.CV_8U);
|
||||
assert.equal(mat.channels(), 3);
|
||||
assert.ok(mat.empty() === false);
|
||||
|
||||
let size = mat.size();
|
||||
assert.equal(size.height, 10);
|
||||
assert.equal(size.width, 20);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// Mat::Mat(const Mat &)
|
||||
{
|
||||
// Copy from another Mat
|
||||
let mat1 = new cv.Mat(10, 20, cv.CV_8UC3);
|
||||
let mat2 = new cv.Mat(mat1);
|
||||
|
||||
assert.equal(mat2.type(), mat1.type());
|
||||
assert.equal(mat2.depth(), mat1.depth());
|
||||
assert.equal(mat2.channels(), mat1.channels());
|
||||
assert.equal(mat2.empty(), mat1.empty());
|
||||
|
||||
let size1 = mat1.size;
|
||||
let size2 = mat2.size();
|
||||
assert.ok(size1[0] === size2[0]);
|
||||
assert.ok(size1[1] === size2[1]);
|
||||
|
||||
mat1.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
|
||||
// Mat::Mat(int rows, int cols, int type, void *data, size_t step=AUTO_STEP)
|
||||
{
|
||||
// 10 * 10 and one channel
|
||||
let data = cv._malloc(10 * 10 * 1);
|
||||
let mat = new cv.Mat(10, 10, cv.CV_8UC1, data, 0);
|
||||
|
||||
assert.equal(mat.type(), cv.CV_8UC1);
|
||||
assert.equal(mat.depth(), cv.CV_8U);
|
||||
assert.equal(mat.channels(), 1);
|
||||
assert.ok(mat.empty() === false);
|
||||
|
||||
let size = mat.size();
|
||||
assert.ok(size.height === 10);
|
||||
assert.ok(size.width === 10);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// Mat::Mat(int rows, int cols, int type, const Scalar& scalar)
|
||||
{
|
||||
// 2 * 2 8UC4 mat
|
||||
let mat = new cv.Mat(2, 2, cv.CV_8UC4, [0, 1, 2, 3]);
|
||||
|
||||
for (let r = 0; r < mat.rows; r++) {
|
||||
for (let c = 0; c < mat.cols; c++) {
|
||||
let element = mat.ptr(r, c);
|
||||
assert.equal(element[0], 0);
|
||||
assert.equal(element[1], 1);
|
||||
assert.equal(element[2], 2);
|
||||
assert.equal(element[3], 3);
|
||||
}
|
||||
}
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// Mat::create(int, int, int)
|
||||
{
|
||||
let mat = new cv.Mat();
|
||||
mat.create(10, 5, cv.CV_8UC3);
|
||||
let size = mat.size();
|
||||
|
||||
assert.ok(mat.type() === cv.CV_8UC3);
|
||||
assert.ok(size.height === 10);
|
||||
assert.ok(size.width === 5);
|
||||
assert.ok(mat.channels() === 3);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
// Mat::create(Size, int)
|
||||
{
|
||||
let mat = new cv.Mat();
|
||||
mat.create({height: 10, width: 5}, cv.CV_8UC4);
|
||||
let size = mat.size();
|
||||
|
||||
assert.ok(mat.type() === cv.CV_8UC4);
|
||||
assert.ok(size.height === 10);
|
||||
assert.ok(size.width === 5);
|
||||
assert.ok(mat.channels() === 4);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
// clone
|
||||
{
|
||||
let mat = cv.Mat.ones(5, 5, cv.CV_8UC1);
|
||||
let mat2 = mat.clone();
|
||||
|
||||
assert.equal(mat.channels, mat2.channels);
|
||||
assert.equal(mat.size().height, mat2.size().height);
|
||||
assert.equal(mat.size().width, mat2.size().width);
|
||||
|
||||
assert.deepEqual(mat.data, mat2.data);
|
||||
|
||||
|
||||
mat.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
// copyTo
|
||||
{
|
||||
let mat = cv.Mat.ones(5, 5, cv.CV_8UC1);
|
||||
let mat2 = new cv.Mat();
|
||||
mat.copyTo(mat2);
|
||||
|
||||
assert.equal(mat.channels, mat2.channels);
|
||||
assert.equal(mat.size().height, mat2.size().height);
|
||||
assert.equal(mat.size().width, mat2.size().width);
|
||||
|
||||
assert.deepEqual(mat.data, mat2.data);
|
||||
|
||||
|
||||
mat.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
// copyTo1
|
||||
{
|
||||
let mat = cv.Mat.ones(5, 5, cv.CV_8UC1);
|
||||
let mat2 = new cv.Mat();
|
||||
let mask = new cv.Mat(5, 5, cv.CV_8UC1, new cv.Scalar(1));
|
||||
mat.copyTo(mat2, mask);
|
||||
|
||||
assert.equal(mat.channels, mat2.channels);
|
||||
assert.equal(mat.size().height, mat2.size().height);
|
||||
assert.equal(mat.size().width, mat2.size().width);
|
||||
|
||||
assert.deepEqual(mat.data, mat2.data);
|
||||
|
||||
|
||||
mat.delete();
|
||||
mat2.delete();
|
||||
mask.delete();
|
||||
}
|
||||
|
||||
// matFromArray
|
||||
{
|
||||
let arrayC1 = [0, -1, 2, -3];
|
||||
let arrayC2 = [0, -1, 2, -3, 4, -5, 6, -7];
|
||||
let arrayC3 = [0, -1, 2, -3, 4, -5, 6, -7, 9, -9, 10, -11];
|
||||
let arrayC4 = [0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, 13, 14, 15];
|
||||
|
||||
let mat8UC1 = cv.matFromArray(2, 2, cv.CV_8UC1, arrayC1);
|
||||
let mat8UC2 = cv.matFromArray(2, 2, cv.CV_8UC2, arrayC2);
|
||||
let mat8UC3 = cv.matFromArray(2, 2, cv.CV_8UC3, arrayC3);
|
||||
let mat8UC4 = cv.matFromArray(2, 2, cv.CV_8UC4, arrayC4);
|
||||
|
||||
let mat8SC1 = cv.matFromArray(2, 2, cv.CV_8SC1, arrayC1);
|
||||
let mat8SC2 = cv.matFromArray(2, 2, cv.CV_8SC2, arrayC2);
|
||||
let mat8SC3 = cv.matFromArray(2, 2, cv.CV_8SC3, arrayC3);
|
||||
let mat8SC4 = cv.matFromArray(2, 2, cv.CV_8SC4, arrayC4);
|
||||
|
||||
let mat16UC1 = cv.matFromArray(2, 2, cv.CV_16UC1, arrayC1);
|
||||
let mat16UC2 = cv.matFromArray(2, 2, cv.CV_16UC2, arrayC2);
|
||||
let mat16UC3 = cv.matFromArray(2, 2, cv.CV_16UC3, arrayC3);
|
||||
let mat16UC4 = cv.matFromArray(2, 2, cv.CV_16UC4, arrayC4);
|
||||
|
||||
let mat16SC1 = cv.matFromArray(2, 2, cv.CV_16SC1, arrayC1);
|
||||
let mat16SC2 = cv.matFromArray(2, 2, cv.CV_16SC2, arrayC2);
|
||||
let mat16SC3 = cv.matFromArray(2, 2, cv.CV_16SC3, arrayC3);
|
||||
let mat16SC4 = cv.matFromArray(2, 2, cv.CV_16SC4, arrayC4);
|
||||
|
||||
let mat32SC1 = cv.matFromArray(2, 2, cv.CV_32SC1, arrayC1);
|
||||
let mat32SC2 = cv.matFromArray(2, 2, cv.CV_32SC2, arrayC2);
|
||||
let mat32SC3 = cv.matFromArray(2, 2, cv.CV_32SC3, arrayC3);
|
||||
let mat32SC4 = cv.matFromArray(2, 2, cv.CV_32SC4, arrayC4);
|
||||
|
||||
let mat32FC1 = cv.matFromArray(2, 2, cv.CV_32FC1, arrayC1);
|
||||
let mat32FC2 = cv.matFromArray(2, 2, cv.CV_32FC2, arrayC2);
|
||||
let mat32FC3 = cv.matFromArray(2, 2, cv.CV_32FC3, arrayC3);
|
||||
let mat32FC4 = cv.matFromArray(2, 2, cv.CV_32FC4, arrayC4);
|
||||
|
||||
let mat64FC1 = cv.matFromArray(2, 2, cv.CV_64FC1, arrayC1);
|
||||
let mat64FC2 = cv.matFromArray(2, 2, cv.CV_64FC2, arrayC2);
|
||||
let mat64FC3 = cv.matFromArray(2, 2, cv.CV_64FC3, arrayC3);
|
||||
let mat64FC4 = cv.matFromArray(2, 2, cv.CV_64FC4, arrayC4);
|
||||
|
||||
assert.deepEqual(mat8UC1.data, new Uint8Array(arrayC1));
|
||||
assert.deepEqual(mat8UC2.data, new Uint8Array(arrayC2));
|
||||
assert.deepEqual(mat8UC3.data, new Uint8Array(arrayC3));
|
||||
assert.deepEqual(mat8UC4.data, new Uint8Array(arrayC4));
|
||||
|
||||
assert.deepEqual(mat8SC1.data8S, new Int8Array(arrayC1));
|
||||
assert.deepEqual(mat8SC2.data8S, new Int8Array(arrayC2));
|
||||
assert.deepEqual(mat8SC3.data8S, new Int8Array(arrayC3));
|
||||
assert.deepEqual(mat8SC4.data8S, new Int8Array(arrayC4));
|
||||
|
||||
assert.deepEqual(mat16UC1.data16U, new Uint16Array(arrayC1));
|
||||
assert.deepEqual(mat16UC2.data16U, new Uint16Array(arrayC2));
|
||||
assert.deepEqual(mat16UC3.data16U, new Uint16Array(arrayC3));
|
||||
assert.deepEqual(mat16UC4.data16U, new Uint16Array(arrayC4));
|
||||
|
||||
assert.deepEqual(mat16SC1.data16S, new Int16Array(arrayC1));
|
||||
assert.deepEqual(mat16SC2.data16S, new Int16Array(arrayC2));
|
||||
assert.deepEqual(mat16SC3.data16S, new Int16Array(arrayC3));
|
||||
assert.deepEqual(mat16SC4.data16S, new Int16Array(arrayC4));
|
||||
|
||||
assert.deepEqual(mat32SC1.data32S, new Int32Array(arrayC1));
|
||||
assert.deepEqual(mat32SC2.data32S, new Int32Array(arrayC2));
|
||||
assert.deepEqual(mat32SC3.data32S, new Int32Array(arrayC3));
|
||||
assert.deepEqual(mat32SC4.data32S, new Int32Array(arrayC4));
|
||||
|
||||
assert.deepEqual(mat32FC1.data32F, new Float32Array(arrayC1));
|
||||
assert.deepEqual(mat32FC2.data32F, new Float32Array(arrayC2));
|
||||
assert.deepEqual(mat32FC3.data32F, new Float32Array(arrayC3));
|
||||
assert.deepEqual(mat32FC4.data32F, new Float32Array(arrayC4));
|
||||
|
||||
assert.deepEqual(mat64FC1.data64F, new Float64Array(arrayC1));
|
||||
assert.deepEqual(mat64FC2.data64F, new Float64Array(arrayC2));
|
||||
assert.deepEqual(mat64FC3.data64F, new Float64Array(arrayC3));
|
||||
assert.deepEqual(mat64FC4.data64F, new Float64Array(arrayC4));
|
||||
|
||||
mat8UC1.delete();
|
||||
mat8UC2.delete();
|
||||
mat8UC3.delete();
|
||||
mat8UC4.delete();
|
||||
mat8SC1.delete();
|
||||
mat8SC2.delete();
|
||||
mat8SC3.delete();
|
||||
mat8SC4.delete();
|
||||
mat16UC1.delete();
|
||||
mat16UC2.delete();
|
||||
mat16UC3.delete();
|
||||
mat16UC4.delete();
|
||||
mat16SC1.delete();
|
||||
mat16SC2.delete();
|
||||
mat16SC3.delete();
|
||||
mat16SC4.delete();
|
||||
mat32SC1.delete();
|
||||
mat32SC2.delete();
|
||||
mat32SC3.delete();
|
||||
mat32SC4.delete();
|
||||
mat32FC1.delete();
|
||||
mat32FC2.delete();
|
||||
mat32FC3.delete();
|
||||
mat32FC4.delete();
|
||||
mat64FC1.delete();
|
||||
mat64FC2.delete();
|
||||
mat64FC3.delete();
|
||||
mat64FC4.delete();
|
||||
}
|
||||
|
||||
// matFromImageData
|
||||
{
|
||||
// Only test in browser
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
let canvas = window.document.createElement('canvas');
|
||||
canvas.width = 2;
|
||||
canvas.height = 2;
|
||||
let ctx = canvas.getContext('2d');
|
||||
ctx.fillStyle='#FF0000';
|
||||
ctx.fillRect(0, 0, 1, 1);
|
||||
ctx.fillRect(1, 1, 1, 1);
|
||||
|
||||
let imageData = ctx.getImageData(0, 0, 2, 2);
|
||||
let mat = cv.matFromImageData(imageData);
|
||||
|
||||
assert.deepEqual(mat.data, new Uint8Array(imageData.data));
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// Mat(mat)
|
||||
{
|
||||
let mat = new cv.Mat(2, 2, cv.CV_8UC4, new cv.Scalar(1, 0, 1, 0));
|
||||
let mat1 = new cv.Mat(mat);
|
||||
let mat2 = mat;
|
||||
|
||||
assert.equal(mat.rows, mat1.rows);
|
||||
assert.equal(mat.cols, mat1.cols);
|
||||
assert.equal(mat.type(), mat1.type());
|
||||
assert.deepEqual(mat.data, mat1.data);
|
||||
|
||||
mat.delete();
|
||||
|
||||
assert.equal(mat1.isDeleted(), false);
|
||||
assert.equal(mat2.isDeleted(), true);
|
||||
|
||||
mat1.delete();
|
||||
}
|
||||
|
||||
// mat.setTo
|
||||
{
|
||||
let mat = new cv.Mat(2, 2, cv.CV_8UC4);
|
||||
let s = [0, 1, 2, 3];
|
||||
|
||||
mat.setTo(s);
|
||||
|
||||
assert.deepEqual(mat.ptr(0, 0), new Uint8Array(s));
|
||||
assert.deepEqual(mat.ptr(0, 1), new Uint8Array(s));
|
||||
assert.deepEqual(mat.ptr(1, 0), new Uint8Array(s));
|
||||
assert.deepEqual(mat.ptr(1, 1), new Uint8Array(s));
|
||||
|
||||
let s1 = [0, 0, 0, 0];
|
||||
mat.setTo(s1);
|
||||
let mask = cv.matFromArray(2, 2, cv.CV_8UC1, [0, 1, 0, 1]);
|
||||
mat.setTo(s, mask);
|
||||
|
||||
assert.deepEqual(mat.ptr(0, 0), new Uint8Array(s1));
|
||||
assert.deepEqual(mat.ptr(0, 1), new Uint8Array(s));
|
||||
assert.deepEqual(mat.ptr(1, 0), new Uint8Array(s1));
|
||||
assert.deepEqual(mat.ptr(1, 1), new Uint8Array(s));
|
||||
|
||||
mat.delete();
|
||||
mask.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_mat_ptr', function(assert) {
|
||||
const RValue = 3;
|
||||
const GValue = 7;
|
||||
const BValue = 197;
|
||||
|
||||
// cv.CV_8UC1 + Mat::ptr(int).
|
||||
{
|
||||
let mat = new cv.Mat(10, 10, cv.CV_8UC1);
|
||||
let view = mat.data;
|
||||
|
||||
// Alter matrix[2, 1].
|
||||
let step = 10;
|
||||
view[2 * step + 1] = RValue;
|
||||
|
||||
// Access matrix[2, 1].
|
||||
view = mat.ptr(2);
|
||||
|
||||
assert.equal(view[1], RValue);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// cv.CV_8UC3 + Mat::ptr(int).
|
||||
{
|
||||
let mat = new cv.Mat(10, 10, cv.CV_8UC3);
|
||||
let view = mat.data;
|
||||
|
||||
// Alter matrix[2, 1].
|
||||
let step = 3 * 10;
|
||||
view[2 * step + 3] = RValue;
|
||||
view[2 * step + 3 + 1] = GValue;
|
||||
view[2 * step + 3 + 2] = BValue;
|
||||
|
||||
// Access matrix[2, 1].
|
||||
view = mat.ptr(2);
|
||||
|
||||
assert.equal(view[3], RValue);
|
||||
assert.equal(view[3 + 1], GValue);
|
||||
assert.equal(view[3 + 2], BValue);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// cv.CV_8UC3 + Mat::ptr(int, int).
|
||||
{
|
||||
let mat = new cv.Mat(10, 10, cv.CV_8UC3);
|
||||
let view = mat.data;
|
||||
|
||||
// Alter matrix[2, 1].
|
||||
let step = 3 * 10;
|
||||
view[2 * step + 3] = RValue;
|
||||
view[2 * step + 3 + 1] = GValue;
|
||||
view[2 * step + 3 + 2] = BValue;
|
||||
|
||||
// Access matrix[2, 1].
|
||||
view = mat.ptr(2, 1);
|
||||
|
||||
assert.equal(view[0], RValue);
|
||||
assert.equal(view[1], GValue);
|
||||
assert.equal(view[2], BValue);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
const RValueF32 = 3.3;
|
||||
const GValueF32 = 7.3;
|
||||
const BValueF32 = 197.3;
|
||||
const EPSILON = 0.001;
|
||||
|
||||
// cv.CV_32FC1 + Mat::ptr(int).
|
||||
{
|
||||
let mat = new cv.Mat(10, 10, cv.CV_32FC1);
|
||||
let view = mat.data32F;
|
||||
|
||||
// Alter matrix[2, 1].
|
||||
let step = 10;
|
||||
view[2 * step + 1] = RValueF32;
|
||||
|
||||
// Access matrix[2, 1].
|
||||
view = mat.floatPtr(2);
|
||||
|
||||
assert.ok(Math.abs(view[1] - RValueF32) < EPSILON);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// cv.CV_32FC3 + Mat::ptr(int).
|
||||
{
|
||||
let mat = new cv.Mat(10, 10, cv.CV_32FC3);
|
||||
let view = mat.data32F;
|
||||
|
||||
// Alter matrix[2, 1].
|
||||
let step = mat.step1(0);
|
||||
view[2 * step + 3] = RValueF32;
|
||||
view[2 * step + 3 + 1] = GValueF32;
|
||||
view[2 * step + 3 + 2] = BValueF32;
|
||||
|
||||
// Access matrix[2, 1].
|
||||
view = mat.floatPtr(2);
|
||||
|
||||
assert.ok(Math.abs(view[3] - RValueF32) < EPSILON);
|
||||
assert.ok(Math.abs(view[3 + 1] - GValueF32) < EPSILON);
|
||||
assert.ok(Math.abs(view[3 + 2] - BValueF32) < EPSILON);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// cv.CV_32FC3 + Mat::ptr(int, int).
|
||||
{
|
||||
let mat = new cv.Mat(10, 10, cv.CV_32FC3);
|
||||
let view = mat.data32F;
|
||||
|
||||
// Alter matrix[2, 1].
|
||||
let step = mat.step1(0);
|
||||
view[2 * step + 3] = RValueF32;
|
||||
view[2 * step + 3 + 1] = GValueF32;
|
||||
view[2 * step + 3 + 2] = BValueF32;
|
||||
|
||||
// Access matrix[2, 1].
|
||||
view = mat.floatPtr(2, 1);
|
||||
|
||||
assert.ok(Math.abs(view[0] - RValueF32) < EPSILON);
|
||||
assert.ok(Math.abs(view[1] - GValueF32) < EPSILON);
|
||||
assert.ok(Math.abs(view[2] - BValueF32) < EPSILON);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_mat_zeros', function(assert) {
|
||||
let zeros = new Uint8Array(10*10).fill(0);
|
||||
// Mat::zeros(int, int, int)
|
||||
{
|
||||
let mat = cv.Mat.zeros(10, 10, cv.CV_8UC1);
|
||||
let view = mat.data;
|
||||
|
||||
assert.deepEqual(view, zeros);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// Mat::zeros(Size, int)
|
||||
{
|
||||
let mat = cv.Mat.zeros({height: 10, width: 10}, cv.CV_8UC1);
|
||||
let view = mat.data;
|
||||
|
||||
assert.deepEqual(view, zeros);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_mat_ones', function(assert) {
|
||||
let ones = new Uint8Array(10*10).fill(1);
|
||||
// Mat::ones(int, int, int)
|
||||
{
|
||||
let mat = cv.Mat.ones(10, 10, cv.CV_8UC1);
|
||||
let view = mat.data;
|
||||
|
||||
assert.deepEqual(view, ones);
|
||||
}
|
||||
// Mat::ones(Size, int)
|
||||
{
|
||||
let mat = cv.Mat.ones({height: 10, width: 10}, cv.CV_8UC1);
|
||||
let view = mat.data;
|
||||
|
||||
assert.deepEqual(view, ones);
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_mat_eye', function(assert) {
|
||||
let eye4by4 = new Uint8Array([1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1]);
|
||||
// Mat::eye(int, int, int)
|
||||
{
|
||||
let mat = cv.Mat.eye(4, 4, cv.CV_8UC1);
|
||||
let view = mat.data;
|
||||
|
||||
assert.deepEqual(view, eye4by4);
|
||||
}
|
||||
|
||||
// Mat::eye(Size, int)
|
||||
{
|
||||
let mat = cv.Mat.eye({height: 4, width: 4}, cv.CV_8UC1);
|
||||
let view = mat.data;
|
||||
|
||||
assert.deepEqual(view, eye4by4);
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_mat_miscs', function(assert) {
|
||||
// Mat::col(int)
|
||||
{
|
||||
let mat = cv.matFromArray(2, 2, cv.CV_8UC2, [1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
let col = mat.col(1);
|
||||
|
||||
assert.equal(col.isContinuous(), false);
|
||||
assert.equal(col.ptr(0, 0)[0], 3);
|
||||
assert.equal(col.ptr(0, 0)[1], 4);
|
||||
assert.equal(col.ptr(1, 0)[0], 7);
|
||||
assert.equal(col.ptr(1, 0)[1], 8);
|
||||
|
||||
col.delete();
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// Mat::row(int)
|
||||
{
|
||||
let mat = cv.Mat.zeros(5, 5, cv.CV_8UC2);
|
||||
let row = mat.row(1);
|
||||
let view = row.data;
|
||||
assert.equal(view[0], 0);
|
||||
assert.equal(view[4], 0);
|
||||
|
||||
row.delete();
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// Mat::convertTo(Mat, int, double, double)
|
||||
{
|
||||
let mat = cv.Mat.ones(5, 5, cv.CV_8UC3);
|
||||
let grayMat = cv.Mat.zeros(5, 5, cv.CV_8UC1);
|
||||
|
||||
mat.convertTo(grayMat, cv.CV_8U, 2, 1);
|
||||
// dest = 2 * source(x, y) + 1.
|
||||
let view = grayMat.data;
|
||||
assert.equal(view[0], (1 * 2) + 1);
|
||||
|
||||
mat.convertTo(grayMat, cv.CV_8U);
|
||||
// dest = 1 * source(x, y) + 0.
|
||||
assert.equal(view[0], 1);
|
||||
|
||||
mat.convertTo(grayMat, cv.CV_8U, 2);
|
||||
// dest = 2 * source(x, y) + 0.
|
||||
assert.equal(view[0], 2);
|
||||
|
||||
grayMat.delete();
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
// split
|
||||
{
|
||||
const R =7;
|
||||
const G =13;
|
||||
const B =29;
|
||||
|
||||
let mat = cv.Mat.ones(5, 5, cv.CV_8UC3);
|
||||
let view = mat.data;
|
||||
view[0] = R;
|
||||
view[1] = G;
|
||||
view[2] = B;
|
||||
|
||||
let bgrPlanes = new cv.MatVector();
|
||||
cv.split(mat, bgrPlanes);
|
||||
assert.equal(bgrPlanes.size(), 3);
|
||||
|
||||
let rMat = bgrPlanes.get(0);
|
||||
view = rMat.data;
|
||||
assert.equal(view[0], R);
|
||||
|
||||
let gMat = bgrPlanes.get(1);
|
||||
view = gMat.data;
|
||||
assert.equal(view[0], G);
|
||||
|
||||
let bMat = bgrPlanes.get(2);
|
||||
view = bMat.data;
|
||||
assert.equal(view[0], B);
|
||||
|
||||
mat.delete();
|
||||
rMat.delete();
|
||||
gMat.delete();
|
||||
bgrPlanes.delete();
|
||||
bMat.delete();
|
||||
}
|
||||
|
||||
// elemSize
|
||||
{
|
||||
let mat = cv.Mat.ones(5, 5, cv.CV_8UC3);
|
||||
assert.equal(mat.elemSize(), 3);
|
||||
assert.equal(mat.elemSize1(), 1);
|
||||
|
||||
let mat2 = cv.Mat.zeros(5, 5, cv.CV_8UC1);
|
||||
assert.equal(mat2.elemSize(), 1);
|
||||
assert.equal(mat2.elemSize1(), 1);
|
||||
|
||||
let mat3 = cv.Mat.eye(5, 5, cv.CV_16UC3);
|
||||
assert.equal(mat3.elemSize(), 2 * 3);
|
||||
assert.equal(mat3.elemSize1(), 2);
|
||||
|
||||
mat.delete();
|
||||
mat2.delete();
|
||||
mat3.delete();
|
||||
}
|
||||
|
||||
// step
|
||||
{
|
||||
let mat = cv.Mat.ones(5, 5, cv.CV_8UC3);
|
||||
assert.equal(mat.step[0], 15);
|
||||
assert.equal(mat.step[1], 3);
|
||||
|
||||
let mat2 = cv.Mat.zeros(5, 5, cv.CV_8UC1);
|
||||
assert.equal(mat2.step[0], 5);
|
||||
assert.equal(mat2.step[1], 1);
|
||||
|
||||
let mat3 = cv.Mat.eye(5, 5, cv.CV_16UC3);
|
||||
assert.equal(mat3.step[0], 30);
|
||||
assert.equal(mat3.step[1], 6);
|
||||
|
||||
mat.delete();
|
||||
mat2.delete();
|
||||
mat3.delete();
|
||||
}
|
||||
|
||||
// dot
|
||||
{
|
||||
let mat = cv.Mat.ones(5, 5, cv.CV_8UC1);
|
||||
let mat2 = cv.Mat.eye(5, 5, cv.CV_8UC1);
|
||||
|
||||
assert.equal(mat.dot(mat), 25);
|
||||
assert.equal(mat.dot(mat2), 5);
|
||||
assert.equal(mat2.dot(mat2), 5);
|
||||
|
||||
mat.delete();
|
||||
mat2.delete();
|
||||
}
|
||||
|
||||
// mul
|
||||
{
|
||||
const FACTOR = 5;
|
||||
let mat = cv.Mat.ones(4, 4, cv.CV_8UC1);
|
||||
let mat2 = cv.Mat.eye(4, 4, cv.CV_8UC1);
|
||||
|
||||
let expected = new Uint8Array([FACTOR, 0, 0, 0,
|
||||
0, FACTOR, 0, 0,
|
||||
0, 0, FACTOR, 0,
|
||||
0, 0, 0, FACTOR]);
|
||||
let mat3 = mat.mul(mat2, FACTOR);
|
||||
|
||||
assert.deepEqual(mat3.data, expected);
|
||||
|
||||
mat.delete();
|
||||
mat2.delete();
|
||||
mat3.delete();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
QUnit.test('test mat access', function(assert) {
|
||||
// test memory view
|
||||
{
|
||||
let data = new Uint8Array([0, 0, 0, 255, 0, 1, 2, 3]);
|
||||
let dataPtr = cv._malloc(8);
|
||||
|
||||
let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 8);
|
||||
dataHeap.set(new Uint8Array(data.buffer));
|
||||
|
||||
let mat = new cv.Mat(8, 1, cv.CV_8UC1, dataPtr, 0);
|
||||
|
||||
|
||||
let unsignedCharView = new Uint8Array(data.buffer);
|
||||
let charView = new Int8Array(data.buffer);
|
||||
let shortView = new Int16Array(data.buffer);
|
||||
let unsignedShortView = new Uint16Array(data.buffer);
|
||||
let intView = new Int32Array(data.buffer);
|
||||
let float32View = new Float32Array(data.buffer);
|
||||
let float64View = new Float64Array(data.buffer);
|
||||
|
||||
|
||||
assert.deepEqual(unsignedCharView, mat.data);
|
||||
assert.deepEqual(charView, mat.data8S);
|
||||
assert.deepEqual(shortView, mat.data16S);
|
||||
assert.deepEqual(unsignedShortView, mat.data16U);
|
||||
assert.deepEqual(intView, mat.data32S);
|
||||
assert.deepEqual(float32View, mat.data32F);
|
||||
assert.deepEqual(float64View, mat.data64F);
|
||||
}
|
||||
|
||||
// test ucharAt(i)
|
||||
{
|
||||
let data = new Uint8Array([0, 0, 0, 255, 0, 1, 2, 3]);
|
||||
let dataPtr = cv._malloc(8);
|
||||
|
||||
let dataHeap = new Uint8Array(cv.HEAPU8.buffer, dataPtr, 8);
|
||||
dataHeap.set(new Uint8Array(data.buffer));
|
||||
|
||||
let mat = new cv.Mat(8, 1, cv.CV_8UC1, dataPtr, 0);
|
||||
|
||||
assert.equal(mat.ucharAt(0), 0);
|
||||
assert.equal(mat.ucharAt(1), 0);
|
||||
assert.equal(mat.ucharAt(2), 0);
|
||||
assert.equal(mat.ucharAt(3), 255);
|
||||
assert.equal(mat.ucharAt(4), 0);
|
||||
assert.equal(mat.ucharAt(5), 1);
|
||||
assert.equal(mat.ucharAt(6), 2);
|
||||
assert.equal(mat.ucharAt(7), 3);
|
||||
}
|
||||
|
||||
// test ushortAt(i)
|
||||
{
|
||||
let data = new Uint16Array([0, 1000, 65000, 255, 0, 1, 2, 3]);
|
||||
let dataPtr = cv._malloc(16);
|
||||
|
||||
let dataHeap = new Uint16Array(cv.HEAPU8.buffer, dataPtr, 8);
|
||||
dataHeap.set(new Uint16Array(data.buffer));
|
||||
|
||||
let mat = new cv.Mat(8, 1, cv.CV_16SC1, dataPtr, 0);
|
||||
|
||||
assert.equal(mat.ushortAt(0), 0);
|
||||
assert.equal(mat.ushortAt(1), 1000);
|
||||
assert.equal(mat.ushortAt(2), 65000);
|
||||
assert.equal(mat.ushortAt(3), 255);
|
||||
assert.equal(mat.ushortAt(4), 0);
|
||||
assert.equal(mat.ushortAt(5), 1);
|
||||
assert.equal(mat.ushortAt(6), 2);
|
||||
assert.equal(mat.ushortAt(7), 3);
|
||||
}
|
||||
|
||||
// test intAt(i)
|
||||
{
|
||||
let data = new Int32Array([0, -1000, 65000, 255, -2000000, -1, 2, 3]);
|
||||
let dataPtr = cv._malloc(32);
|
||||
|
||||
let dataHeap = new Int32Array(cv.HEAPU32.buffer, dataPtr, 8);
|
||||
dataHeap.set(new Int32Array(data.buffer));
|
||||
|
||||
let mat = new cv.Mat(8, 1, cv.CV_32SC1, dataPtr, 0);
|
||||
|
||||
assert.equal(mat.intAt(0), 0);
|
||||
assert.equal(mat.intAt(1), -1000);
|
||||
assert.equal(mat.intAt(2), 65000);
|
||||
assert.equal(mat.intAt(3), 255);
|
||||
assert.equal(mat.intAt(4), -2000000);
|
||||
assert.equal(mat.intAt(5), -1);
|
||||
assert.equal(mat.intAt(6), 2);
|
||||
assert.equal(mat.intAt(7), 3);
|
||||
}
|
||||
|
||||
// test floatAt(i)
|
||||
{
|
||||
const EPSILON = 0.001;
|
||||
let data = new Float32Array([0, -10.5, 650.001, 255, -20.1, -1.2, 2, 3.5]);
|
||||
let dataPtr = cv._malloc(32);
|
||||
|
||||
let dataHeap = new Float32Array(cv.HEAPU32.buffer, dataPtr, 8);
|
||||
dataHeap.set(new Float32Array(data.buffer));
|
||||
|
||||
let mat = new cv.Mat(8, 1, cv.CV_32FC1, dataPtr, 0);
|
||||
|
||||
assert.equal(Math.abs(mat.floatAt(0)-0) < EPSILON, true);
|
||||
assert.equal(Math.abs(mat.floatAt(1)+10.5) < EPSILON, true);
|
||||
assert.equal(Math.abs(mat.floatAt(2)-650.001) < EPSILON, true);
|
||||
assert.equal(Math.abs(mat.floatAt(3)-255) < EPSILON, true);
|
||||
assert.equal(Math.abs(mat.floatAt(4)+20.1) < EPSILON, true);
|
||||
assert.equal(Math.abs(mat.floatAt(5)+1.2) < EPSILON, true);
|
||||
assert.equal(Math.abs(mat.floatAt(6)-2) < EPSILON, true);
|
||||
assert.equal(Math.abs(mat.floatAt(7)-3.5) < EPSILON, true);
|
||||
}
|
||||
|
||||
// test intAt(i,j)
|
||||
{
|
||||
let mat = cv.Mat.eye({height: 3, width: 3}, cv.CV_32SC1);
|
||||
|
||||
assert.equal(mat.intAt(0, 0), 1);
|
||||
assert.equal(mat.intAt(0, 1), 0);
|
||||
assert.equal(mat.intAt(0, 2), 0);
|
||||
assert.equal(mat.intAt(1, 0), 0);
|
||||
assert.equal(mat.intAt(1, 1), 1);
|
||||
assert.equal(mat.intAt(1, 2), 0);
|
||||
assert.equal(mat.intAt(2, 0), 0);
|
||||
assert.equal(mat.intAt(2, 1), 0);
|
||||
assert.equal(mat.intAt(2, 2), 1);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_mat_operations', function(assert) {
|
||||
// test minMaxLoc
|
||||
{
|
||||
let src = cv.Mat.ones(4, 4, cv.CV_8UC1);
|
||||
|
||||
src.data[2] = 0;
|
||||
src.data[5] = 2;
|
||||
|
||||
let result = cv.minMaxLoc(src);
|
||||
|
||||
assert.equal(result.minVal, 0);
|
||||
assert.equal(result.maxVal, 2);
|
||||
assert.deepEqual(result.minLoc, {x: 2, y: 0});
|
||||
assert.deepEqual(result.maxLoc, {x: 1, y: 1});
|
||||
|
||||
src.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_mat_roi', function(assert) {
|
||||
// test minMaxLoc
|
||||
{
|
||||
let mat = cv.matFromArray(2, 2, cv.CV_8UC1, [0, 1, 2, 3]);
|
||||
let roi = mat.roi(new cv.Rect(1, 1, 1, 1));
|
||||
|
||||
assert.equal(roi.rows, 1);
|
||||
assert.equal(roi.cols, 1);
|
||||
assert.deepEqual(roi.data, new Uint8Array([mat.ucharAt(1, 1)]));
|
||||
|
||||
mat.delete();
|
||||
roi.delete();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
QUnit.test('test_mat_range', function(assert) {
|
||||
{
|
||||
let src = cv.matFromArray(2, 2, cv.CV_8UC1, [0, 1, 2, 3]);
|
||||
let mat = src.colRange(0, 1);
|
||||
|
||||
assert.equal(mat.isContinuous(), false);
|
||||
assert.equal(mat.rows, 2);
|
||||
assert.equal(mat.cols, 1);
|
||||
assert.equal(mat.ucharAt(0), 0);
|
||||
assert.equal(mat.ucharAt(1), 2);
|
||||
|
||||
mat.delete();
|
||||
|
||||
mat = src.colRange({start: 0, end: 1});
|
||||
|
||||
assert.equal(mat.isContinuous(), false);
|
||||
assert.equal(mat.rows, 2);
|
||||
assert.equal(mat.cols, 1);
|
||||
assert.equal(mat.ucharAt(0), 0);
|
||||
assert.equal(mat.ucharAt(1), 2);
|
||||
|
||||
mat.delete();
|
||||
|
||||
mat = src.rowRange(1, 2);
|
||||
|
||||
assert.equal(mat.rows, 1);
|
||||
assert.equal(mat.cols, 2);
|
||||
assert.deepEqual(mat.data, new Uint8Array([2, 3]));
|
||||
|
||||
mat.delete();
|
||||
|
||||
mat = src.rowRange({start: 1, end: 2});
|
||||
|
||||
assert.equal(mat.rows, 1);
|
||||
assert.equal(mat.cols, 2);
|
||||
assert.deepEqual(mat.data, new Uint8Array([2, 3]));
|
||||
|
||||
mat.delete();
|
||||
|
||||
src.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('test_mat_diag', function(assert) {
|
||||
// test diag
|
||||
{
|
||||
let mat = cv.matFromArray(3, 3, cv.CV_8UC1, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
let d = mat.diag();
|
||||
let d1 = mat.diag(1);
|
||||
let d2 = mat.diag(-1);
|
||||
|
||||
assert.equal(mat.isContinuous(), true);
|
||||
assert.equal(d.isContinuous(), false);
|
||||
assert.equal(d1.isContinuous(), false);
|
||||
assert.equal(d2.isContinuous(), false);
|
||||
|
||||
assert.equal(d.ucharAt(0), 0);
|
||||
assert.equal(d.ucharAt(1), 4);
|
||||
assert.equal(d.ucharAt(2), 8);
|
||||
|
||||
assert.equal(d1.ucharAt(0), 1);
|
||||
assert.equal(d1.ucharAt(1), 5);
|
||||
|
||||
assert.equal(d2.ucharAt(0), 3);
|
||||
assert.equal(d2.ucharAt(1), 7);
|
||||
|
||||
mat.delete();
|
||||
d.delete();
|
||||
d1.delete();
|
||||
d2.delete();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,307 @@
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu
|
||||
//
|
||||
// LICENSE AGREEMENT
|
||||
// Copyright (c) 2015 The Regents of the University of California (Regents)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the University nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
var haarcascade_data = undefined;
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
// The environment is Node.js
|
||||
let fs = require("fs");
|
||||
haarcascade_data = fs.readFileSync("haarcascade_frontalface_default.xml");
|
||||
}
|
||||
|
||||
QUnit.module('Object Detection', {});
|
||||
QUnit.test('Cascade classification', function(assert) {
|
||||
// Group rectangle
|
||||
{
|
||||
let rectList = new cv.RectVector();
|
||||
let weights = new cv.IntVector();
|
||||
let groupThreshold = 1;
|
||||
const eps = 0.2;
|
||||
|
||||
let rect1 = new cv.Rect(1, 2, 3, 4);
|
||||
let rect2 = new cv.Rect(1, 4, 2, 3);
|
||||
|
||||
rectList.push_back(rect1);
|
||||
rectList.push_back(rect2);
|
||||
|
||||
cv.groupRectangles(rectList, weights, groupThreshold, eps);
|
||||
|
||||
|
||||
rectList.delete();
|
||||
weights.delete();
|
||||
}
|
||||
|
||||
// CascadeClassifier
|
||||
{
|
||||
if (haarcascade_data) {
|
||||
cv.FS_createDataFile("/", "haarcascade_frontalface_default.xml", haarcascade_data, true, false, false);
|
||||
}
|
||||
|
||||
let classifier = new cv.CascadeClassifier();
|
||||
const modelPath = '/haarcascade_frontalface_default.xml';
|
||||
|
||||
assert.equal(classifier.empty(), true);
|
||||
|
||||
|
||||
classifier.load(modelPath);
|
||||
assert.equal(classifier.empty(), false);
|
||||
|
||||
let image = cv.Mat.eye({height: 10, width: 10}, cv.CV_8UC3);
|
||||
let objects = new cv.RectVector();
|
||||
let numDetections = new cv.IntVector();
|
||||
const scaleFactor = 1.1;
|
||||
const minNeighbors = 3;
|
||||
const flags = 0;
|
||||
const minSize = {height: 0, width: 0};
|
||||
const maxSize = {height: 10, width: 10};
|
||||
|
||||
classifier.detectMultiScale2(image, objects, numDetections, scaleFactor,
|
||||
minNeighbors, flags, minSize, maxSize);
|
||||
|
||||
// test default parameters
|
||||
classifier.detectMultiScale2(image, objects, numDetections, scaleFactor,
|
||||
minNeighbors, flags, minSize);
|
||||
classifier.detectMultiScale2(image, objects, numDetections, scaleFactor,
|
||||
minNeighbors, flags);
|
||||
classifier.detectMultiScale2(image, objects, numDetections, scaleFactor,
|
||||
minNeighbors);
|
||||
classifier.detectMultiScale2(image, objects, numDetections, scaleFactor);
|
||||
|
||||
classifier.delete();
|
||||
objects.delete();
|
||||
numDetections.delete();
|
||||
}
|
||||
|
||||
// HOGDescriptor
|
||||
{
|
||||
let hog = new cv.HOGDescriptor();
|
||||
let mat = new cv.Mat({height: 10, width: 10}, cv.CV_8UC1);
|
||||
let descriptors = new cv.FloatVector();
|
||||
let locations = new cv.PointVector();
|
||||
|
||||
|
||||
assert.equal(hog.winSize.height, 128);
|
||||
assert.equal(hog.winSize.width, 64);
|
||||
assert.equal(hog.nbins, 9);
|
||||
assert.equal(hog.derivAperture, 1);
|
||||
assert.equal(hog.winSigma, -1);
|
||||
assert.equal(hog.histogramNormType, 0);
|
||||
assert.equal(hog.nlevels, 64);
|
||||
|
||||
hog.nlevels = 32;
|
||||
assert.equal(hog.nlevels, 32);
|
||||
|
||||
hog.delete();
|
||||
mat.delete();
|
||||
descriptors.delete();
|
||||
locations.delete();
|
||||
}
|
||||
});
|
||||
QUnit.test('QR code detect and decode', function (assert) {
|
||||
{
|
||||
const detector = new cv.QRCodeDetector();
|
||||
let mat = cv.Mat.ones(800, 600, cv.CV_8U);
|
||||
assert.ok(mat);
|
||||
|
||||
// test detect
|
||||
let points = new cv.Mat();
|
||||
let qrCodeFound = detector.detect(mat, points);
|
||||
assert.equal(points.rows, 0)
|
||||
assert.equal(points.cols, 0)
|
||||
assert.equal(qrCodeFound, false);
|
||||
|
||||
// test detectMult
|
||||
qrCodeFound = detector.detectMulti(mat, points);
|
||||
assert.equal(points.rows, 0)
|
||||
assert.equal(points.cols, 0)
|
||||
assert.equal(qrCodeFound, false);
|
||||
|
||||
// test decode (with random numbers)
|
||||
let decodeTestPoints = cv.matFromArray(1, 4, cv.CV_32FC2, [10, 20, 30, 40, 60, 80, 90, 100]);
|
||||
let qrCodeContent = detector.decode(mat, decodeTestPoints);
|
||||
assert.equal(typeof qrCodeContent, 'string');
|
||||
assert.equal(qrCodeContent, '');
|
||||
|
||||
//test detectAndDecode
|
||||
qrCodeContent = detector.detectAndDecode(mat);
|
||||
assert.equal(typeof qrCodeContent, 'string');
|
||||
assert.equal(qrCodeContent, '');
|
||||
|
||||
// test decodeCurved
|
||||
qrCodeContent = detector.decodeCurved(mat, decodeTestPoints);
|
||||
assert.equal(typeof qrCodeContent, 'string');
|
||||
assert.equal(qrCodeContent, '');
|
||||
|
||||
decodeTestPoints.delete();
|
||||
points.delete();
|
||||
mat.delete();
|
||||
|
||||
}
|
||||
});
|
||||
QUnit.test('Aruco-based QR code detect', function (assert) {
|
||||
{
|
||||
let qrcode_params = new cv.QRCodeDetectorAruco_Params();
|
||||
let detector = new cv.QRCodeDetectorAruco();
|
||||
let mat = cv.Mat.ones(800, 600, cv.CV_8U);
|
||||
assert.ok(mat);
|
||||
|
||||
detector.setDetectorParameters(qrcode_params);
|
||||
|
||||
let points = new cv.Mat();
|
||||
let qrCodeFound = detector.detect(mat, points);
|
||||
assert.equal(points.rows, 0)
|
||||
assert.equal(points.cols, 0)
|
||||
assert.equal(qrCodeFound, false);
|
||||
|
||||
qrcode_params.delete();
|
||||
detector.delete();
|
||||
points.delete();
|
||||
mat.delete();
|
||||
}
|
||||
});
|
||||
QUnit.test('Bar code detect', function (assert) {
|
||||
{
|
||||
let detector = new cv.barcode_BarcodeDetector();
|
||||
let mat = cv.Mat.ones(800, 600, cv.CV_8U);
|
||||
assert.ok(mat);
|
||||
|
||||
let points = new cv.Mat();
|
||||
let codeFound = detector.detect(mat, points);
|
||||
assert.equal(points.rows, 0)
|
||||
assert.equal(points.cols, 0)
|
||||
assert.equal(codeFound, false);
|
||||
|
||||
codeContent = detector.detectAndDecode(mat);
|
||||
assert.equal(typeof codeContent, 'string');
|
||||
assert.equal(codeContent, '');
|
||||
|
||||
detector.delete();
|
||||
points.delete();
|
||||
mat.delete();
|
||||
}
|
||||
});
|
||||
QUnit.test('Aruco detector', function (assert) {
|
||||
{
|
||||
let dictionary = cv.getPredefinedDictionary(cv.DICT_4X4_50);
|
||||
let aruco_image = new cv.Mat();
|
||||
let detectorParameters = new cv.aruco_DetectorParameters();
|
||||
let refineParameters = new cv.aruco_RefineParameters(10, 3, true);
|
||||
let detector = new cv.aruco_ArucoDetector(dictionary, detectorParameters,refineParameters);
|
||||
let corners = new cv.MatVector();
|
||||
let ids = new cv.Mat();
|
||||
|
||||
dictionary.generateImageMarker(10, 128, aruco_image);
|
||||
assert.ok(!aruco_image.empty());
|
||||
|
||||
detector.detectMarkers(aruco_image, corners, ids);
|
||||
|
||||
dictionary.delete();
|
||||
aruco_image.delete();
|
||||
detectorParameters.delete();
|
||||
refineParameters.delete();
|
||||
detector.delete();
|
||||
corners.delete();
|
||||
ids.delete();
|
||||
}
|
||||
});
|
||||
QUnit.test('Charuco detector', function (assert) {
|
||||
{
|
||||
let dictionary = new cv.getPredefinedDictionary(cv.DICT_4X4_50);
|
||||
let boardIds = new cv.Mat();
|
||||
let board = new cv.aruco_CharucoBoard(new cv.Size(3, 5), 64, 32, dictionary, boardIds);
|
||||
let charucoParameters = new cv.aruco_CharucoParameters();
|
||||
let detectorParameters = new cv.aruco_DetectorParameters();
|
||||
let refineParameters = new cv.aruco_RefineParameters(10, 3, true);
|
||||
let detector = new cv.aruco_CharucoDetector(board, charucoParameters, detectorParameters, refineParameters);
|
||||
let board_image = new cv.Mat();
|
||||
let corners = new cv.Mat();
|
||||
let ids = new cv.Mat();
|
||||
|
||||
board.generateImage(new cv.Size(300, 500), board_image);
|
||||
assert.ok(!board_image.empty());
|
||||
|
||||
let chess_corners = board.getChessboardCorners();
|
||||
|
||||
detector.detectBoard(board_image, corners, ids);
|
||||
assert.ok(!corners.empty());
|
||||
assert.ok(!ids.empty());
|
||||
|
||||
dictionary.delete();
|
||||
boardIds.delete();
|
||||
board.delete();
|
||||
board_image.delete();
|
||||
charucoParameters.delete();
|
||||
detectorParameters.delete();
|
||||
refineParameters.delete();
|
||||
detector.delete();
|
||||
corners.delete();
|
||||
ids.delete();
|
||||
chess_corners.delete();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,110 @@
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
|
||||
// Author : Rijubrata Bhaumik, Intel Corporation. rijubrata.bhaumik[at]intel[dot]com
|
||||
|
||||
QUnit.module('Photo', {});
|
||||
|
||||
QUnit.test('test_photo', function(assert) {
|
||||
// CalibrateDebevec
|
||||
{
|
||||
let calibration = new cv.CalibrateDebevec();
|
||||
assert.ok(true, calibration);
|
||||
//let response = calibration.process(images, exposures);
|
||||
}
|
||||
// CalibrateRobertson
|
||||
{
|
||||
let calibration = new cv.CalibrateRobertson();
|
||||
assert.ok(true, calibration);
|
||||
//let response = calibration.process(images, exposures);
|
||||
}
|
||||
|
||||
// MergeDebevec
|
||||
{
|
||||
let merge = new cv.MergeDebevec();
|
||||
assert.ok(true, merge);
|
||||
//let hdr = merge.process(images, exposures, response);
|
||||
}
|
||||
// MergeMertens
|
||||
{
|
||||
let merge = new cv.MergeMertens();
|
||||
assert.ok(true, merge);
|
||||
//let hdr = merge.process(images, exposures, response);
|
||||
}
|
||||
// MergeRobertson
|
||||
{
|
||||
let merge = new cv.MergeRobertson();
|
||||
assert.ok(true, merge);
|
||||
//let hdr = merge.process(images, exposures, response);
|
||||
}
|
||||
|
||||
// TonemapDrago
|
||||
{
|
||||
let tonemap = new cv.TonemapDrago();
|
||||
assert.ok(true, tonemap);
|
||||
// let ldr = new cv.Mat();
|
||||
// let retval = tonemap.process(hdr, ldr);
|
||||
}
|
||||
// TonemapMantiuk
|
||||
{
|
||||
let tonemap = new cv.TonemapMantiuk();
|
||||
assert.ok(true, tonemap);
|
||||
// let ldr = new cv.Mat();
|
||||
// let retval = tonemap.process(hdr, ldr);
|
||||
}
|
||||
// TonemapReinhard
|
||||
{
|
||||
let tonemap = new cv.TonemapReinhard();
|
||||
assert.ok(true, tonemap);
|
||||
// let ldr = new cv.Mat();
|
||||
// let retval = tonemap.process(hdr, ldr);
|
||||
}
|
||||
// Inpaint
|
||||
{
|
||||
let src = new cv.Mat(100, 100, cv.CV_8UC3, new cv.Scalar(127, 127, 127, 255));
|
||||
let mask = new cv.Mat(100, 100, cv.CV_8UC1, new cv.Scalar(0, 0, 0, 0));
|
||||
let dst = new cv.Mat();
|
||||
cv.line(mask, new cv.Point(10, 50), new cv.Point(90, 50), new cv.Scalar(255, 255, 255, 255),5);
|
||||
cv.inpaint(src, mask, dst, 3, cv.INPAINT_TELEA);
|
||||
assert.equal(dst.rows, 100);
|
||||
assert.equal(dst.cols, 100);
|
||||
assert.equal(dst.channels(), 3);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,252 @@
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu
|
||||
//
|
||||
// LICENSE AGREEMENT
|
||||
// Copyright (c) 2015 The Regents of the University of California (Regents)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the University nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
QUnit.module('Utils', {});
|
||||
QUnit.test('Test vectors', function(assert) {
|
||||
{
|
||||
let pointVector = new cv.PointVector();
|
||||
for (let i=0; i<100; ++i) {
|
||||
pointVector.push_back({x: i, y: 2*i});
|
||||
}
|
||||
|
||||
assert.equal(pointVector.size(), 100);
|
||||
|
||||
let index = 10;
|
||||
let item = pointVector.get(index);
|
||||
assert.equal(item.x, index);
|
||||
assert.equal(item.y, 2*index);
|
||||
|
||||
index = 0;
|
||||
item = pointVector.get(index);
|
||||
assert.equal(item.x, index);
|
||||
assert.equal(item.y, 2*index);
|
||||
|
||||
index = 99;
|
||||
item = pointVector.get(index);
|
||||
assert.equal(item.x, index);
|
||||
assert.equal(item.y, 2*index);
|
||||
|
||||
pointVector.delete();
|
||||
}
|
||||
|
||||
{
|
||||
let pointVector = new cv.PointVector();
|
||||
for (let i=0; i<100; ++i) {
|
||||
pointVector.push_back(new cv.Point(i, 2*i));
|
||||
}
|
||||
|
||||
pointVector.push_back(new cv.Point());
|
||||
|
||||
assert.equal(pointVector.size(), 101);
|
||||
|
||||
let index = 10;
|
||||
let item = pointVector.get(index);
|
||||
assert.equal(item.x, index);
|
||||
assert.equal(item.y, 2*index);
|
||||
|
||||
index = 0;
|
||||
item = pointVector.get(index);
|
||||
assert.equal(item.x, index);
|
||||
assert.equal(item.y, 2*index);
|
||||
|
||||
index = 99;
|
||||
item = pointVector.get(index);
|
||||
assert.equal(item.x, index);
|
||||
assert.equal(item.y, 2*index);
|
||||
|
||||
index = 100;
|
||||
item = pointVector.get(index);
|
||||
assert.equal(item.x, 0);
|
||||
assert.equal(item.y, 0);
|
||||
|
||||
pointVector.delete();
|
||||
}
|
||||
});
|
||||
QUnit.test('Test Rect', function(assert) {
|
||||
let rectVector = new cv.RectVector();
|
||||
let rect = {x: 1, y: 2, width: 3, height: 4};
|
||||
rectVector.push_back(rect);
|
||||
rectVector.push_back(new cv.Rect());
|
||||
rectVector.push_back(new cv.Rect(rect));
|
||||
rectVector.push_back(new cv.Rect({x: 5, y: 6}, {width: 7, height: 8}));
|
||||
rectVector.push_back(new cv.Rect(9, 10, 11, 12));
|
||||
|
||||
assert.equal(rectVector.size(), 5);
|
||||
|
||||
let item = rectVector.get(0);
|
||||
assert.equal(item.x, 1);
|
||||
assert.equal(item.y, 2);
|
||||
assert.equal(item.width, 3);
|
||||
assert.equal(item.height, 4);
|
||||
|
||||
item = rectVector.get(1);
|
||||
assert.equal(item.x, 0);
|
||||
assert.equal(item.y, 0);
|
||||
assert.equal(item.width, 0);
|
||||
assert.equal(item.height, 0);
|
||||
|
||||
item = rectVector.get(2);
|
||||
assert.equal(item.x, 1);
|
||||
assert.equal(item.y, 2);
|
||||
assert.equal(item.width, 3);
|
||||
assert.equal(item.height, 4);
|
||||
|
||||
item = rectVector.get(3);
|
||||
assert.equal(item.x, 5);
|
||||
assert.equal(item.y, 6);
|
||||
assert.equal(item.width, 7);
|
||||
assert.equal(item.height, 8);
|
||||
|
||||
item = rectVector.get(4);
|
||||
assert.equal(item.x, 9);
|
||||
assert.equal(item.y, 10);
|
||||
assert.equal(item.width, 11);
|
||||
assert.equal(item.height, 12);
|
||||
|
||||
rectVector.delete();
|
||||
});
|
||||
QUnit.test('Test Size', function(assert) {
|
||||
{
|
||||
let mat = new cv.Mat();
|
||||
mat.create({width: 5, height: 10}, cv.CV_8UC4);
|
||||
let size = mat.size();
|
||||
|
||||
assert.ok(mat.type() === cv.CV_8UC4);
|
||||
assert.ok(size.height === 10);
|
||||
assert.ok(size.width === 5);
|
||||
assert.ok(mat.channels() === 4);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
|
||||
{
|
||||
let mat = new cv.Mat();
|
||||
mat.create(new cv.Size(5, 10), cv.CV_8UC4);
|
||||
let size = mat.size();
|
||||
|
||||
assert.ok(mat.type() === cv.CV_8UC4);
|
||||
assert.ok(size.height === 10);
|
||||
assert.ok(size.width === 5);
|
||||
assert.ok(mat.channels() === 4);
|
||||
|
||||
mat.delete();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
QUnit.test('test_rotated_rect', function(assert) {
|
||||
{
|
||||
let rect = {center: {x: 100, y: 100}, size: {height: 100, width: 50}, angle: 30};
|
||||
|
||||
assert.equal(rect.center.x, 100);
|
||||
assert.equal(rect.center.y, 100);
|
||||
assert.equal(rect.angle, 30);
|
||||
assert.equal(rect.size.height, 100);
|
||||
assert.equal(rect.size.width, 50);
|
||||
}
|
||||
|
||||
{
|
||||
let rect = new cv.RotatedRect();
|
||||
|
||||
assert.equal(rect.center.x, 0);
|
||||
assert.equal(rect.center.y, 0);
|
||||
assert.equal(rect.angle, 0);
|
||||
assert.equal(rect.size.height, 0);
|
||||
assert.equal(rect.size.width, 0);
|
||||
|
||||
let points = cv.RotatedRect.points(rect);
|
||||
|
||||
assert.equal(points[0].x, 0);
|
||||
assert.equal(points[0].y, 0);
|
||||
assert.equal(points[1].x, 0);
|
||||
assert.equal(points[1].y, 0);
|
||||
assert.equal(points[2].x, 0);
|
||||
assert.equal(points[2].y, 0);
|
||||
assert.equal(points[3].x, 0);
|
||||
assert.equal(points[3].y, 0);
|
||||
}
|
||||
|
||||
{
|
||||
let rect = new cv.RotatedRect({x: 100, y: 100}, {height: 100, width: 50}, 30);
|
||||
|
||||
assert.equal(rect.center.x, 100);
|
||||
assert.equal(rect.center.y, 100);
|
||||
assert.equal(rect.angle, 30);
|
||||
assert.equal(rect.size.height, 100);
|
||||
assert.equal(rect.size.width, 50);
|
||||
|
||||
let points = cv.RotatedRect.points(rect);
|
||||
|
||||
assert.equal(points[0].x, cv.RotatedRect.boundingRect2f(rect).x);
|
||||
assert.equal(points[1].y, cv.RotatedRect.boundingRect2f(rect).y);
|
||||
|
||||
let points1 = cv.boxPoints(rect);
|
||||
assert.deepEqual(points, points1);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,127 @@
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Sajjad Taheri, University of California, Irvine. sajjadt[at]uci[dot]edu
|
||||
//
|
||||
// LICENSE AGREEMENT
|
||||
// Copyright (c) 2015 The Regents of the University of California (Regents)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
// 1. Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the University nor the
|
||||
// names of its contributors may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
QUnit.module('Video', {});
|
||||
QUnit.test('Background Segmentation', function(assert) {
|
||||
// BackgroundSubtractorMOG2
|
||||
{
|
||||
const history = 600;
|
||||
const varThreshold = 15;
|
||||
const detectShadows = true;
|
||||
|
||||
let mog2 = new cv.BackgroundSubtractorMOG2(history, varThreshold, detectShadows);
|
||||
|
||||
assert.equal(mog2 instanceof cv.BackgroundSubtractorMOG2, true);
|
||||
|
||||
mog2.delete();
|
||||
|
||||
mog2 = new cv.BackgroundSubtractorMOG2();
|
||||
|
||||
assert.equal(mog2 instanceof cv.BackgroundSubtractorMOG2, true);
|
||||
|
||||
mog2.delete();
|
||||
|
||||
mog2 = new cv.BackgroundSubtractorMOG2(history);
|
||||
|
||||
assert.equal(mog2 instanceof cv.BackgroundSubtractorMOG2, true);
|
||||
|
||||
mog2.delete();
|
||||
|
||||
mog2 = new cv.BackgroundSubtractorMOG2(history, varThreshold);
|
||||
|
||||
assert.equal(mog2 instanceof cv.BackgroundSubtractorMOG2, true);
|
||||
|
||||
mog2.delete();
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('TrackerMIL', function(assert) {
|
||||
{
|
||||
let src1 = cv.Mat.zeros(100, 100, cv.CV_8UC1);
|
||||
let src2 = cv.Mat.zeros(100, 100, cv.CV_8UC1);
|
||||
|
||||
let tracker = new cv.TrackerMIL();
|
||||
|
||||
assert.equal(tracker instanceof cv.TrackerMIL, true);
|
||||
assert.equal(tracker instanceof cv.Tracker, true);
|
||||
|
||||
let rect = new cv.Rect(10, 10, 50, 60);
|
||||
tracker.init(src1, rect);
|
||||
|
||||
let [updated, rect2] = tracker.update(src2);
|
||||
|
||||
assert.equal(updated, true);
|
||||
assert.equal(rect2.width, 50);
|
||||
assert.equal(rect2.height, 60);
|
||||
|
||||
tracker.delete();
|
||||
src1.delete();
|
||||
src2.delete();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>OpenCV JS Tests</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
||||
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.20.0.css" type="text/css" media="screen">
|
||||
<style>
|
||||
body {
|
||||
font-family: Monospace;
|
||||
background-color: #ffffff;
|
||||
margin: 0px;
|
||||
}
|
||||
a {
|
||||
color: #0040ff;
|
||||
}
|
||||
</style>
|
||||
<script src="http://code.jquery.com/qunit/qunit-2.0.1.js"></script>
|
||||
<script type="text/javascript">
|
||||
QUnit.config.autostart = false;
|
||||
|
||||
QUnit.log(function(details) {
|
||||
if (details.result) {
|
||||
return;
|
||||
}
|
||||
var loc = details.module + ": " + details.name + ": ",
|
||||
output = "FAILED: " + loc + ( details.message ? details.message : "" )
|
||||
prefix = details.message ? ", " : "";
|
||||
|
||||
if (details.actual) {
|
||||
output += prefix + "expected: " + details.expected + ", actual: " + details.actual;
|
||||
prefix = ', ';
|
||||
}
|
||||
if (details.source) {
|
||||
output += prefix + details.source;
|
||||
}
|
||||
console.warn(output);
|
||||
});
|
||||
QUnit.done(function(details) {
|
||||
console.log("Total: " + details.total + " Failed: " + details.failed + " Passed: " + details.passed);
|
||||
console.log("Time(ms): " + details.runtime);
|
||||
});
|
||||
|
||||
// Helper for opencv.js (see below)
|
||||
var Module = {
|
||||
preRun: [function() {
|
||||
Module.FS_createPreloadedFile('/', 'haarcascade_frontalface_default.xml', 'haarcascade_frontalface_default.xml', true, false);
|
||||
}],
|
||||
postRun: [] ,
|
||||
onRuntimeInitialized: function() {
|
||||
console.log("Emscripten runtime is ready, launching QUnit tests...");
|
||||
if (window.cv instanceof Promise) {
|
||||
window.cv.then((target) => {
|
||||
window.cv = target;
|
||||
console.log(cv.getBuildInformation());
|
||||
QUnit.start();
|
||||
})
|
||||
} else {
|
||||
// for backward compatible
|
||||
console.log(cv.getBuildInformation());
|
||||
QUnit.start();
|
||||
}
|
||||
},
|
||||
print: (function() {
|
||||
var element = document.getElementById('output');
|
||||
if (element) element.value = ''; // clear browser cache
|
||||
return function(text) {
|
||||
console.log(text);
|
||||
if (element) {
|
||||
element.value += text + "\n";
|
||||
element.scrollTop = element.scrollHeight; // focus on bottom
|
||||
}
|
||||
};
|
||||
})(),
|
||||
printErr: function(text) {
|
||||
console.error(text);
|
||||
},
|
||||
setStatus: function(text) {
|
||||
console.log(text);
|
||||
},
|
||||
totalDependencies: 0
|
||||
};
|
||||
|
||||
Module.setStatus('Downloading...');
|
||||
window.onerror = function(event) {
|
||||
Module.setStatus('Exception thrown, see JavaScript console');
|
||||
Module.setStatus = function(text) {
|
||||
if (text) Module.printErr('[post-exception status] ' + text);
|
||||
};
|
||||
};
|
||||
|
||||
function opencvjs_LoadError() {
|
||||
Module.printErr('Failed to load/initialize opencv.js');
|
||||
QUnit.module('LoaderFatalError', {});
|
||||
QUnit.config.module = 'LoaderFatalError';
|
||||
QUnit.only("Failed to load OpenCV.js", function(assert) {
|
||||
assert.ok(false, "Can't load/initialize opencv.js");
|
||||
});
|
||||
QUnit.start();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="qunit"></div>
|
||||
<div id="qunit-fixture"></div>
|
||||
|
||||
<script type="application/javascript" async src="opencv.js" onerror="opencvjs_LoadError()"></script>
|
||||
<script type="application/javascript" src="test_mat.js"></script>
|
||||
<script type="application/javascript" src="test_utils.js"></script>
|
||||
<script type="application/javascript" src="test_core.js"></script>
|
||||
<script type="application/javascript" src="test_imgproc.js"></script>
|
||||
<script type="application/javascript" src="test_objdetect.js"></script>
|
||||
<script type="application/javascript" src="test_video.js"></script>
|
||||
<script type="application/javascript" src="test_photo.js"></script>
|
||||
<script type="application/javascript" src="test_features2d.js"></script>
|
||||
<script type="application/javascript" src="test_calib3d.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,70 @@
|
||||
// //////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
|
||||
let testrunner = require('node-qunit');
|
||||
testrunner.options.maxBlockDuration = 20000; // cause opencv_js.js need time to load
|
||||
|
||||
testrunner.run(
|
||||
{
|
||||
code: {path: "opencv.js", namespace: "cv"},
|
||||
tests: ['init_cv.js',
|
||||
'test_mat.js',
|
||||
'test_utils.js',
|
||||
'test_core.js',
|
||||
'test_imgproc.js',
|
||||
'test_objdetect.js',
|
||||
'test_video.js',
|
||||
'test_features2d.js',
|
||||
'test_photo.js',
|
||||
'test_calib3d.js',
|
||||
],
|
||||
},
|
||||
function(err, report) {
|
||||
console.log(report.failed + ' failed, ' + report.passed + ' passed');
|
||||
if (report.failed || err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
process.on('exit', function() {
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user