nareshmlx/opencv-pr huggingface dataset:
**File:** modules/gapi/test/infer/gapi_infer_onnx_test.cpp
**Change Type:** modified
**Context:** PR #18903: G-API: ONNX. Disable unnecessary outputs

**Code Changes:**
```diff
@@ -9,10 +9,11 @@
 #ifdef HAVE_ONNX
 
 #include <stdexcept>
-#include <onnxruntime_cxx_api.h>
-#include <ade/util/iota_range.hpp>
 #include <codecvt> // wstring_convert
 
+#include <onnxruntime_cxx_api.h>
+#include <ade/util/iota_range.hpp>
```

Review comment:
I don't get this overall message though
**File:** modules/gapi/test/infer/gapi_infer_onnx_test.cpp
**Change Type:** modified
**Context:** PR #18903: G-API: ONNX. Disable unnecessary outputs
**Review Line:** 203

**Code Changes:**
```diff
@@ -192,7 +200,7 @@ void remapYolo(const std::unordered_map<std::string, cv::Mat> &onnx,
     // Configured output
     cv::Mat& out = gapi.begin()->second;
     // Simple copy
-    copyToOut<float>(in, out);
+    copyToOut<float>(in, -1.f, out);
 }
 
 void remapYoloV3(const std::unordered_map<std::string, cv::Mat> &onnx,
@@ -209,13 +217,14 @@ void remapYoloV3(const std::unordered_map<std::string, cv::Mat> &onnx,
     cv::Mat& out_scores = gapi.at("out2");
```

Review comment:
Where does this magic number come from?
**File:** modules/gapi/test/infer/gapi_infer_onnx_test.cpp
**Change Type:** modified
**Context:** PR #18903: G-API: ONNX. Disable unnecessary outputs

**Code Changes:**
```diff
@@ -9,10 +9,11 @@
 #ifdef HAVE_ONNX
 
 #include <stdexcept>
-#include <onnxruntime_cxx_api.h>
-#include <ade/util/iota_range.hpp>
 #include <codecvt> // wstring_convert
 
+#include <onnxruntime_cxx_api.h>
+#include <ade/util/iota_range.hpp>
```

Review comment:
Changed message.
**File:** modules/gapi/test/infer/gapi_infer_onnx_test.cpp
**Change Type:** modified
**Context:** PR #18903: G-API: ONNX. Disable unnecessary outputs
**Review Line:** 203

**Code Changes:**
```diff
@@ -192,7 +200,7 @@ void remapYolo(const std::unordered_map<std::string, cv::Mat> &onnx,
     // Configured output
     cv::Mat& out = gapi.begin()->second;
     // Simple copy
-    copyToOut<float>(in, out);
+    copyToOut<float>(in, -1.f, out);
 }
 
 void remapYoloV3(const std::unordered_map<std::string, cv::Mat> &onnx,
@@ -209,13 +217,14 @@ void remapYoloV3(const std::unordered_map<std::string, cv::Mat> &onnx,
     cv::Mat& out_scores = gapi.at("out2");
```

Review comment:
From user. It is end of data mark. Output has positive values and this mark separate correct data and garbage. `copyToOut` function is part of remapping function.
**File:** modules/gapi/include/opencv2/gapi/infer/onnx.hpp
**Change Type:** modified
**Context:** PR #18903: G-API: ONNX. Disable unnecessary outputs
**Review Line:** 134

**Code Changes:**
```diff
+    @param out_metas out meta information.
+    @param pp post processing function, which has two parameters. First is onnx
+    result, second is graph output. Both parameters is std::map that contain pair of
+    layer's name and cv::Mat.
+    @return reference to object of class Params.
+    */
+    Params<Net>& cfgPostProc(const std::vector<cv::GMatDesc> &out_metas,
                              const PostProc &pp) {
-        desc.out_metas = outs;
+        desc.out_metas        = out_metas;
         desc.custom_post_proc = pp;
```

Review comment:
Please merge this now open a follow-up task to fix this text.
**File:** apps/model-diagnostics/model_diagnostics.cpp
**Change Type:** added
**Context:** PR #19693: ONNX diagnostic tool corrections

**Code Changes:**
```diff
@@ -0,0 +1,62 @@
+/*************************************************
+USAGE:
+./model_diagnostics -m <onnx file location>
+**************************************************/
+#include <opencv2/dnn.hpp>
+#include <opencv2/core/utils/filesystem.hpp>
+
+#include <iostream>
+
```

Review comment:
it's not good to alter DNN behaviour by setting a global variable. It would be better to have an overloaded variant of readNet() that will pass the corresponding flags to the importers w/o affecting global state.
**File:** apps/model-diagnostics/model_diagnostics.cpp
**Change Type:** added
**Context:** PR #19693: ONNX diagnostic tool corrections
**Review Line:** 1

**Code Changes:**
```diff
@@ -0,0 +1,62 @@
+/*************************************************
+USAGE:
+./model_diagnostics -m <onnx file location>
+**************************************************/
+#include <opencv2/dnn.hpp>
+#include <opencv2/core/utils/filesystem.hpp>
```

Review comment:
would be nice to also have a Python script for that, not just .cpp app.
**File:** apps/model-diagnostics/model_diagnostics.cpp
**Change Type:** added
**Context:** PR #19693: ONNX diagnostic tool corrections
**Review Line:** 1

**Code Changes:**
```diff
@@ -0,0 +1,62 @@
+/*************************************************
+USAGE:
+./model_diagnostics -m <onnx file location>
+**************************************************/
+#include <opencv2/dnn.hpp>
+#include <opencv2/core/utils/filesystem.hpp>
```

Review comment:
Why is it important? It's debug tool for DNN networks. Python bindings adds extra abstraction layer and make debugging harder.
**File:** apps/model-diagnostics/model_diagnostics.cpp
**Change Type:** added
**Context:** PR #19693: ONNX diagnostic tool corrections

**Code Changes:**
```diff
@@ -0,0 +1,62 @@
+/*************************************************
+USAGE:
+./model_diagnostics -m <onnx file location>
+**************************************************/
+#include <opencv2/dnn.hpp>
+#include <opencv2/core/utils/filesystem.hpp>
+
+#include <iostream>
+
```

Review comment:
I prefer adding global variable instead of exploding of public API. API parameters should cover regular usage and don't confuse users. It is some kind of logging utilities. Even in functional world nobody brings logger instance parameter into each function. --- This approach allows to keep this patch small.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #19693: ONNX diagnostic tool corrections

**Code Changes:**
```diff
@@ -100,6 +100,18 @@ CV__DNN_INLINE_NS_BEGIN
     CV_EXPORTS std::vector< std::pair<Backend, Target> > getAvailableBackends();
     CV_EXPORTS_W std::vector<Target> getAvailableTargets(dnn::Backend be);
 
+    /**
+     * @brief Enables detailed logging of the DNN model loading with CV DNN API.
+     * @param[in] isDiagnosticsMode Indicates whether diagnostic mode should be set.
+     *
+     * Diagnostic mode provides detailed logging of the model loading stage to explore
+     * potential problems (ex.: not implemented layer type).
```

Review comment:
Please mention reading / loading stage of DNN models in the name and documentation string. Current generic name may confuse users.
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #19693: ONNX diagnostic tool corrections

**Code Changes:**
```diff
@@ -8,6 +8,8 @@
 #include "../precomp.hpp"
 #include <opencv2/dnn/shape_utils.hpp>
 
+#include <opencv2/dnn/layer_reg.private.hpp>
+
 #include <opencv2/core/utils/logger.defines.hpp>
 #undef CV_LOG_STRIP_LEVEL
 #define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_DEBUG + 1
@@ -37,6 +39,7 @@ namespace cv {
```

Review comment:
Lets minimize global mandatory variables initialization. Move them to functions with initialization on-demand. ``` /*static*/ const std::set<String>& ONNXImporter::getSupportedTypes() { static const std::set<String> g_types = { ... }; return g_types; } ```
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #19693: ONNX diagnostic tool corrections
**Review Line:** 108

**Code Changes:**
```diff
+    /**
+     * @brief Enables detailed logging of the DNN model loading with CV DNN API.
+     * @param[in] isDiagnosticsMode Indicates whether diagnostic mode should be set.
+     *
+     * Diagnostic mode provides detailed logging of the model loading stage to explore
+     * potential problems (ex.: not implemented layer type).
+     *
+     * @note In diagnostic mode series of assertions will be skipped, it can lead to the
+     * expected application crash.
+     */
+    CV_EXPORTS void enableModelDiagnostics(bool isDiagnosticsMode);
```

Review comment:
I propose to implicitly declare that the option is dangerous because it forces DNN module to skip internal shape/status/exceptions check and it may crash the app.
**File:** apps/model-diagnostics/model_diagnostics.cpp
**Change Type:** added
**Context:** PR #19693: ONNX diagnostic tool corrections

**Code Changes:**
```diff
@@ -0,0 +1,62 @@
+/*************************************************
+USAGE:
+./model_diagnostics -m <onnx file location>
+**************************************************/
+#include <opencv2/dnn.hpp>
+#include <opencv2/core/utils/filesystem.hpp>
+
+#include <iostream>
+
```

Review comment:
I do not think that `findFile` call is good idea. It's diagnostic tool and it should work with path without search.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #19693: ONNX diagnostic tool corrections
**Review Line:** 108

**Code Changes:**
```diff
+    /**
+     * @brief Enables detailed logging of the DNN model loading with CV DNN API.
+     * @param[in] isDiagnosticsMode Indicates whether diagnostic mode should be set.
+     *
+     * Diagnostic mode provides detailed logging of the model loading stage to explore
+     * potential problems (ex.: not implemented layer type).
+     *
+     * @note In diagnostic mode series of assertions will be skipped, it can lead to the
+     * expected application crash.
+     */
+    CV_EXPORTS void enableModelDiagnostics(bool isDiagnosticsMode);
```

Review comment:
Added 'note' about it.
**File:** modules/dnn/src/layers/slice_layer.cpp
**Change Type:** modified
**Context:** PR #19546: Added Steps support in DNN Slice layer

**Code Changes:**
```diff
@@ -64,6 +64,7 @@ class SliceLayerImpl : public SliceLayer
     SliceLayerImpl(const LayerParams& params)
     {
         setParamsFrom(params);
+        hasSteps = false;
         axis = params.get<int>("axis", 1);
         num_split = params.get<int>("num_split", 0);
         hasDynamicShapes = params.get<bool>("has_dynamic_shapes", false);
@@ -112,6 +113,22 @@ class SliceLayerImpl : public SliceLayer
                     sliceRanges[0][i].end = end;  // We'll finalize a negative value later.
```

Review comment:
Perhaps this check should be moved out of `.forward()` method and calculated earlier (store value as class field). Try to put that before `supportBackend()` callback to properly support for other backends: IE, Vulkan, CUDA or OpenCL target.
**File:** modules/dnn/src/layers/slice_layer.cpp
**Change Type:** modified
**Context:** PR #19546: Added Steps support in DNN Slice layer

**Code Changes:**
```diff
@@ -64,6 +64,7 @@ class SliceLayerImpl : public SliceLayer
     SliceLayerImpl(const LayerParams& params)
     {
         setParamsFrom(params);
+        hasSteps = false;
         axis = params.get<int>("axis", 1);
         num_split = params.get<int>("num_split", 0);
         hasDynamicShapes = params.get<bool>("has_dynamic_shapes", false);
@@ -112,6 +113,22 @@ class SliceLayerImpl : public SliceLayer
                     sliceRanges[0][i].end = end;  // We'll finalize a negative value later.
```

Review comment:
Do we really need `finalSliceSteps`? We use `finalSliceRanges` to replace negative ranges to absolute values depends on input shape. Do we have undetermined steps?
**File:** modules/dnn/src/layers/slice_layer.cpp
**Change Type:** modified
**Context:** PR #19546: Added Steps support in DNN Slice layer
**Review Line:** 169

**Code Changes:**
```diff
                 {
                     if (shapesInitialized || inpShape[j] > 0)
                         outputs[i][j] = normalize_axis_range(sliceRanges[i][j], inpShape[j]).size();
+
+                    if (!sliceSteps.empty() && (i < sliceSteps.size()) && (j < sliceSteps[i].size()) && (sliceSteps[i][j] > 1))
+                        outputs[i][j] = (outputs[i][j] + sliceSteps[i][j] - 1) / sliceSteps[i][j];
                 }
             }
         }
@@ -181,6 +201,7 @@ class SliceLayerImpl : public SliceLayer
         const MatSize& inpShape = inputs[0].size;
```

Review comment:
Please add out of range checks for `sliceSteps[i][j]` access.
**File:** modules/dnn/src/layers/slice_layer.cpp
**Change Type:** modified
**Context:** PR #19546: Added Steps support in DNN Slice layer

**Code Changes:**
```diff
@@ -64,6 +64,7 @@ class SliceLayerImpl : public SliceLayer
     SliceLayerImpl(const LayerParams& params)
     {
         setParamsFrom(params);
+        hasSteps = false;
         axis = params.get<int>("axis", 1);
         num_split = params.get<int>("num_split", 0);
         hasDynamicShapes = params.get<bool>("has_dynamic_shapes", false);
@@ -112,6 +113,22 @@ class SliceLayerImpl : public SliceLayer
                     sliceRanges[0][i].end = end;  // We'll finalize a negative value later.
```

Review comment:
IMHO, provided implementation is really slow. I believe we should have optimized case for 2D (the last 2 dims) processing at least.
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #19546: Added Steps support in DNN Slice layer

**Code Changes:**
```diff
@@ -641,20 +641,11 @@ void ONNXImporter::handleNode(const opencv_onnx::NodeProto& node_proto_)
             int axis = 0;
             std::vector<int> begin;
             std::vector<int> end;
+            std::vector<int> steps;
             int inp_size = node_proto.input_size();
 
             if (inp_size == 1)
             {
-                if (layerParams.has("steps"))
```

Review comment:
Do we want to support this case?
**File:** modules/dnn/test/test_onnx_importer.cpp
**Change Type:** modified
**Context:** PR #19546: Added Steps support in DNN Slice layer

**Code Changes:**
```diff
@@ -627,6 +627,26 @@ TEST_P(Test_ONNX_layers, Slice)
 #endif
 }
 
+TEST_P(Test_ONNX_layers, Slice_Steps_2DInput)
+{
+    testONNXModels("slice_opset_11_steps_2d");
+}
+
+TEST_P(Test_ONNX_layers, Slice_Steps_3DInput)
```

Review comment:
Implementation should fallback on CPU code instead of test skipping.
**File:** modules/dnn/src/layers/eltwise_layer.cpp
**Change Type:** modified
**Context:** PR #19477: Added TF add behaviour alignment
**Review Line:** 692

**Code Changes:**
```diff
+                            {
+                                outIdx[2] = x;
+                                inputs[i].at<float>(outIdx.data()) = tmpInput.at<float>(idx.data());
+                            }
+                        }
+                    }
+                    inputs[i] = inputs[i].reshape(0, outShape);
+                }
+            }
+        }
+
```

Review comment:
Can you please comment what this block performs? Some kind of reorder?
**File:** modules/dnn/src/layers/eltwise_layer.cpp
**Change Type:** modified
**Context:** PR #19477: Added TF add behaviour alignment
**Review Line:** 689

**Code Changes:**
```diff
+                        {
+                            outIdx[1] = idx[1] = k;
+                            for (size_t x = 0; x < xSize; x++)
+                            {
+                                outIdx[2] = x;
+                                inputs[i].at<float>(outIdx.data()) = tmpInput.at<float>(idx.data());
+                            }
+                        }
+                    }
+                    inputs[i] = inputs[i].reshape(0, outShape);
+                }
```

Review comment:
IMHO, generating duplicated data doesn't look good from performance perspective.
**File:** modules/dnn/src/layers/eltwise_layer.cpp
**Change Type:** modified
**Context:** PR #19477: Added TF add behaviour alignment
**Review Line:** 223

**Code Changes:**
```diff
+            {
+                bool allOnes = isAllOnes(inputs[i], 2, dims);
+                if (!allOnes && !isVecFound)
+                {
+                    vecIdx = i;
+                    isVecFound = true;
+                }
+
+                if (!allOnes && i != vecIdx)
+                {
+                    for (size_t j = 2; j < dims; j++)
```

Review comment:
IMHO, such stuff should be explicitly specified through parameters instead of implicit internal handling.
**File:** modules/dnn/src/layers/eltwise_layer.cpp
**Change Type:** modified
**Context:** PR #19477: Added TF add behaviour alignment
**Review Line:** 213

**Code Changes:**
```diff
         outputChannels = numChannels;
 
         outputs.assign(1, inputs[0]);
         outputs[0][1] = numChannels;
+
+        if (dims > 2)
+        {
+            size_t vecIdx = 0;
+            bool isVecFound = false;
+            for (size_t i = 0; i < inputs.size(); i++)
+            {
```

Review comment:
Removed code above: ``` for (size_t j = 2; j < dims; j++) CV_Assert(inputs[0][j] == inputs[i][j]); ``` ~~Check with `j == 2` is lost.~~
**File:** modules/dnn/src/layers/eltwise_layer.cpp
**Change Type:** modified
**Context:** PR #19477: Added TF add behaviour alignment
**Review Line:** 223

**Code Changes:**
```diff
+            {
+                bool allOnes = isAllOnes(inputs[i], 2, dims);
+                if (!allOnes && !isVecFound)
+                {
+                    vecIdx = i;
+                    isVecFound = true;
+                }
+
+                if (!allOnes && i != vecIdx)
+                {
+                    for (size_t j = 2; j < dims; j++)
```

Review comment:
Main concern here is about correct and accurate implementation of `supportBackend()` callback. Only OpenCV/CPU backend supports new mode (CUDA, Halide, Vulkan, even OpenCV/OpenCL doesn't support that). Unsupported backends should be filtered out in the right way.
**File:** modules/dnn/src/layers/eltwise_layer.cpp
**Change Type:** modified
**Context:** PR #19477: Added TF add behaviour alignment
**Review Line:** 223

**Code Changes:**
```diff
+            {
+                bool allOnes = isAllOnes(inputs[i], 2, dims);
+                if (!allOnes && !isVecFound)
+                {
+                    vecIdx = i;
+                    isVecFound = true;
+                }
+
+                if (!allOnes && i != vecIdx)
+                {
+                    for (size_t j = 2; j < dims; j++)
```

Review comment:
`forward()` is modified below, see `if (channelsModeInput == ELTWISE_CHANNNELS_SAME && inputs[0].dims > 2)` --- Tests filter out non-working "OpenCL" cases (as mentioned there this should not be done for OpenCV/OCL code path) --- > modify only one of the inputs' shape Probably we can't do that. Input is always a some output of another layer. --- > Thus, do we really need supportBackend() callback corrections here? `supportBackend()` must be revised if we add support for new mode.
**File:** modules/dnn/src/layers/eltwise_layer.cpp
**Change Type:** modified
**Context:** PR #19477: Added TF add behaviour alignment
**Review Line:** 658

**Code Changes:**
```diff
@@ -602,6 +654,47 @@ class EltwiseLayerImpl CV_FINAL : public EltwiseLayer
 
         CV_Assert(outputs.size() == 1);
         const int nstripes = getNumThreads();
+
+        if (channelsModeInput == ELTWISE_CHANNNELS_SAME && inputs[0].dims > 2)
+        {
+            for (size_t i = 0; i < inputs.size(); i++)
+            {
+                MatShape inpShape = shape(inputs[i].size);
+                bool allOnes = isAllOnes(inpShape, 2, inputs[i].dims);
```

Review comment:
Please add bailout code in `forward_ocl()` (line 546) for new functionality: ```.diff if ((inputs_.depth() == CV_16S && op != SUM) || (channelsMode != ELTWISE_CHANNNELS_SAME)) return false; + if (hasVecInput) + return false; // TODO not implemented yet: https://github.com/opencv/opencv/pull/19477 ```
**File:** modules/core/misc/objc/common/CVObjcUtil.h
**Change Type:** modified
**Context:** PR #17818: Documentation fixes/improvements

**Code Changes:**
```diff
@@ -6,12 +6,6 @@
 
 #pragma once
 
-typedef union { double d; int64_t l; } V64;
-typedef union { float f; int32_t i; } V32;
-
-#define DOUBLE_TO_BITS(x)  ((V64){ .d = x }).l
-#define FLOAT_TO_BITS(x)  ((V32){ .f = x }).i
-
```

Review comment:
I wonder, if those DOUBLE_TO_BITS, FLOAT_TO_BITS is necessary to have in the form of macros in header files? I guess, those conversions are not that performance-critical? Can we just declare those functions in the header file and implement, together with unions (btw, there are already such unions, Cv32suf and Cv64suf) somewhere in .cpp or .mm file? In this case, we don't have to put HASH_UTILS define in many headers
**File:** doc/js_tutorials/js_setup/js_setup/js_setup.markdown
**Change Type:** modified
**Context:** PR #19284: Add QRCodeDetector to JavaScript Build

**Code Changes:**
```diff
@@ -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
```

Review comment:
Lets keep `OPENCV_TEST_DATA_PATH` optional. Prefer to use environment variable for `OPENCV_TEST_DATA_PATH`.
**File:** modules/js/generator/embindgen.py
**Change Type:** modified
**Context:** PR #19284: Add QRCodeDetector to JavaScript Build

**Code Changes:**
```diff
@@ -119,6 +119,7 @@ def makeWhiteList(module_list):
     'InputOutputArray': 'cv::Mat&',
     'InputArrayOfArrays': 'const std::vector<cv::Mat>&',
     'OutputArrayOfArrays': 'std::vector<cv::Mat>&',
+    'string': 'std::string',
     'String': 'std::string',
     'const String&':'const std::string&'
 }
@@ -462,8 +463,7 @@ def gen_function_binding_with_wrapper(self, func, class_info):
                     ret_type = type_dict[ptr_type]
```

Review comment:
Keep existed coding style. Please remove the comment as it doesn't help and just confuse readers.
**File:** modules/js/test/test_objdetect.js
**Change Type:** modified
**Context:** PR #19284: Add QRCodeDetector to JavaScript Build

**Code Changes:**
```diff
@@ -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);
+
```

Review comment:
Avoid unnecessary changes (here and below)
**File:** modules/js/test/test_objdetect.js
**Change Type:** modified
**Context:** PR #19284: Add QRCodeDetector to JavaScript Build

**Code Changes:**
```diff
@@ -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);
+
```

Review comment:
Does it work in Node.JS ?
**File:** doc/js_tutorials/js_setup/js_setup/js_setup.markdown
**Change Type:** modified
**Context:** PR #19284: Add QRCodeDetector to JavaScript Build

**Code Changes:**
```diff
@@ -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
```

Review comment:
Did i get you right, that the tests for the `QRCodeDetector` should be skipped when the enviroment variable `OPENCV_TEST_DATA_PATH` is not set? Because the tests depend on two files from the `opencv_extra` repository.