nareshmlx/opencv-pr huggingface dataset:
**File:** modules/dnn/src/tensorflow/tf_importer.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -64,16 +64,6 @@ static int toNCDHW(int idx)
     else return (5 + idx) % 4 + 1;
 }
 
-// This values are used to indicate layer output's data layout where it's possible.
-enum DataLayout
-{
-    DATA_LAYOUT_NHWC,
-    DATA_LAYOUT_NCHW,
-    DATA_LAYOUT_NDHWC,
```

Review comment:
The `enum DataLayout` in `dnn.hpp` conflict with the same enum in `tf_importer.cpp` and `tflite_importer.cpp` Change the name from `DataLayout` to `DataLayoutTF` to handle this issue.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -108,6 +108,21 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_NPU,
     };
 
+    /**
+     * @brief Enum of data layout for model inference.
+     * @see Image2BlobParams
+     */
+    enum DataLayout
+    {
```

Review comment:
> `Image2BlobParams` fixed.
**File:** modules/dnn/src/tensorflow/tf_importer.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -64,16 +64,6 @@ static int toNCDHW(int idx)
     else return (5 + idx) % 4 + 1;
 }
 
-// This values are used to indicate layer output's data layout where it's possible.
-enum DataLayout
-{
-    DATA_LAYOUT_NHWC,
-    DATA_LAYOUT_NCHW,
-    DATA_LAYOUT_NDHWC,
```

Review comment:
I'm against of introducing another data type. Let's reuse DataLayout enumeration
**File:** modules/dnn/src/tflite/tflite_importer.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -22,18 +22,6 @@ CV__DNN_INLINE_NS_BEGIN
 
 using namespace opencv_tflite;
 
-// This values are used to indicate layer output's data layout where it's possible.
-// Approach is similar to TensorFlow importer but TFLite models do not have explicit
-// layout field "data_format". So we consider that all 4D inputs are in NHWC data layout.
-enum DataLayout
-{
-    DATA_LAYOUT_NHWC,
```

Review comment:
let's reuse DataLayout
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -108,6 +108,21 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_NPU,
     };
 
+    /**
+     * @brief Enum of data layout for model inference.
+     * @see Image2BlobParams
+     */
+    enum DataLayout
+    {
```

Review comment:
spase before final dot.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -108,6 +108,21 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_NPU,
     };
 
+    /**
+     * @brief Enum of data layout for model inference.
+     * @see Image2BlobParams
+     */
+    enum DataLayout
+    {
```

Review comment:
Extra bracket at the end of the line.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -108,6 +108,21 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_NPU,
     };
 
+    /**
+     * @brief Enum of data layout for model inference.
+     * @see Image2BlobParams
+     */
+    enum DataLayout
+    {
```

Review comment:
I propose to describe default behavior: resize to required input size without presuming aspect ratio.
**File:** modules/dnn/test/test_misc.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam
**Review Line:** 71

**Code Changes:**
```diff
+TEST(blobFromImageWithParams_4ch, NHWC_scalar_scale)
+{
+    Mat img(10, 10, CV_8UC4, cv::Scalar(0,1,2,3));
+    std::vector<double> factorVec = {0.1, 0.2, 0.3, 0.4};
+
+    Scalar scalefactor(factorVec[0], factorVec[1], factorVec[2], factorVec[3]);
+
+    Image2BlobParams param;
+    param.scalefactor = scalefactor;
+    param.datalayout = DNN_LAYOUT_NHWC;
+    Mat blob = dnn::blobFromImageWithParams(img, param); // [1, 10, 10, 4]
```

Review comment:
You do not need `std::vector<double>`, you can just initialize `Scalar scalefactor(0.1, 0.2, 0.3, 0.4);`
**File:** modules/dnn/test/test_misc.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -63,6 +63,63 @@ TEST(imagesFromBlob, Regression)
     }
 }
 
+TEST(blobFromImageWithParams_4ch, NHWC_scalar_scale)
+{
+    Mat img(10, 10, CV_8UC4, cv::Scalar(0,1,2,3));
+    std::vector<double> factorVec = {0.1, 0.2, 0.3, 0.4};
+
+    Scalar scalefactor(factorVec[0], factorVec[1], factorVec[2], factorVec[3]);
```

Review comment:
No need to create plains with the same values. The same may be achieved with Mat img(10, 10, CV_8UC4, cv::Scalar(0,1,2,3)); All Mat pixels are initialized with Scalar value.
**File:** modules/dnn/test/test_misc.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam
**Review Line:** 92

**Code Changes:**
```diff
+            EXPECT_NEAR(hwPtr[0], targetVec[0], 1e-5);
+            EXPECT_NEAR(hwPtr[1], targetVec[1], 1e-5);
+            EXPECT_NEAR(hwPtr[2], targetVec[2], 1e-5);
+            EXPECT_NEAR(hwPtr[3], targetVec[3], 1e-5);
+        }
+    }
+}
+
+TEST(blobFromImageWithParams_4ch, letter_box)
+{
+    Mat img(40, 20, CV_8UC4, cv::Scalar(0,1,2,3));
```

Review comment:
The same idea may be applied here too: ``` cv::Mat expected_target(10, 10, CV_32FC4, cv::Scalar(...)); EXPECT_MAT_NEAR(expected_target, blob, 1e-5); ```
**File:** modules/dnn/test/test_misc.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam
**Review Line:** 71

**Code Changes:**
```diff
+TEST(blobFromImageWithParams_4ch, NHWC_scalar_scale)
+{
+    Mat img(10, 10, CV_8UC4, cv::Scalar(0,1,2,3));
+    std::vector<double> factorVec = {0.1, 0.2, 0.3, 0.4};
+
+    Scalar scalefactor(factorVec[0], factorVec[1], factorVec[2], factorVec[3]);
+
+    Image2BlobParams param;
+    param.scalefactor = scalefactor;
+    param.datalayout = DNN_LAYOUT_NHWC;
+    Mat blob = dnn::blobFromImageWithParams(img, param); // [1, 10, 10, 4]
```

Review comment:
the `factorVec[i]` will be used at the following code.
**File:** modules/dnn/test/test_misc.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam
**Review Line:** 92

**Code Changes:**
```diff
+            EXPECT_NEAR(hwPtr[0], targetVec[0], 1e-5);
+            EXPECT_NEAR(hwPtr[1], targetVec[1], 1e-5);
+            EXPECT_NEAR(hwPtr[2], targetVec[2], 1e-5);
+            EXPECT_NEAR(hwPtr[3], targetVec[3], 1e-5);
+        }
+    }
+}
+
+TEST(blobFromImageWithParams_4ch, letter_box)
+{
+    Mat img(40, 20, CV_8UC4, cv::Scalar(0,1,2,3));
```

Review comment:
I just found that the shape of `cv::Mat expected_target(10, 10, CV_32FC4, cv::Scalar(...));` is different with the output of `blobFromImage`. The main difference is the former is a multi-channel image, while the latter is a multi-dimensional image (channels are moved to dimensions.) I would like to keep the current solution.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -108,6 +108,21 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_NPU,
     };
 
+    /**
+     * @brief Enum of data layout for model inference.
+     * @see Image2BlobParams
+     */
+    enum DataLayout
+    {
```

Review comment:
Not documented item.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -108,6 +108,21 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_NPU,
     };
 
+    /**
+     * @brief Enum of data layout for model inference.
+     * @see Image2BlobParams
+     */
+    enum DataLayout
+    {
```

Review comment:
Difference between `DNN_LAYOUT_NDHWC` and `DNN_LAYOUT_NHWC` is not clear.
**File:** modules/dnn/src/dnn_utils.cpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -11,8 +11,17 @@ namespace cv {
 namespace dnn {
 CV__DNN_INLINE_NS_BEGIN
 
+Image2BlobParams::Image2BlobParams():scalefactor(Scalar::all(1.0)), size(Size()), mean(Scalar()), swapRB(false), ddepth(CV_32F),
+                           datalayout(DNN_LAYOUT_NCHW), paddingmode(DNN_PMODE_NULL)
+{}
 
-Mat blobFromImage(InputArray image, double scalefactor, const Size& size,
+Image2BlobParams::Image2BlobParams(const Scalar& scalefactor_, const Size& size_, const Scalar& mean_, bool swapRB_,
```

Review comment:
The function was renamed from `blobFromImages` to `blobFromImagesWithParams`. No need to presume backward compatibility. I propose to drop the hack.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam

**Code Changes:**
```diff
@@ -108,6 +108,21 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_NPU,
     };
 
+    /**
+     * @brief Enum of data layout for model inference.
+     * @see Image2BlobParams
+     */
+    enum DataLayout
+    {
```

Review comment:
The `NDHWC` is for tensorflow 5D data, like using in conv3d, and the `NHWC` is tensorflow normal 4D data. I will add details documentation for this part code.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #22750: DNN: Add New API blobFromImageParam
**Review Line:** 123

**Code Changes:**
```diff
+        DNN_LAYOUT_ND = 1,        //!< OpenCV data layout for 2D data.
+        DNN_LAYOUT_NCHW = 2,      //!< OpenCV data layout for 4D data.
+        DNN_LAYOUT_NCDHW = 3,      //!< OpenCV data layout for 5D data.
+        DNN_LAYOUT_NHWC = 4,      //!< Tensorflow-like data layout for 4D data.
+        DNN_LAYOUT_NDHWC = 5,      //!< Tensorflow-like data layout for 5D data.
+        DNN_LAYOUT_PLANAR = 6,     //!< Tensorflow-like data layout, it should only be used at tf or tflite model parsing.
+    };
+
     CV_EXPORTS std::vector< std::pair<Backend, Target> > getAvailableBackends();
     CV_EXPORTS_W std::vector<Target> getAvailableTargets(dnn::Backend be);
 
```

Review comment:
final decision from meeting: we keep both of them.
**File:** modules/objdetect/include/opencv2/objdetect/face.hpp
**Change Type:** modified
**Context:** PR #23476: Add notes for the output format of FaceDetectorYN.detect()

**Code Changes:**
```diff
@@ -54,10 +54,20 @@ class CV_EXPORTS_W FaceDetectorYN
 
     CV_WRAP virtual int getTopK() = 0;
 
-    /** @brief A simple interface to detect face from given image
-     *
+    /** @brief Detects faces in the input image. Following is an example output.
+
+     * ![image](pics/lena-face-detection.jpg)
+
```

Review comment:
I propose to add image with landmarks or detailed landmarks description or reference to the original project.
**File:** modules/imgcodecs/test/test_tiff.cpp
**Change Type:** modified
**Context:** PR #23433: imgcodecs: tiff: Support to encode for CV_32S with compression params

**Code Changes:**
```diff
@@ -14,6 +14,38 @@ namespace opencv_test { namespace {
 #define int64 int64_hack_
 #include "tiff.h"
 
+// Re-define Mat type as enum for showing on Google Test.
+enum CV_ddtCn{
+  _CV_8UC1  = CV_8UC1,  _CV_8UC3  = CV_8UC3,  _CV_8UC4  = CV_8UC4,
+  _CV_8SC1  = CV_8SC1,  _CV_8SC3  = CV_8SC3,  _CV_8SC4  = CV_8SC4,
+  _CV_16UC1 = CV_16UC1, _CV_16UC3 = CV_16UC3, _CV_16UC4 = CV_16UC4,
+  _CV_16SC1 = CV_16SC1, _CV_16SC3 = CV_16SC3, _CV_16SC4 = CV_16SC4,
```

Review comment:
It's better to implement it as parameterized test. In case of single option failure, it's more obvious. Also less side effects between iterations. See https://github.com/opencv/opencv/blob/4.x/modules/core/test/test_arithm.cpp#L2216 as example and documentation: http://google.github.io/googletest/reference/testing.html#TEST_P
**File:** modules/imgcodecs/src/grfmt_tiff.cpp
**Change Type:** modified
**Context:** PR #23433: imgcodecs: tiff: Support to encode for CV_32S with compression params

**Code Changes:**
```diff
@@ -63,6 +63,9 @@ using namespace tiff_dummy_namespace;
 namespace cv
 {
 
+// to extend cvtColor() to support CV_8S, CV_16S, CV_32S and CV_64F.
+static void extend_cvtColor( InputArray _src, OutputArray _dst, int code );
+
 #define CV_TIFF_CHECK_CALL(call) \
     if (0 == (call)) { \
         CV_LOG_WARNING(NULL, "OpenCV TIFF(line " << __LINE__ << "): failed " #call); \
```

Review comment:
Please add meaningful message to the assertion.
**File:** modules/imgcodecs/src/grfmt_tiff.cpp
**Change Type:** modified
**Context:** PR #23433: imgcodecs: tiff: Support to encode for CV_32S with compression params
**Review Line:** 1434

**Code Changes:**
```diff
 
@@ -1424,6 +1431,57 @@ bool  TiffEncoder::write( const Mat& img, const std::vector<int>& params)
     return writeLibTiff(img_vec, params);
 }
 
+static void extend_cvtColor( InputArray _src, OutputArray _dst, int code )
+{
+    CV_Assert( !_src.empty() );
+    CV_Assert( _src.dims() == 2 );
+
+    // This function extend_cvtColor reorders the src channels with only thg limited condition.
```

Review comment:
Technically, you can use `cv::split` to decompose the image on planes and cv::merge to assemble them in any order you want. Single piece of code should cover all missing types. In case if, let's say `CV_16S` is mot supported by one if functions, you can cast it it CV_16U, do permutations and cast back.
**File:** modules/imgcodecs/test/test_tiff.cpp
**Change Type:** modified
**Context:** PR #23433: imgcodecs: tiff: Support to encode for CV_32S with compression params

**Code Changes:**
```diff
@@ -14,6 +14,38 @@ namespace opencv_test { namespace {
 #define int64 int64_hack_
 #include "tiff.h"
 
+// Re-define Mat type as enum for showing on Google Test.
+enum CV_ddtCn{
+  _CV_8UC1  = CV_8UC1,  _CV_8UC3  = CV_8UC3,  _CV_8UC4  = CV_8UC4,
+  _CV_8SC1  = CV_8SC1,  _CV_8SC3  = CV_8SC3,  _CV_8SC4  = CV_8SC4,
+  _CV_16UC1 = CV_16UC1, _CV_16UC3 = CV_16UC3, _CV_16UC4 = CV_16UC4,
+  _CV_16SC1 = CV_16SC1, _CV_16SC3 = CV_16SC3, _CV_16SC4 = CV_16SC4,
```

Review comment:
`::zeros()` is not IO operation or subject for test. I do not see reason for the assert.
**File:** modules/imgcodecs/test/test_tiff.cpp
**Change Type:** modified
**Context:** PR #23433: imgcodecs: tiff: Support to encode for CV_32S with compression params

**Code Changes:**
```diff
@@ -14,6 +14,38 @@ namespace opencv_test { namespace {
 #define int64 int64_hack_
 #include "tiff.h"
 
+// Re-define Mat type as enum for showing on Google Test.
+enum CV_ddtCn{
+  _CV_8UC1  = CV_8UC1,  _CV_8UC3  = CV_8UC3,  _CV_8UC4  = CV_8UC4,
+  _CV_8SC1  = CV_8SC1,  _CV_8SC3  = CV_8SC3,  _CV_8SC4  = CV_8SC4,
+  _CV_16UC1 = CV_16UC1, _CV_16UC3 = CV_16UC3, _CV_16UC4 = CV_16UC4,
+  _CV_16SC1 = CV_16SC1, _CV_16SC3 = CV_16SC3, _CV_16SC4 = CV_16SC4,
```

Review comment:
Size and type check are enough. Empty check is redundant.
**File:** modules/imgcodecs/test/test_tiff.cpp
**Change Type:** modified
**Context:** PR #23433: imgcodecs: tiff: Support to encode for CV_32S with compression params

**Code Changes:**
```diff
@@ -14,6 +14,38 @@ namespace opencv_test { namespace {
 #define int64 int64_hack_
 #include "tiff.h"
 
+// Re-define Mat type as enum for showing on Google Test.
+enum CV_ddtCn{
+  _CV_8UC1  = CV_8UC1,  _CV_8UC3  = CV_8UC3,  _CV_8UC4  = CV_8UC4,
+  _CV_8SC1  = CV_8SC1,  _CV_8SC3  = CV_8SC3,  _CV_8SC4  = CV_8SC4,
+  _CV_16UC1 = CV_16UC1, _CV_16UC3 = CV_16UC3, _CV_16UC4 = CV_16UC4,
+  _CV_16SC1 = CV_16SC1, _CV_16SC3 = CV_16SC3, _CV_16SC4 = CV_16SC4,
```

Review comment:
I think it will be OK. https://github.com/Kumataro/opencv/blob/8de13490979ae3f2e2485b123d2df0c1ea2229b6/modules/imgcodecs/test/test_tiff.cpp#L875-L881
**File:** modules/imgcodecs/test/test_tiff.cpp
**Change Type:** modified
**Context:** PR #23433: imgcodecs: tiff: Support to encode for CV_32S with compression params

**Code Changes:**
```diff
@@ -14,6 +14,38 @@ namespace opencv_test { namespace {
 #define int64 int64_hack_
 #include "tiff.h"
 
+// Re-define Mat type as enum for showing on Google Test.
+enum CV_ddtCn{
+  _CV_8UC1  = CV_8UC1,  _CV_8UC3  = CV_8UC3,  _CV_8UC4  = CV_8UC4,
+  _CV_8SC1  = CV_8SC1,  _CV_8SC3  = CV_8SC3,  _CV_8SC4  = CV_8SC4,
+  _CV_16UC1 = CV_16UC1, _CV_16UC3 = CV_16UC3, _CV_16UC4 = CV_16UC4,
+  _CV_16SC1 = CV_16SC1, _CV_16SC3 = CV_16SC3, _CV_16SC4 = CV_16SC4,
```

Review comment:
Some test codes use `src.empty()` to check the result of imread(). https://github.com/opencv/opencv/blob/725e440d278aca07d35a5e8963ef990572b07316/modules/imgcodecs/test/test_tiff.cpp#L570-L576 However I found another way to test imread. I think it is more user-friendly style for others. In New PR, I replaced as this style. https://github.com/opencv/opencv/blob/725e440d278aca07d35a5e8963ef990572b07316/modules/imgcodecs/test/test_tiff.cpp#L683
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #23482: DNN: support the split node of onnx opset >= 13
**Review Line:** 1487

**Code Changes:**
```diff
         DictValue splits = layerParams.get("split");
@@ -1480,13 +1484,26 @@ void ONNXImporter::parseSplit(LayerParams& layerParams, const opencv_onnx::NodeP
         }
         layerParams.set("slice_point", DictValue::arrayInt(&slicePoints[0], slicePoints.size()));
     }
+    else if (node_proto.input_size() == 2) // opset >= 13, the split will be stored at the second input, instead of the attribute.
+    {
+        CV_Assert(constBlobs.find(node_proto.input(1)) != constBlobs.end());
+        Mat splitsBlob = getBlob(node_proto, 1);
+        int splitSize = splitsBlob.total();
+
```

Review comment:
BTW, there `onnx_opset` field to avoid guessing using the number of inputs (that is not reliable).
**File:** modules/dnn/src/onnx/onnx_importer.cpp
**Change Type:** modified
**Context:** PR #23482: DNN: support the split node of onnx opset >= 13
**Review Line:** 1487

**Code Changes:**
```diff
         DictValue splits = layerParams.get("split");
@@ -1480,13 +1484,26 @@ void ONNXImporter::parseSplit(LayerParams& layerParams, const opencv_onnx::NodeP
         }
         layerParams.set("slice_point", DictValue::arrayInt(&slicePoints[0], slicePoints.size()));
     }
+    else if (node_proto.input_size() == 2) // opset >= 13, the split will be stored at the second input, instead of the attribute.
+    {
+        CV_Assert(constBlobs.find(node_proto.input(1)) != constBlobs.end());
+        Mat splitsBlob = getBlob(node_proto, 1);
+        int splitSize = splitsBlob.total();
+
```

Review comment:
Thx for your code review. I agree with you, but currently, I have no better solution for this. Since we can not get the info of `opset` version. And from onnx's doc, the split has only input when the `opset < 13`. https://github.com/onnx/onnx/blob/main/docs/Changelog.md#split-11 And when `opset >= 13`, input may have the second input, and it's used only for `split`. https://github.com/onnx/onnx/blob/main/docs/Operators.md#split.
**File:** cmake/OpenCVDetectCUDA.cmake
**Change Type:** modified
**Context:** PR #17499: Fix cuda11 - ``` force_builders=Custom buildworker:Custom=linux-4 build_image:Custom=ubuntu-cuda11:18.04 Xbuild_image:Custom=ubuntu-cuda11:...
**Review Line:** 31

**Code Changes:**
```diff
@@ -28,6 +28,11 @@ endif()
 
 if(CUDA_FOUND)
   set(HAVE_CUDA 1)
+  if(CUDA_VERSION VERSION_GREATER_EQUAL "11.0")
+    # CUDA 11.0 removes nppicom
+    ocv_list_filterout(CUDA_nppi_LIBRARY "nppicom")
+    ocv_list_filterout(CUDA_npp_LIBRARY "nppicom")
+  endif()
 
```

Review comment:
I don't think it's a good idea to hard code CUDA version here. It may change again in future, and twisting based on version number is just increasing the chaos. Let's filter out the library based on result of helper function.
**File:** cmake/OpenCVDetectCUDA.cmake
**Change Type:** modified
**Context:** PR #17499: Fix cuda11 - ``` force_builders=Custom buildworker:Custom=linux-4 build_image:Custom=ubuntu-cuda11:18.04 Xbuild_image:Custom=ubuntu-cuda11:...

**Code Changes:**
```diff
@@ -28,6 +28,11 @@ endif()
 
 if(CUDA_FOUND)
   set(HAVE_CUDA 1)
+  if(CUDA_VERSION VERSION_GREATER_EQUAL "11.0")
+    # CUDA 11.0 removes nppicom
+    ocv_list_filterout(CUDA_nppi_LIBRARY "nppicom")
+    ocv_list_filterout(CUDA_npp_LIBRARY "nppicom")
+  endif()
 
```

Review comment:
Please try to use [ocv_list_filterout()](https://github.com/opencv/opencv/blob/4.3.0/cmake/OpenCVUtils.cmake#L1050) macro: ``` ocv_list_filterout(CUDA_nppi_LIBRARY "nppicom") ocv_list_filterout(CUDA_npp_LIBRARY "nppicom") ```
**File:** modules/dnn/CMakeLists.txt
**Change Type:** modified
**Context:** PR #17499: Fix cuda11 - ``` force_builders=Custom buildworker:Custom=linux-4 build_image:Custom=ubuntu-cuda11:18.04 Xbuild_image:Custom=ubuntu-cuda11:...
**Review Line:** 25

**Code Changes:**
```diff
   add_definitions(-DCV_OCL4DNN=1)
 endif()
 
-ocv_option(OPENCV_DNN_CUDA "Build with CUDA support" HAVE_CUDA AND HAVE_CUBLAS AND HAVE_CUDNN)
+if(NOT DEFINED OPENCV_DNN_CUDA AND HAVE_CUDNN AND CUDNN_VERSION VERSION_LESS 8.0)
+  message(STATUS "DNN: CUDNN 8.0 is not supported yes. Details: https://github.com/opencv/opencv/issues/17496")
+endif()
+ocv_option(OPENCV_DNN_CUDA "Build with CUDA support"
+    HAVE_CUDA
+    AND HAVE_CUBLAS
+    AND HAVE_CUDNN
```

Review comment:
Yet not yes. There is a typo :)
**File:** modules/dnn/CMakeLists.txt
**Change Type:** modified
**Context:** PR #17499: Fix cuda11 - ``` force_builders=Custom buildworker:Custom=linux-4 build_image:Custom=ubuntu-cuda11:18.04 Xbuild_image:Custom=ubuntu-cuda11:...
**Review Line:** 25

**Code Changes:**
```diff
   add_definitions(-DCV_OCL4DNN=1)
 endif()
 
-ocv_option(OPENCV_DNN_CUDA "Build with CUDA support" HAVE_CUDA AND HAVE_CUBLAS AND HAVE_CUDNN)
+if(NOT DEFINED OPENCV_DNN_CUDA AND HAVE_CUDNN AND CUDNN_VERSION VERSION_LESS 8.0)
+  message(STATUS "DNN: CUDNN 8.0 is not supported yes. Details: https://github.com/opencv/opencv/issues/17496")
+endif()
+ocv_option(OPENCV_DNN_CUDA "Build with CUDA support"
+    HAVE_CUDA
+    AND HAVE_CUBLAS
+    AND HAVE_CUDNN
```

Review comment:
Hopefully this message will be removed soon =)
**File:** modules/core/include/opencv2/core/utility.hpp
**Change Type:** modified
**Context:** PR #22889: core: improve doc for setNumThreads

**Code Changes:**
```diff
@@ -179,11 +179,11 @@ CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback, void* userdat
 CV_EXPORTS String tempfile( const char* suffix = 0);
 CV_EXPORTS void glob(String pattern, std::vector<String>& result, bool recursive = false);
 
-/** @brief OpenCV will try to set the number of threads for the next parallel region.
+/** @brief OpenCV will try to set the number of threads for subsequent parallel regions.
 
-If threads == 0, OpenCV will disable threading optimizations and run all it's functions
-sequentially. Passing threads \< 0 will reset threads number to system default. This function must
-be called outside of parallel region.
```

Review comment:
Proposed change looks good to me. --- However there is another design issue. Which contradicts to the real implementation of some parallel backends. There is mess with `threads == 0` and `threads == 1` values. E.g., OpenMP case: https://github.com/opencv/opencv/blame/913a2dbdaa3fbd011f7d4f08b381deb9dfe43b97/modules/core/src/parallel.cpp#L469 ``` omp_set_num_threads(threads > 0 ? threads : numThreadsMax); ``` (code is from 2012 at least) Docs states this: > If threads == 0, OpenCV will disable threading optimizations and run all it's functions sequentially So, using '0' parameter value is not recommended at all and it is a subject to the change. --- Another important note, `setNumThreads()` is not a thread-safe function. It is fatal to call it simultaneously in case of TBB at least (TBB's arena may become corrupted).