nareshmlx/opencv-pr huggingface dataset:
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #21036: dnn: TIM-VX NPU backend support
**Review Line:** 99

**Code Changes:**
```diff
@@ -95,7 +96,8 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_FPGA,  //!< FPGA device with CPU fallbacks using Inference Engine's Heterogeneous plugin.
         DNN_TARGET_CUDA,
         DNN_TARGET_CUDA_FP16,
-        DNN_TARGET_HDDL
+        DNN_TARGET_HDDL,
+        DNN_TARGET_NPU,
     };
 
     CV_EXPORTS std::vector< std::pair<Backend, Target> > getAvailableBackends();
@@ -321,6 +323,19 @@ CV__DNN_INLINE_NS_BEGIN
```

Review comment:
Enum additions should go to the end.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #21036: dnn: TIM-VX NPU backend support

**Code Changes:**
```diff
@@ -75,6 +75,7 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_BACKEND_VKCOM,
         DNN_BACKEND_CUDA,
         DNN_BACKEND_WEBNN,
+        DNN_BACKEND_TIMVX,
 #ifdef __OPENCV_BUILD
         DNN_BACKEND_INFERENCE_ENGINE_NGRAPH = 1000000,     // internal - use DNN_BACKEND_INFERENCE_ENGINE + setInferenceEngineBackendType()
         DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019,      // internal - use DNN_BACKEND_INFERENCE_ENGINE + setInferenceEngineBackendType()
@@ -95,7 +96,8 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_FPGA,  //!< FPGA device with CPU fallbacks using Inference Engine's Heterogeneous plugin.
```

Review comment:
wrong addition
**File:** modules/dnn/src/int8layers/convolution_layer.cpp
**Change Type:** modified
**Context:** PR #21036: dnn: TIM-VX NPU backend support

**Code Changes:**
```diff
@@ -9,6 +9,7 @@
 
 #include "opencv2/core/hal/hal.hpp"
 #include "opencv2/core/hal/intrin.hpp"
+#include "../op_timvx.hpp"
 #include <iostream>
 #include <numeric>
 
@@ -46,6 +47,7 @@ class BaseConvolutionLayerInt8Impl : public ConvolutionLayerInt8
         int ngroups = params.get<int>("group", 1);
```

Review comment:
remove unnecessary changes
**File:** modules/dnn/src/op_timvx.cpp
**Change Type:** added
**Context:** PR #21036: dnn: TIM-VX NPU backend support

**Code Changes:**
```diff
@@ -0,0 +1,931 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+//
+// Copyright (C) 2019-2021, Shenzhen Institute of Artificial Intelligence and
+// Robotics for Society, all rights reserved.
+// Third party copyrights are property of their respective owners.
+
+#include "precomp.hpp"
```

Review comment:
> 0 we don't need magic numbers here. Use CV_8U directly.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #21036: dnn: TIM-VX NPU backend support
**Review Line:** 99

**Code Changes:**
```diff
@@ -95,7 +96,8 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_FPGA,  //!< FPGA device with CPU fallbacks using Inference Engine's Heterogeneous plugin.
         DNN_TARGET_CUDA,
         DNN_TARGET_CUDA_FP16,
-        DNN_TARGET_HDDL
+        DNN_TARGET_HDDL,
+        DNN_TARGET_NPU,
     };
 
     CV_EXPORTS std::vector< std::pair<Backend, Target> > getAvailableBackends();
@@ -321,6 +323,19 @@ CV__DNN_INLINE_NS_BEGIN
```

Review comment:
This comment is about TARGET, not BACKEND. Requirement of addition to the end comes from preserving values of already existed enum items.
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #21036: dnn: TIM-VX NPU backend support
**Review Line:** 99

**Code Changes:**
```diff
@@ -95,7 +96,8 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_FPGA,  //!< FPGA device with CPU fallbacks using Inference Engine's Heterogeneous plugin.
         DNN_TARGET_CUDA,
         DNN_TARGET_CUDA_FP16,
-        DNN_TARGET_HDDL
+        DNN_TARGET_HDDL,
+        DNN_TARGET_NPU,
     };
 
     CV_EXPORTS std::vector< std::pair<Backend, Target> > getAvailableBackends();
@@ -321,6 +323,19 @@ CV__DNN_INLINE_NS_BEGIN
```

Review comment:
In BACKEND put to the end before `#ifdef __OPENCV_BUILD`
**File:** modules/dnn/include/opencv2/dnn/dnn.hpp
**Change Type:** modified
**Context:** PR #21036: dnn: TIM-VX NPU backend support
**Review Line:** 99

**Code Changes:**
```diff
@@ -95,7 +96,8 @@ CV__DNN_INLINE_NS_BEGIN
         DNN_TARGET_FPGA,  //!< FPGA device with CPU fallbacks using Inference Engine's Heterogeneous plugin.
         DNN_TARGET_CUDA,
         DNN_TARGET_CUDA_FP16,
-        DNN_TARGET_HDDL
+        DNN_TARGET_HDDL,
+        DNN_TARGET_NPU,
     };
 
     CV_EXPORTS std::vector< std::pair<Backend, Target> > getAvailableBackends();
@@ -321,6 +323,19 @@ CV__DNN_INLINE_NS_BEGIN
```

Review comment:
Thank your reply, got it.
**File:** 3rdparty/libtim-vx/tim-vx.cmake
**Change Type:** added
**Context:** PR #21036: dnn: TIM-VX NPU backend support

**Code Changes:**
```diff
@@ -0,0 +1,73 @@
+set(TIMVX_COMMIT_HASH "1d9c7ab941b3d8d9c4d28d80058402725731e3d6")
+set(OCV_TIMVX_DIR "${OpenCV_BINARY_DIR}/3rdparty/libtim-vx")
+set(OCV_TIMVX_SOURCE_PATH "${OCV_TIMVX_DIR}/TIM-VX-${TIMVX_COMMIT_HASH}")
+
+# Download TIM-VX source code
+if(EXISTS "${OCV_TIMVX_SOURCE_PATH}")
+    message(STATUS "TIM-VX: Use cache of TIM-VX source code at ${OCV_TIMVX_SOURCE_PATH}")
+    set(TIMVX_FOUND ON)
+else()
```

Review comment:
Do we have a cleaner way to override the `BUILD_SHARED_LIBS` var in TIMVX's CMakeLists.txt?
**File:** 3rdparty/libtim-vx/tim-vx.cmake
**Change Type:** added
**Context:** PR #21036: dnn: TIM-VX NPU backend support

**Code Changes:**
```diff
@@ -0,0 +1,73 @@
+set(TIMVX_COMMIT_HASH "1d9c7ab941b3d8d9c4d28d80058402725731e3d6")
+set(OCV_TIMVX_DIR "${OpenCV_BINARY_DIR}/3rdparty/libtim-vx")
+set(OCV_TIMVX_SOURCE_PATH "${OCV_TIMVX_DIR}/TIM-VX-${TIMVX_COMMIT_HASH}")
+
+# Download TIM-VX source code
+if(EXISTS "${OCV_TIMVX_SOURCE_PATH}")
+    message(STATUS "TIM-VX: Use cache of TIM-VX source code at ${OCV_TIMVX_SOURCE_PATH}")
+    set(TIMVX_FOUND ON)
+else()
```

Review comment:
Fixed with replacing source of TIM-VX to my own fork. Also `ocv_install` is moved to my fork.
**File:** 3rdparty/libtim-vx/tim-vx.cmake
**Change Type:** added
**Context:** PR #21036: dnn: TIM-VX NPU backend support

**Code Changes:**
```diff
@@ -0,0 +1,73 @@
+set(TIMVX_COMMIT_HASH "1d9c7ab941b3d8d9c4d28d80058402725731e3d6")
+set(OCV_TIMVX_DIR "${OpenCV_BINARY_DIR}/3rdparty/libtim-vx")
+set(OCV_TIMVX_SOURCE_PATH "${OCV_TIMVX_DIR}/TIM-VX-${TIMVX_COMMIT_HASH}")
+
+# Download TIM-VX source code
+if(EXISTS "${OCV_TIMVX_SOURCE_PATH}")
+    message(STATUS "TIM-VX: Use cache of TIM-VX source code at ${OCV_TIMVX_SOURCE_PATH}")
+    set(TIMVX_FOUND ON)
+else()
```

Review comment:
`ocv_install_target` is now moved to my fork of TIM-VX. Maybe we can create a branch in the official TIM-VX repo just like `tengine-opencv` in Tengine.
**File:** cmake/OpenCVFindTIMVX.cmake
**Change Type:** added
**Context:** PR #21036: dnn: TIM-VX NPU backend support

**Code Changes:**
```diff
@@ -0,0 +1,69 @@
+set(TIMVX_INSTALL_DIR "" CACHE PATH "Path to libtim-vx installation")
+set(VIVANTE_SDK_DIR "" CACHE PATH "Path to VIVANTE SDK needed by TIM-VX.")
+set(VIVANTE_SDK_LIB_CANDIDATES "OpenVX;VSC;GAL;ArchModelSw;NNArchPerf" CACHE STRING "VIVANTE SDK library candidates")
+
+# Ensure VIVANTE SDK library candidates are present in given search path
+function(find_vivante_sdk_libs _viv_notfound _viv_search_path)
+    foreach(one ${VIVANTE_SDK_LIB_CANDIDATES})
+        #NO_DEFAULT_PATH is used to ensure VIVANTE SDK libs are from one only source
+        find_library(VIV_${one}_LIB ${one} PATHS "${_viv_search_path}/lib" NO_DEFAULT_PATH)
```

Review comment:
This problem is solved by using a version of VIVANTE SDK (https://github.com/VeriSilicon/TIM-VX/releases/download/v1.1.37/x86_64_linux.v6.4.9.ci-prebuild.tgz) which does not require a specific header any more.
**File:** 3rdparty/libtim-vx/tim-vx.cmake
**Change Type:** added
**Context:** PR #21036: dnn: TIM-VX NPU backend support

**Code Changes:**
```diff
@@ -0,0 +1,73 @@
+set(TIMVX_COMMIT_HASH "1d9c7ab941b3d8d9c4d28d80058402725731e3d6")
+set(OCV_TIMVX_DIR "${OpenCV_BINARY_DIR}/3rdparty/libtim-vx")
+set(OCV_TIMVX_SOURCE_PATH "${OCV_TIMVX_DIR}/TIM-VX-${TIMVX_COMMIT_HASH}")
+
+# Download TIM-VX source code
+if(EXISTS "${OCV_TIMVX_SOURCE_PATH}")
+    message(STATUS "TIM-VX: Use cache of TIM-VX source code at ${OCV_TIMVX_SOURCE_PATH}")
+    set(TIMVX_FOUND ON)
+else()
```

Review comment:
We are going to have a discussion with TIM-VX devs to work out a branch in TIM-VX repo for us to use.
**File:** .github/workflows/PR-4.x-ARM64.yaml
**Change Type:** modified
**Context:** PR #21907: Workflow to build and test on ARM64 for 4.x branch

**Code Changes:**
```diff
@@ -1,7 +1,9 @@
 name: PR:4.x ARM64
 
-# TODO: enable pipeline after 4.x update
-on: workflow_dispatch
+on:
+  pull_request:
+    branches:
+      - 4.x
 
```

Review comment:
Could you add opencv_contrib fork check as it is [here](https://github.com/asenyaev/opencv/commit/eca5ec9223ca5e34c064b5a76dac1250a43fafc7#diff-0ca63d0ce204328dcde092d58d84a7987d66e7583ff7597faec248d32119ee6fR168-R180)? It can be done in a separate PR.
**File:** .github/workflows/PR-4.x-ARM64.yaml
**Change Type:** modified
**Context:** PR #21907: Workflow to build and test on ARM64 for 4.x branch

**Code Changes:**
```diff
@@ -1,7 +1,9 @@
 name: PR:4.x ARM64
 
-# TODO: enable pipeline after 4.x update
-on: workflow_dispatch
+on:
+  pull_request:
+    branches:
+      - 4.x
 
```

Review comment:
Why are there no gapi tests?
**File:** .github/workflows/PR-4.x-ARM64.yaml
**Change Type:** modified
**Context:** PR #21907: Workflow to build and test on ARM64 for 4.x branch

**Code Changes:**
```diff
@@ -1,7 +1,9 @@
 name: PR:4.x ARM64
 
-# TODO: enable pipeline after 4.x update
-on: workflow_dispatch
+on:
+  pull_request:
+    branches:
+      - 4.x
 
```

Review comment:
Yes, the check is added.
**File:** .github/workflows/PR-4.x-ARM64.yaml
**Change Type:** modified
**Context:** PR #21907: Workflow to build and test on ARM64 for 4.x branch

**Code Changes:**
```diff
@@ -1,7 +1,9 @@
 name: PR:4.x ARM64
 
-# TODO: enable pipeline after 4.x update
-on: workflow_dispatch
+on:
+  pull_request:
+    branches:
+      - 4.x
 
```

Review comment:
GAPI tests are disabled in the [old pipeline](https://github.com/opencv-cn-ci-bot/opencv-cn-pipelines/blob/306c133eeef2bfefc507dc9d1513e4ed4b9098ee/precommit/ubuntu-20.04-arm64.groovy#L16). Is it okay to turn it on now?
**File:** .github/workflows/PR-4.x-ARM64.yaml
**Change Type:** modified
**Context:** PR #21907: Workflow to build and test on ARM64 for 4.x branch

**Code Changes:**
```diff
@@ -1,7 +1,9 @@
 name: PR:4.x ARM64
 
-# TODO: enable pipeline after 4.x update
-on: workflow_dispatch
+on:
+  pull_request:
+    branches:
+      - 4.x
 
```

Review comment:
G-API was not tested on ARM with BuildBot-based setup and there were a bunch of test failures there. We decided to disable G-API on ARM too. Feel free to try again as a lot if test failures have been fixed for the last year.
**File:** .github/workflows/PR-4.x-ARM64.yaml
**Change Type:** modified
**Context:** PR #21907: Workflow to build and test on ARM64 for 4.x branch

**Code Changes:**
```diff
@@ -1,7 +1,9 @@
 name: PR:4.x ARM64
 
-# TODO: enable pipeline after 4.x update
-on: workflow_dispatch
+on:
+  pull_request:
+    branches:
+      - 4.x
 
```

Review comment:
GAPI tests are enabled. Lets see what happens.
**File:** modules/core/perf/opencl/perf_matop.cpp
**Change Type:** modified
**Context:** PR #21937: Fix warnings for clang15
**Review Line:** 236

**Code Changes:**
```diff
@@ -233,6 +233,7 @@ PERF_TEST_P_(OpenCLBuffer, cpu_read)
             for (size_t x_bytes = 0; x_bytes < width_bytes; x_bytes++)
                 counter += (unsigned)(ptr[x_bytes]);
         }
+        (void)counter; // To avoid -Wunused-but-set-variable
     }
 
     SANITY_CHECK_NOTHING();
```

Review comment:
You can remove counter at all, I believe.
**File:** modules/core/src/trace.cpp
**Change Type:** modified
**Context:** PR #21937: Fix warnings for clang15

**Code Changes:**
```diff
@@ -988,15 +988,13 @@ void parallelForFinalize(const Region& rootRegion)
     std::vector<TraceManagerThreadLocal*> threads_ctx;
     getTraceManager().tls.gather(threads_ctx);
     RegionStatistics parallel_for_stat;
-    int threads = 0;
     for (size_t i = 0; i < threads_ctx.size(); i++)
     {
         TraceManagerThreadLocal* child_ctx = threads_ctx[i];
 
         if (child_ctx && child_ctx->stackTopRegion() == &rootRegion)
```

Review comment:
It looks like `threads` variable is useless and can be removed.
**File:** modules/3d/src/pointcloud/utils.hpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,65 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#ifndef _CODERS_UTILS_H_
+#define _CODERS_UTILS_H_
+
+#include <string>
+#include <vector>
```

Review comment:
Compile-time check should be used instead of runtime check. See `WORDS_BIGENDIAN`.
**File:** modules/3d/include/opencv2/3d.hpp
**Change Type:** modified
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -2588,6 +2588,60 @@ class CV_EXPORTS Octree {
     Ptr<Impl> p;
 };
 
+
+/** @brief Loads a point cloud from a file.
+*
+* The function loads point cloud from the specified file and returns it.
+* If the cloud cannot be read, throws an error
+*
```

Review comment:
The function name is redundant here. The description is always placed with function signature in html and source code.
**File:** modules/3d/src/pointcloud/load_point_cloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,199 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include "../precomp.hpp"
+
+#include "io_base.hpp"
+#include "io_obj.hpp"
+#include "io_ply.hpp"
```

Review comment:
".OBJ" and ".PLY should work too."
**File:** modules/3d/src/pointcloud/load_point_cloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud
**Review Line:** 67

**Code Changes:**
```diff
+    decoder->setSource(filename);
+
+    std::vector<Point3f> vec_vertices;
+    std::vector<Point3f> vec_normals;
+
+    decoder->readData(vec_vertices, vec_normals);
+
+    if (!vec_vertices.empty())
+        Mat(static_cast<int>(vec_vertices.size()), 1, CV_32FC3, &vec_vertices[0]).copyTo(vertices);
+
+    if (!vec_normals.empty() && normals.needed())
```

Review comment:
`readData` throws exceptions with `CV_Error` macro. It means that function just falis each time when file was not open/empty/etc. It's against your function description (fail-safe execution and empty arrays as output).
**File:** modules/3d/test/test_pointcloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,186 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include <opencv2/core.hpp>
+#include <vector>
+#include <cstdio>
+
+#include "test_precomp.hpp"
```

Review comment:
`EXPECT_TRUE`?
**File:** modules/3d/test/test_pointcloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud
**Review Line:** 95

**Code Changes:**
```diff
+
+    auto folder = cvtest::TS::ptr()->get_data_path();
+    std::string new_path = tempfile("new.ply");
+
+    cv::loadPointCloud(folder + "pointcloudio/orig.ply", points, normals);
+    cv::savePointCloud(new_path, points, normals);
+
+    std::vector<cv::Point3f> points_gold;
+    std::vector<cv::Point3f> normals_gold;
+
+    cv::loadPointCloud(new_path, points_gold, normals_gold);
```

Review comment:
It's bad idea to save things to OPENCV_TEST_DATA_PATH location: - It confuses git. Developer can commit intermediate state by mistake - In case of intermediate function failure the test always reads old file and indicates wrong PASS. Please take a look on `cv::FileStorage` tests in core. They create temporary files in tmp location with different names and remove them after the test execution.
**File:** modules/3d/test/test_pointcloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,186 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include <opencv2/core.hpp>
+#include <vector>
+#include <cstdio>
+
+#include "test_precomp.hpp"
```

Review comment:
What if there are no normals in obj file? It should be tested too.
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud
**Review Line:** 28

**Code Changes:**
```diff
+Practice
+-------
+
+Loading and saving of point cloud can be done using `cv::loadPointCloud` and `cv::savePointCloud` accordingly.
+
+Currently supported formats are:
+- [.OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file) (supported keys are v(which is responsible for point position), vn(normal coordinates) and f(faces of a mesh), other keys are ignored)
+- [.PLY](https://en.wikipedia.org/wiki/PLY_(file_format)) (all encoding types(ascii and byte) are supported with limitation to only float type for data)
+
+@code{.py}
+vertices, normals = cv2.loadPointCloud("teapot.obj")
```

Review comment:
add more info about internal supported and ignored parameters (vn, v etc.). info about endian\ascii etc
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,75 @@
+Point cloud visualisation {#tutorial_point_cloud}
+==============================
+
+|    |    |
+| -: | :- |
+| Original author | Dmitrii Klepikov |
+| Compatibility | OpenCV >= 5.0 |
+
+Goal
```

Review comment:
what exactly returned? vector of points of float etc.
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,75 @@
+Point cloud visualisation {#tutorial_point_cloud}
+==============================
+
+|    |    |
+| -: | :- |
+| Original author | Dmitrii Klepikov |
+| Compatibility | OpenCV >= 5.0 |
+
+Goal
```

Review comment:
.astype(np.float32)
**File:** modules/3d/src/pointcloud/load_point_cloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud
**Review Line:** 62

**Code Changes:**
```diff
+        String file_ext = getExtension(filename);
+        CV_LOG_ERROR(NULL, "File extension '" << file_ext << "' is not supported");
+        return;
+    }
+
+    decoder->setSource(filename);
+
+    std::vector<Point3f> vec_vertices;
+    std::vector<Point3f> vec_normals;
+
+    decoder->readData(vec_vertices, vec_normals);
```

Review comment:
check decoder on nullptr
**File:** modules/3d/src/pointcloud/utils.hpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,65 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#ifndef _CODERS_UTILS_H_
+#define _CODERS_UTILS_H_
+
+#include <string>
+#include <vector>
```

Review comment:
you don't use it
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,75 @@
+Point cloud visualisation {#tutorial_point_cloud}
+==============================
+
+|    |    |
+| -: | :- |
+| Original author | Dmitrii Klepikov |
+| Compatibility | OpenCV >= 5.0 |
+
+Goal
```

Review comment:
compile >> in cmake while building OpenCV from source.
**File:** modules/3d/src/pointcloud/load_point_cloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,199 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include "../precomp.hpp"
+
+#include "io_base.hpp"
+#include "io_obj.hpp"
+#include "io_ply.hpp"
```

Review comment:
check on nullptr too
**File:** modules/3d/src/pointcloud/utils.hpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,65 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#ifndef _CODERS_UTILS_H_
+#define _CODERS_UTILS_H_
+
+#include <string>
+#include <vector>
```

Review comment:
repeat from line 21
**File:** modules/3d/test/test_pointcloud.cpp
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud
**Review Line:** 184

**Code Changes:**
```diff
+    std::vector<cv::Point3f> points;
+    std::vector<cv::Point3f> normals;
+
+    auto folder = cvtest::TS::ptr()->get_data_path();
+    cv::savePointCloud(folder + "pointcloudio/fake.fake", points, normals);
+}
+
+}} /* namespace opencv_test */
```

Review comment:
add tests for mesh functions too
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,75 @@
+Point cloud visualisation {#tutorial_point_cloud}
+==============================
+
+|    |    |
+| -: | :- |
+| Original author | Dmitrii Klepikov |
+| Compatibility | OpenCV >= 5.0 |
+
+Goal
```

Review comment:
Name usually comes first in English. It's better to write `Dmitrii Klepikov` to exclude confuses in emails and other communication.
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud
**Review Line:** 33

**Code Changes:**
```diff
+Currently supported formats are:
+- [.OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file) (supported keys are v(which is responsible for point position), vn(normal coordinates) and f(faces of a mesh), other keys are ignored)
+- [.PLY](https://en.wikipedia.org/wiki/PLY_(file_format)) (all encoding types(ascii and byte) are supported with limitation to only float type for data)
+
+@code{.py}
+vertices, normals = cv2.loadPointCloud("teapot.obj")
+@endcode
+
+Function `cv::loadPointCloud` returns vector of points of float (`cv::Point3f`) and vector of their normals(if specified in source file).
+To visualize it you can use functions from viz3d module and it is needed to reinterpret data into another format
+
```

Review comment:
I recommend to use code substitution from example python file as it's done in `tutorials/imgproc/histograms/back_projection/back_projection.markdown` and `python/tutorial_code/Histograms_Matching/back_projection/calcBackProject_Demo1.py`. The samples code is checked with CI and is always "buildable" with the library.
**File:** doc/tutorials/3d/point_cloud/point_cloud.markdown
**Change Type:** added
**Context:** PR #20471: GSoC module to save and load point cloud

**Code Changes:**
```diff
@@ -0,0 +1,75 @@
+Point cloud visualisation {#tutorial_point_cloud}
+==============================
+
+|    |    |
+| -: | :- |
+| Original author | Dmitrii Klepikov |
+| Compatibility | OpenCV >= 5.0 |
+
+Goal
```

Review comment:
Please use \` \` for function and type names. Doxygen ads links for them to API reference.