From 960f501cc18bed647c3718c4d62fc94a4819ab1c Mon Sep 17 00:00:00 2001 From: Ziachnix <76476871+Ziachnix@users.noreply.github.com> Date: Sat, 13 Mar 2021 13:52:44 +0100 Subject: [PATCH] Merge pull request #19284 from Ziachnix:feature/js-qr-code-detector Add QRCodeDetector to JavaScript Build * ADD: js support for qrCodeDetector - cherry picked commit to solve rebase error * CHG. Revert haarcascade path * FIX: Tests without images * ADD: decodeCurved * js(docs): don't require OPENCV_TEST_DATA_PATH Co-authored-by: Alexander Alekhin --- .../js_setup/js_setup/js_setup.markdown | 7 ++++ modules/js/generator/embindgen.py | 7 ++-- modules/js/test/test_objdetect.js | 41 +++++++++++++++++++ platforms/js/build_js.py | 2 +- platforms/js/opencv_js.config.py | 3 +- 5 files changed, 54 insertions(+), 6 deletions(-) diff --git a/doc/js_tutorials/js_setup/js_setup/js_setup.markdown b/doc/js_tutorials/js_setup/js_setup/js_setup.markdown index 7fd7fe05c3..43bffc9653 100644 --- a/doc/js_tutorials/js_setup/js_setup/js_setup.markdown +++ b/doc/js_tutorials/js_setup/js_setup/js_setup.markdown @@ -138,6 +138,7 @@ Building OpenCV.js from Source python ./platforms/js/build_js.py build_js --cmake_option="-DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules" @endcode + Running OpenCV.js Tests --------------------------------------- @@ -303,6 +304,12 @@ The example uses latest version of emscripten. If the build fails you should try docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk:2.0.10 emcmake python3 ./platforms/js/build_js.py build_js @endcode +In Windows use the following PowerShell command: + +@code{.bash} +docker run --rm --workdir /src -v "$(get-location):/src" "emscripten/emsdk:2.0.10" emcmake python3 ./platforms/js/build_js.py build_js +@endcode + ### Building the documentation with Docker To build the documentation `doxygen` needs to be installed. Create a file named `Dockerfile` with the following content: diff --git a/modules/js/generator/embindgen.py b/modules/js/generator/embindgen.py index a11309a551..dc7a001df1 100644 --- a/modules/js/generator/embindgen.py +++ b/modules/js/generator/embindgen.py @@ -119,6 +119,7 @@ type_dict = { 'InputOutputArray': 'cv::Mat&', 'InputArrayOfArrays': 'const std::vector&', 'OutputArrayOfArrays': 'std::vector&', + 'string': 'std::string', 'String': 'std::string', 'const String&':'const std::string&' } @@ -462,8 +463,7 @@ class JSWrapperGenerator(object): ret_type = type_dict[ptr_type] for key in type_dict: if key in ret_type: - ret_type = ret_type.replace(key, type_dict[key]) - + ret_type = re.sub('(^|[^\w])' + key + '($|[^\w])', type_dict[key], ret_type) arg_types = [] unwrapped_arg_types = [] for arg in variant.args: @@ -567,7 +567,7 @@ class JSWrapperGenerator(object): # consider the default parameter variants args_num = len(variant.args) - j if args_num in class_info.constructor_arg_num: - # FIXME: workaournd for constructor overload with same args number + # FIXME: workaround for constructor overload with same args number # e.g. DescriptorMatcher continue class_info.constructor_arg_num.add(args_num) @@ -627,7 +627,6 @@ class JSWrapperGenerator(object): ret_type = 'void' if variant.rettype.strip() == '' else variant.rettype ret_type = ret_type.strip() - if ret_type.startswith('Ptr'): #smart pointer ptr_type = ret_type.replace('Ptr<', '').replace('>', '') if ptr_type in type_dict: diff --git a/modules/js/test/test_objdetect.js b/modules/js/test/test_objdetect.js index 79c357ae2f..dc863d682f 100644 --- a/modules/js/test/test_objdetect.js +++ b/modules/js/test/test_objdetect.js @@ -159,3 +159,44 @@ QUnit.test('Cascade classification', function(assert) { 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(); + + } +}); \ No newline at end of file diff --git a/platforms/js/build_js.py b/platforms/js/build_js.py index 7f9ce3ea8b..c9a451643f 100644 --- a/platforms/js/build_js.py +++ b/platforms/js/build_js.py @@ -114,7 +114,7 @@ class Builder: "-DWITH_GPHOTO2=OFF", "-DWITH_LAPACK=OFF", "-DWITH_ITT=OFF", - "-DWITH_QUIRC=OFF", + "-DWITH_QUIRC=ON", "-DBUILD_ZLIB=ON", "-DBUILD_opencv_apps=OFF", "-DBUILD_opencv_calib3d=ON", diff --git a/platforms/js/opencv_js.config.py b/platforms/js/opencv_js.config.py index 749624be88..86551ae4d9 100644 --- a/platforms/js/opencv_js.config.py +++ b/platforms/js/opencv_js.config.py @@ -22,7 +22,8 @@ imgproc = {'': ['Canny', 'GaussianBlur', 'Laplacian', 'HoughLines', 'HoughLinesP objdetect = {'': ['groupRectangles'], 'HOGDescriptor': ['load', 'HOGDescriptor', 'getDefaultPeopleDetector', 'getDaimlerPeopleDetector', 'setSVMDetector', 'detectMultiScale'], - 'CascadeClassifier': ['load', 'detectMultiScale2', 'CascadeClassifier', 'detectMultiScale3', 'empty', 'detectMultiScale']} + 'CascadeClassifier': ['load', 'detectMultiScale2', 'CascadeClassifier', 'detectMultiScale3', 'empty', 'detectMultiScale'], + 'QRCodeDetector': ['QRCodeDetector', 'decode', 'decodeCurved', 'detect', 'detectAndDecode', 'detectMulti', 'setEpsX', 'setEpsY']} video = {'': ['CamShift', 'calcOpticalFlowFarneback', 'calcOpticalFlowPyrLK', 'createBackgroundSubtractorMOG2', \ 'findTransformECC', 'meanShift'],