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

Merge pull request #15371 from Wenzhao-Xiang:gsoc_2019

[GSoC 2019] Improve the performance of JavaScript version of OpenCV (OpenCV.js)

* [GSoC 2019]

Improve the performance of JavaScript version of OpenCV (OpenCV.js):
1. Create the base of OpenCV.js performance test:
     This perf test is based on benchmark.js(https://benchmarkjs.com). And first add `cvtColor`, `Resize`, `Threshold` into it.
2. Optimize the OpenCV.js performance by WASM threads:
     This optimization is based on Web Worker API and SharedArrayBuffer, so it can be only used in browser.
3. Optimize the OpenCV.js performance by WASM SIMD:
     Add WASM SIMD backend for OpenCV Universal Intrinsics. It's experimental as WASM SIMD is still in development.

* [GSoC2019] 

1. use short license header
2. fix documentation node issue
3. remove the unused `hasSIMD128()` api

* [GSoC2019]

1. fix emscripten define
2. use fallback function for f16

* [GSoC2019]

Fix rebase issue
This commit is contained in:
Wenzhao Xiang
2019-09-24 21:30:42 +08:00
committed by Alexander Alekhin
parent 3cf9185159
commit c2096771cb
20 changed files with 5693 additions and 16 deletions
@@ -157,6 +157,11 @@
# define CV_MSA 1
#endif
#ifdef __EMSCRIPTEN__
# define CV_WASM_SIMD 1
# include <wasm_simd128.h>
#endif
#endif // CV_ENABLE_INTRINSICS && !CV_DISABLE_OPTIMIZATION && !__CUDACC__
#if defined CV_CPU_COMPILE_AVX && !defined CV_CPU_BASELINE_COMPILE_AVX
@@ -328,3 +333,7 @@ struct VZeroUpperGuard {
#ifndef CV_MSA
# define CV_MSA 0
#endif
#ifndef CV_WASM_SIMD
# define CV_WASM_SIMD 0
#endif
@@ -168,7 +168,7 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
# undef CV_MSA
#endif
#if CV_SSE2 || CV_NEON || CV_VSX || CV_MSA
#if CV_SSE2 || CV_NEON || CV_VSX || CV_MSA || CV_WASM_SIMD
#define CV__SIMD_FORWARD 128
#include "opencv2/core/hal/intrin_forward.hpp"
#endif
@@ -190,6 +190,9 @@ using namespace CV_CPU_OPTIMIZATION_HAL_NAMESPACE;
#include "opencv2/core/hal/intrin_msa.hpp"
#elif CV_WASM_SIMD
#include "opencv2/core/hal/intrin_wasm.hpp"
#else
#define CV_SIMD128_CPP 1
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -31,6 +31,11 @@ using namespace cv;
namespace {
static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI);
static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI);
static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI);
static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI);
#ifdef __EMSCRIPTEN__
static inline float atan_f32(float y, float x)
{
@@ -42,11 +47,6 @@ static inline float atan_f32(float y, float x)
return a; // range [0; 360)
}
#else
static const float atan2_p1 = 0.9997878412794807f*(float)(180/CV_PI);
static const float atan2_p3 = -0.3258083974640975f*(float)(180/CV_PI);
static const float atan2_p5 = 0.1555786518463281f*(float)(180/CV_PI);
static const float atan2_p7 = -0.04432655554792128f*(float)(180/CV_PI);
static inline float atan_f32(float y, float x)
{
float ax = std::abs(x), ay = std::abs(y);
+2 -2
View File
@@ -54,7 +54,7 @@
#endif
#if defined __linux__ || defined __APPLE__ || defined __GLIBC__ \
|| defined __HAIKU__
|| defined __HAIKU__ || defined __EMSCRIPTEN__
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
@@ -793,7 +793,7 @@ int cv::getNumberOfCPUs(void)
#elif defined __ANDROID__
static int ncpus = getNumberOfCPUsImpl();
return ncpus;
#elif defined __linux__ || defined __GLIBC__ || defined __HAIKU__
#elif defined __linux__ || defined __GLIBC__ || defined __HAIKU__ || defined __EMSCRIPTEN__
return (int)sysconf( _SC_NPROCESSORS_ONLN );
#elif defined __APPLE__
int numCPU=0;
+35 -2
View File
@@ -82,11 +82,21 @@ add_definitions("-std=c++11")
link_libraries(${OPENCV_MODULE_${the_module}_DEPS})
ocv_add_executable(${the_module} ${bindings_cpp})
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()
set_target_properties(${the_module} PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} --memory-init-file 0 -s TOTAL_MEMORY=134217728 -s ALLOW_MEMORY_GROWTH=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} --memory-init-file 0 -s TOTAL_MEMORY=128MB -s WASM_MEM_MAX=1GB -s ALLOW_MEMORY_GROWTH=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s MODULARIZE=1 -s SINGLE_FILE=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s EXPORT_NAME=\"'cv'\" -s DEMANGLE_SUPPORT=1")
set(EMSCRIPTEN_LINK_FLAGS "${EMSCRIPTEN_LINK_FLAGS} -s FORCE_FILESYSTEM=1 --use-preload-plugins --bind --post-js ${JS_HELPER} -Wno-missing-prototypes")
@@ -142,3 +152,26 @@ list(APPEND opencv_test_js_file_deps "${test_data_path}" "${opencv_test_js_bin_d
add_custom_target(${PROJECT_NAME}_test ALL
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 ALL
DEPENDS ${OCV_JS_PATH} ${opencv_perf_js_file_deps})
+35
View File
@@ -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 paramater, and then click the `Run` button to run the specific case, or it will run all the cases.
+18
View File
@@ -0,0 +1,18 @@
if (typeof window === 'undefined') {
var cv = require("../opencv");
}
const cvSize = {
szODD: new cv.Size(127, 61),
szQVGA: new cv.Size(320, 240),
szVGA: new cv.Size(640, 480),
szqHD: new cv.Size(960, 540),
sz720p: new cv.Size(1280, 720),
sz1080p: new cv.Size(1920, 1080),
sz130x60: new cv.Size(130, 60),
sz213x120: new cv.Size(120 * 1280 / 720, 120),
}
if (typeof window === 'undefined') {
exports.cvSize = cvSize;
}
+19
View File
@@ -0,0 +1,19 @@
{
"name": "opencv_js_perf",
"description": "Perfermance 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": "BSD-3-Clause",
"bugs": {
"url": "https://github.com/opencv/opencv/issues"
},
"homepage": "https://github.com/opencv/opencv"
}
+59
View File
@@ -0,0 +1,59 @@
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 cvtStr2cvSize = function(strSize) {
let size;
switch(strSize) {
case "127,61": size = cvSize.szODD;break;
case '320,240': size = cvSize.szQVGA;break;
case '640,480': size = cvSize.szVGA;break;
case '960,540': size = cvSize.szqHD;break;
case '1280,720': size = cvSize.sz720p;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;
}
if (typeof window === 'undefined') {
exports.fillGradient = fillGradient;
exports.cvtStr2cvSize = cvtStr2cvSize;
exports.combine = combine;
}
@@ -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,572 @@
const 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');
}
cv.onRuntimeInitialized = () => {
console.log('opencv.js loaded');
if (isNodeJs) {
global.cv = cv;
global.combine = HelpFunc.combine;
global.cvtStr2cvSize = HelpFunc.cvtStr2cvSize;
global.cvSize = Base.cvSize;
} else {
runButton.removeAttribute('disabled');
runButton.setAttribute('class', 'btn btn-primary');
runButton.innerHTML = 'Run';
}
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
};
const CvtMode = [
"COLOR_BGR2BGR555", "COLOR_BGR2BGR565", "COLOR_BGR2BGRA", "COLOR_BGR2GRAY",
"COLOR_BGR2HLS", "COLOR_BGR2HLS_FULL", "COLOR_BGR2HSV", "COLOR_BGR2HSV_FULL",
"COLOR_BGR2Lab", "COLOR_BGR2Luv", "COLOR_BGR2RGB", "COLOR_BGR2RGBA", "COLOR_BGR2XYZ",
"COLOR_BGR2YCrCb", "COLOR_BGR2YUV", "COLOR_BGR5552BGR", "COLOR_BGR5552BGRA",
"COLOR_BGR5552GRAY", "COLOR_BGR5552RGB", "COLOR_BGR5552RGBA", "COLOR_BGR5652BGR",
"COLOR_BGR5652BGRA", "COLOR_BGR5652GRAY", "COLOR_BGR5652RGB", "COLOR_BGR5652RGBA",
"COLOR_BGRA2BGR", "COLOR_BGRA2BGR555", "COLOR_BGRA2BGR565", "COLOR_BGRA2GRAY", "COLOR_BGRA2RGBA",
"CX_BGRA2HLS", "CX_BGRA2HLS_FULL", "CX_BGRA2HSV", "CX_BGRA2HSV_FULL",
"CX_BGRA2Lab", "CX_BGRA2Luv", "CX_BGRA2XYZ",
"CX_BGRA2YCrCb", "CX_BGRA2YUV",
"COLOR_GRAY2BGR", "COLOR_GRAY2BGR555", "COLOR_GRAY2BGR565", "COLOR_GRAY2BGRA",
"COLOR_HLS2BGR", "COLOR_HLS2BGR_FULL", "COLOR_HLS2RGB", "COLOR_HLS2RGB_FULL",
"CX_HLS2BGRA", "CX_HLS2BGRA_FULL", "CX_HLS2RGBA", "CX_HLS2RGBA_FULL",
"COLOR_HSV2BGR", "COLOR_HSV2BGR_FULL", "COLOR_HSV2RGB", "COLOR_HSV2RGB_FULL",
"CX_HSV2BGRA", "CX_HSV2BGRA_FULL", "CX_HSV2RGBA", "CX_HSV2RGBA_FULL",
"COLOR_Lab2BGR", "COLOR_Lab2LBGR", "COLOR_Lab2LRGB", "COLOR_Lab2RGB",
"CX_Lab2BGRA", "CX_Lab2LBGRA", "CX_Lab2LRGBA", "CX_Lab2RGBA",
"COLOR_LBGR2Lab", "COLOR_LBGR2Luv", "COLOR_LRGB2Lab", "COLOR_LRGB2Luv",
"CX_LBGRA2Lab", "CX_LBGRA2Luv", "CX_LRGBA2Lab", "CX_LRGBA2Luv",
"COLOR_Luv2BGR", "COLOR_Luv2LBGR", "COLOR_Luv2LRGB", "COLOR_Luv2RGB",
"CX_Luv2BGRA", "CX_Luv2LBGRA", "CX_Luv2LRGBA", "CX_Luv2RGBA",
"COLOR_RGB2BGR555", "COLOR_RGB2BGR565", "COLOR_RGB2GRAY",
"COLOR_RGB2HLS", "COLOR_RGB2HLS_FULL", "COLOR_RGB2HSV", "COLOR_RGB2HSV_FULL",
"COLOR_RGB2Lab", "COLOR_RGB2Luv", "COLOR_RGB2XYZ", "COLOR_RGB2YCrCb", "COLOR_RGB2YUV",
"COLOR_RGBA2BGR", "COLOR_RGBA2BGR555", "COLOR_RGBA2BGR565", "COLOR_RGBA2GRAY",
"CX_RGBA2HLS", "CX_RGBA2HLS_FULL", "CX_RGBA2HSV", "CX_RGBA2HSV_FULL",
"CX_RGBA2Lab", "CX_RGBA2Luv", "CX_RGBA2XYZ",
"CX_RGBA2YCrCb", "CX_RGBA2YUV",
"COLOR_XYZ2BGR", "COLOR_XYZ2RGB", "CX_XYZ2BGRA", "CX_XYZ2RGBA",
"COLOR_YCrCb2BGR", "COLOR_YCrCb2RGB", "CX_YCrCb2BGRA", "CX_YCrCb2RGBA",
"COLOR_YUV2BGR", "COLOR_YUV2RGB", "CX_YUV2BGRA", "CX_YUV2RGBA"
];
const CvtModeSize = [cvSize.szODD, cvSize.szVGA, cvSize.sz1080p];
const combiCvtMode = combine(CvtModeSize, CvtMode);
// didn't support 16u and 32f perf tests according to
// https://github.com/opencv/opencv/commit/4e679e1cc5b075ec006b29a58b4fe117523fba1d
const CvtMode16U = [
"COLOR_BGR2BGRA", "COLOR_BGR2GRAY",
"COLOR_BGR2RGB", "COLOR_BGR2RGBA", "COLOR_BGR2XYZ",
"COLOR_BGR2YCrCb", "COLOR_BGR2YUV",
"COLOR_BGRA2BGR", "COLOR_BGRA2GRAY", "COLOR_BGRA2RGBA",
"CX_BGRA2XYZ",
"CX_BGRA2YCrCb", "CX_BGRA2YUV",
"COLOR_GRAY2BGR", "COLOR_GRAY2BGRA",
"COLOR_RGB2GRAY",
"COLOR_RGB2XYZ", "COLOR_RGB2YCrCb", "COLOR_RGB2YUV",
"COLOR_RGBA2BGR", "COLOR_RGBA2GRAY",
"CX_RGBA2XYZ",
"CX_RGBA2YCrCb", "CX_RGBA2YUV",
"COLOR_XYZ2BGR", "COLOR_XYZ2RGB", "CX_XYZ2BGRA", "CX_XYZ2RGBA",
"COLOR_YCrCb2BGR", "COLOR_YCrCb2RGB", "CX_YCrCb2BGRA", "CX_YCrCb2RGBA",
"COLOR_YUV2BGR", "COLOR_YUV2RGB", "CX_YUV2BGRA", "CX_YUV2RGBA"
];
const CvtMode16USize = [cvSize.szODD, cvSize.szVGA, cvSize.sz1080p];
const combiCvtMode16U = combine(CvtMode16USize, CvtMode16U);
const CvtMode32F = [
"COLOR_BGR2BGRA", "COLOR_BGR2GRAY",
"COLOR_BGR2HLS", "COLOR_BGR2HLS_FULL", "COLOR_BGR2HSV", "COLOR_BGR2HSV_FULL",
"COLOR_BGR2Lab", "COLOR_BGR2Luv", "COLOR_BGR2RGB", "COLOR_BGR2RGBA", "COLOR_BGR2XYZ",
"COLOR_BGR2YCrCb", "COLOR_BGR2YUV",
"COLOR_BGRA2BGR", "COLOR_BGRA2GRAY", "COLOR_BGRA2RGBA",
"CX_BGRA2HLS", "CX_BGRA2HLS_FULL", "CX_BGRA2HSV", "CX_BGRA2HSV_FULL",
"CX_BGRA2Lab", "CX_BGRA2Luv", "CX_BGRA2XYZ",
"CX_BGRA2YCrCb", "CX_BGRA2YUV",
"COLOR_GRAY2BGR", "COLOR_GRAY2BGRA",
"COLOR_HLS2BGR", "COLOR_HLS2BGR_FULL", "COLOR_HLS2RGB", "COLOR_HLS2RGB_FULL",
"CX_HLS2BGRA", "CX_HLS2BGRA_FULL", "CX_HLS2RGBA", "CX_HLS2RGBA_FULL",
"COLOR_HSV2BGR", "COLOR_HSV2BGR_FULL", "COLOR_HSV2RGB", "COLOR_HSV2RGB_FULL",
"CX_HSV2BGRA", "CX_HSV2BGRA_FULL", "CX_HSV2RGBA", "CX_HSV2RGBA_FULL",
"COLOR_Lab2BGR", "COLOR_Lab2LBGR", "COLOR_Lab2LRGB", "COLOR_Lab2RGB",
"CX_Lab2BGRA", "CX_Lab2LBGRA", "CX_Lab2LRGBA", "CX_Lab2RGBA",
"COLOR_LBGR2Lab", "COLOR_LBGR2Luv", "COLOR_LRGB2Lab", "COLOR_LRGB2Luv",
"CX_LBGRA2Lab", "CX_LBGRA2Luv", "CX_LRGBA2Lab", "CX_LRGBA2Luv",
"COLOR_Luv2BGR", "COLOR_Luv2LBGR", "COLOR_Luv2LRGB", "COLOR_Luv2RGB",
"CX_Luv2BGRA", "CX_Luv2LBGRA", "CX_Luv2LRGBA", "CX_Luv2RGBA",
"COLOR_RGB2GRAY",
"COLOR_RGB2HLS", "COLOR_RGB2HLS_FULL", "COLOR_RGB2HSV", "COLOR_RGB2HSV_FULL",
"COLOR_RGB2Lab", "COLOR_RGB2Luv", "COLOR_RGB2XYZ", "COLOR_RGB2YCrCb", "COLOR_RGB2YUV",
"COLOR_RGBA2BGR", "COLOR_RGBA2GRAY",
"CX_RGBA2HLS", "CX_RGBA2HLS_FULL", "CX_RGBA2HSV", "CX_RGBA2HSV_FULL",
"CX_RGBA2Lab", "CX_RGBA2Luv", "CX_RGBA2XYZ",
"CX_RGBA2YCrCb", "CX_RGBA2YUV",
"COLOR_XYZ2BGR", "COLOR_XYZ2RGB", "CX_XYZ2BGRA", "CX_XYZ2RGBA",
"COLOR_YCrCb2BGR", "COLOR_YCrCb2RGB", "CX_YCrCb2BGRA", "CX_YCrCb2RGBA",
"COLOR_YUV2BGR", "COLOR_YUV2RGB", "CX_YUV2BGRA", "CX_YUV2RGBA"
];
const CvtMode32FSize = [cvSize.szODD, cvSize.szVGA, cvSize.sz1080p];
const combiCvtMode32F = combine(CvtMode32FSize, CvtMode32F);
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) {
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) {
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 = [size.width, size.height];
addCvtColorCase(suite);
// set init params
let index = suite.length - 1;
suite[index].params = {
size: sizeArray,
matType: matType,
mode: mode
};
};
}
function addCvtModeBayerCase(suite, combination) {
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 = [size.width, size.height];
addCvtColorCase(suite);
// set init params
let index = suite.length - 1;
suite[index].params = {
size: sizeArray,
matType: matType,
mode: mode
};
};
}
function addCvtMode2Case(suite, combination) {
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 = [size.width, size.height+size.height/2];
addCvtColorCase(suite);
// set init params
let index = suite.length - 1;
suite[index].params = {
size: sizeArray,
matType: matType,
mode: mode
};
};
}
function addCvtMode3Case(suite, combination) {
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 = [size.width, size.height+size.height/2];
addCvtColorCase(suite);
// set init params
let index = suite.length - 1;
suite[index].params = {
size: sizeArray,
matType: matType,
mode: mode
};
};
}
function addEdgeAwareBayerModeCase(suite, combination) {
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 = [size.width, size.height];
addCvtColorCase(suite);
// set init params
let index = suite.length - 1;
suite[index].params = {
size: sizeArray,
matType: matType,
mode: mode
};
};
}
function decodeParams2Case(suite, params) {
let sizeStr = (params.match(/[0-9]+/g) || []).slice(0, 2).toString();
let mode = (params.match(/CX\_[A-z]+2[A-z]+/) || params.match(/COLOR\_[A-z]+2[A-z]+/) || []).toString();
let size = cvtStr2cvSize(sizeStr);
// check if the params match and add case
for (let i = 0; i < combinations.length; ++i) {
let combination = combinations[i];
for (let j = 0; j < combination.length; ++j) {
if (size === combination[j][0] && mode === combination[j][1]) {
cvtFunc[i](suite, [combination[j]]);
}
}
}
}
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 params = event.target.params;
let mode = params.mode;
let size = params.size;
log(`=== ${event.target.name} ${currentCaseId} ===`);
log(`params: (${parseInt(size[0])}x${parseInt(size[1])}, ${mode})`);
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;
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];
decodeParams2Case(suite, params);
} else {
log("no filter or getting invalid params, run all the cases");
addCvtModeCase(suite, combiCvtMode);
addCvtModeBayerCase(suite, combiCvtModeBayer);
addCvtMode2Case(suite, combiCvtMode2);
addCvtMode3Case(suite, combiCvtMode3);
}
setBenchmarkSuite(suite);
log(`Running ${totalCaseNum} tests from CvtColor`);
suite.run({ 'async': true }); // run the benchmark
}
// init
let cvtFunc = [addCvtModeCase, addCvtModeBayerCase, addCvtMode2Case, addCvtMode3Case];//, addEdgeAwareBayerModeCase];
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) {
runButton.setAttribute("disabled", "disabled");
runButton.setAttribute('class', 'btn btn-primary disabled');
runButton.innerHTML = "Running";
}
}
}
};
@@ -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>
+262
View File
@@ -0,0 +1,262 @@
const 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');
}
cv.onRuntimeInitialized = () => {
console.log('opencv.js loaded');
if (isNodeJs) {
global.cv = cv;
global.combine = HelpFunc.combine;
global.fillGradient = HelpFunc.fillGradient;
global.cvtStr2cvSize = HelpFunc.cvtStr2cvSize;
global.cvSize = Base.cvSize;
} else {
runButton.removeAttribute('disabled');
runButton.setAttribute('class', 'btn btn-primary');
runButton.innerHTML = 'Run';
}
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 addResizeUpLinearCase(suite, combination) {
totalCaseNum += combination.length;
for (let i = 0; i < combination.length; ++i) {
let matType = combination[i][0];
let from = combination[i][1];
let to = combination[i][2];
suite.add('resize', function() {
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 dst = new cv.Mat(to, matType);
fillGradient(cv, src);
},
'teardown': function() {
src.delete();
dst.delete();
}
});
// set init params
let index = suite.length - 1;
suite[index].params = {
from: from,
to: to,
matType: matType
};
}
}
function addResizeDownLinearCase(suite, combination) {
totalCaseNum += combination.length;
for (let i = 0; i < combination.length; ++i) {
let matType = combination[i][0];
let from = combination[i][1];
let to = combination[i][2];
suite.add('resize', function() {
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 dst = new cv.Mat(to, matType);
fillGradient(cv, src);
},
'teardown': function() {
src.delete();
dst.delete();
}
});
// set init params
let index = suite.length - 1;
suite[index].params = {
from: from,
to: to,
matType: matType
};
}
}
function addResizeAreaFastCase(suite, combination) {
totalCaseNum += combination.length;
for (let i = 0; i < combination.length; ++i) {
let matType = combination[i][0];
let from = combination[i][1];
let scale = combination[i][2];
from.width = (Math.floor(from.width/scale))*scale;
from.height = (Math.floor(from.height/scale))*scale;
let to = {
width: from.width/scale,
height: from.height/scale}; // for params print
suite.add('resize', function() {
cv.resize(src, dst, dst.size(), 0, 0, cv.INTER_AREA);
}, {
'setup': function() {
let from = this.params.from;
let scale = this.params.scale;
let matType = cv[this.params.matType];
let src = new cv.Mat(from, matType);
let dst = new cv.Mat(from.height/scale, from.width/scale, matType);
},
'teardown': function() {
src.delete();
dst.delete();
}
});
// set init params
let index = suite.length - 1;
suite[index].params = {
from: from,
scale: scale,
matType: matType
};
}
}
function decodeParams2Case(suite, params) {
let sizeString = (params.match(/[0-9]+x[0-9]+/g) || []).slice(0, 2).toString();
let sizes = (sizeString.match(/[0-9]+/g) || []);
let size1Str = sizes.slice(0, 2).toString();
let size2Str = sizes.slice(2, 5).toString();
let matType = (params.match(/CV\_[0-9]+[A-z][A-z][0-9]/) || []).toString();
let size1 = cvtStr2cvSize(size1Str);
let size2 = cvtStr2cvSize(size2Str);
// check if the params match and add case
for (let i = 0; i < combinations.length; ++i) {
let combination = combinations[i];
for (let j = 0; j < combination.length; ++j) {
if (matType === combination[j][0] && size1 === combination[j][1] && size2 === combination[j][2]) {
resizeFunc[i](suite, [combination[j]]);
}
}
}
}
function log(message) {
console.log(message);
if (!isNodeJs) {
logElement.innerHTML += `\n${'\t'.repeat(1) + message}`;
}
}
function setBenchmarkSuite(suite) {
suite
// add listeners
.on('cycle', function(event) {
++currentCaseId;
let params = event.target.params;
let matType = params.matType;
let size1 = params.from;
let size2 = params.to;
log(`=== ${event.target.name} ${currentCaseId} ===`);
log(`params: (${matType},${parseInt(size1.width)}x${parseInt(size1.height)},`+
`${parseInt(size2.width)}x${parseInt(size2.height)})`);
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;
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];
decodeParams2Case(suite, params);
} else {
log("no filter or getting invalid params, run all the cases");
addResizeUpLinearCase(suite, combiUpLinear);
addResizeDownLinearCase(suite, combiDownLinear);
}
setBenchmarkSuite(suite);
log(`Running ${totalCaseNum} tests from Resize`);
suite.run({ 'async': true }); // run the benchmark
}
// init
let resizeFunc = [addResizeUpLinearCase, addResizeDownLinearCase];//, addResizeAreaFastCase];
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) {
runButton.setAttribute("disabled", "disabled");
runButton.setAttribute('class', 'btn btn-primary disabled');
runButton.innerHTML = "Running";
}
}
}
};
@@ -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,217 @@
const 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');
}
cv.onRuntimeInitialized = () => {
console.log('opencv.js loaded');
if (isNodeJs) {
global.cv = cv;
global.combine = HelpFunc.combine;
global.cvtStr2cvSize = HelpFunc.cvtStr2cvSize;
global.cvSize = Base.cvSize;
} else {
runButton.removeAttribute('disabled');
runButton.setAttribute('class', 'btn btn-primary');
runButton.innerHTML = 'Run';
}
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 addSizeMatTypeThreshTypeCase(suite, combination) {
totalCaseNum += combination.length;
for (let i = 0; i < combination.length; ++i) {
let matSize = combination[i][0];
let matType = combination[i][1];
let threshType = combination[i][2];
suite.add('threshold', function() {
cv.threshold(src, dst, threshold, thresholdMax, threshType);
}, {
'setup': function() {
let matSize = this.params.matSize;
let matType = cv[this.params.matType];
let threshType = cv[this.params.threshType];
let threshold = 127.0;
let thresholdMax = 210.0;
let src = new cv.Mat(matSize, matType);
let dst = new cv.Mat(matSize, matType);
let srcView = src.data;
srcView[0] = 0;
srcView[1] = 100;
srcView[2] = 200;
},
'teardown': function() {
src.delete();
dst.delete();
}
});
// set init params
let index = suite.length - 1;
suite[index].params = {
matSize: matSize,
matType: matType,
threshType: threshType
};
}
}
function addSizeOnlyCase(suite, combination) {
totalCaseNum += combination.length;
for (let i = 0; i < combination.length; ++i) {
let matSize = combination[i][0];
suite.add('threshold', function() {
cv.threshold(src, dst, threshold, thresholdMax, cv.THRESH_BINARY|cv.THRESH_OTSU);
}, {
'setup': function() {
let matSize = this.params.matSize;
let threshold = 127.0;
let thresholdMax = 210.0;
let src = new cv.Mat(matSize, cv.CV_8UC1);
let dst = new cv.Mat(matSize, cv.CV_8UC1);
let srcView = src.data;
srcView[0] = 0;
srcView[1] = 100;
srcView[2] = 200;
},
'teardown': function() {
src.delete();
dst.delete();
}
});
// set init params
let index = suite.length - 1;
suite[index].params = {
matSize: matSize,
matType: 'CV_8UC1',
threshType: 'THRESH_BINARY|THRESH_OTSU'
};
}
}
function decodeParams2Case(suite, params, isSizeOnly) {
let sizeString = params.match(/[0-9]+x[0-9]+/g).toString();
let sizes = sizeString.match(/[0-9]+/g);
let size1Str = sizes.slice(0, 2).toString();
let matSize = cvtStr2cvSize(size1Str);
let matType, threshType;
if (isSizeOnly) {
matType = 'CV_8UC1';
threshType = 'THRESH_BINARY|THRESH_OTSU';
} else {
matType = (params.match(/CV\_[0-9]+[A-z][A-z][0-9]/) || []).toString();
threshType = (params.match(/THRESH\_[A-z]+\_?[A-z]*/) || []).toString();
}
// check if the params match and add case
for (let i = 0; i < combinations.length; ++i) {
let combination = combinations[i];
for (let j = 0; j < combination.length; ++j) {
if (matSize === combination[j][0] && matType === combination[j][1] && threshType === combination[j][2]) {
thresholdFunc[i](suite, [combination[j]]);
}
}
}
}
function log(message) {
console.log(message);1
if (!isNodeJs) {
logElement.innerHTML += `\n${'\t'.repeat(1) + message}`;
}
}
function setBenchmarkSuite(suite) {
suite
// add listeners
.on('cycle', function(event) {
++currentCaseId;
let params = event.target.params;
let matSize = params.matSize;
let matType = params.matType;
let threshType = params.threshType;
log(`=== ${event.target.name} ${currentCaseId} ===`);
log(`params: (${parseInt(matSize.width)}x${parseInt(matSize.height)},`+
`${matType},${threshType})`);
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;
totalCaseNum = 0;
currentCaseId = 0;
if (/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\w+\)/g.test(paramsContent.toString())) {
let params = paramsContent.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\w+\)/g)[0];
let isSizeOnly = 0;
decodeParams2Case(suite, params, isSizeOnly);
} else if (/[\ ]*[0-9]+x[0-9]+[\ ]*/g.test(paramsContent.toString())) {
let params = paramsContent.toString().match(/[\ ]*[0-9]+x[0-9]+[\ ]*/g)[0];
let isSizeOnly = 1;
decodeParams2Case(suite, params, isSizeOnly);
}
else {
log("no filter or getting invalid params, run all the cases");
addSizeMatTypeThreshTypeCase(suite, combiSizeMatTypeThreshType);
addSizeOnlyCase(suite, combiSizeOnly);
}
setBenchmarkSuite(suite);
log(`Running ${totalCaseNum} tests from Threshold`);
suite.run({ 'async': true }); // run the benchmark
}
// init
let thresholdFunc = [addSizeMatTypeThreshTypeCase, addSizeOnlyCase];
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]+,[\ ]*\w+,[\ ]*\w+\)/g.test(args.toString())) {
paramsContent = args.toString().match(/\([0-9]+x[0-9]+,[\ ]*\w+,[\ ]*\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) {
runButton.setAttribute("disabled", "disabled");
runButton.setAttribute('class', 'btn btn-primary disabled');
runButton.innerHTML = "Running";
}
}
}
};
+80 -4
View File
@@ -71,6 +71,18 @@
#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;
@@ -357,6 +369,51 @@ namespace binding_utils
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)
@@ -531,10 +588,10 @@ EMSCRIPTEN_BINDINGS(binding_utils)
.field("distance", &cv::DMatch::distance);
emscripten::value_array<cv::Scalar_<double>> ("Scalar")
.element(index<0>())
.element(index<1>())
.element(index<2>())
.element(index<3>());
.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)
@@ -610,6 +667,25 @@ EMSCRIPTEN_BINDINGS(binding_utils)
function("getBuildInformation", &binding_utils::getBuildInformation);
#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);
+7 -1
View File
@@ -87,9 +87,15 @@ def make_umd(opencvjs, cvjs):
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
} 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