nareshmlx/opencv-pr huggingface dataset:
**File:** 3rdparty/hal_rvv/hal_rvv_1p0/types.hpp
**Change Type:** added
**Context:** PR #26977: [Refactor](HAL RVV): Consolidate Helpers for Code Reusability

**Code Changes:**
```diff
@@ -0,0 +1,485 @@
+// 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.
+#pragma once
+
+#include <riscv_vector.h>
+#include <type_traits>
+
+namespace cv { namespace cv_hal_rvv {
```

Review comment:
I'm really sorry for misunderstanding you again. I thought you were saying that the macro concatenation was too ugly and asked me to split the type name definition. Of course, I also think the macro is ugly, so I’ve now changed the name and also expanded the macro.
**File:** modules/objdetect/test/test_arucodetection.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 658

**Code Changes:**
```diff
+TEST(CV_ArucoMultiDict, setGetDictionaries)
+{
+    vector<aruco::Dictionary> dictionaries = {aruco::getPredefinedDictionary(aruco::DICT_4X4_50), aruco::getPredefinedDictionary(aruco::DICT_5X5_100)};
+    aruco::ArucoDetector detector(dictionaries);
+    vector<aruco::Dictionary> dicts = detector.getDictionaries();
+    ASSERT_EQ(dicts.size(), 2ul);
+    EXPECT_EQ(dicts[0].markerSize, 4);
+    EXPECT_EQ(dicts[1].markerSize, 5);
+    dictionaries.clear();
+    dictionaries.push_back(aruco::getPredefinedDictionary(aruco::DICT_6X6_100));
+    dictionaries.push_back(aruco::getPredefinedDictionary(aruco::DICT_7X7_250));
```

Review comment:
Please add comment to the detector constructor that it uses one of predefined dictionaries by default. Value `2` is not obvious here.
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -285,6 +285,16 @@ class CV_EXPORTS_W ArucoDetector : public Algorithm
                           const DetectorParameters &detectorParams = DetectorParameters(),
                           const RefineParameters& refineParams = RefineParameters());
 
+    /** @brief ArucoDetector constructor for multiple dictionaries
+     *
+     * @param dictionaries indicates the type of markers that will be searched. Empty dictionaries will throw an error.
+     * @param detectorParams marker detection parameters
+     * @param refineParams marker refine detection parameters
+     */
```

Review comment:
size_t does not work well with Java and Python bindings. let's use just int.
**File:** modules/objdetect/test/test_arucodetection.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -6,6 +6,18 @@
 #include "opencv2/objdetect/aruco_detector.hpp"
 #include "opencv2/calib3d.hpp"
 
+namespace cv {
+    namespace aruco {
+        bool operator==(const Dictionary& d1, const Dictionary& d2);
+        bool operator==(const Dictionary& d1, const Dictionary& d2) {
+            return d1.markerSize == d2.markerSize
+                && std::equal(d1.bytesList.begin<Vec<uint8_t, 4>>(), d1.bytesList.end<Vec<uint8_t, 4>>(), d2.bytesList.begin<Vec<uint8_t, 4>>())
```

Review comment:
``` Point2f firstCorner(markerSidePixels / 2.f + x * (1.5f * markerSidePixels), markerSidePixels / 2.f + y * (1.5f * markerSidePixels)); Mat aux = img((int)firstCorner.x, (int)firstCorner.y, markerSidePixels. markerSidePixels); ```
**File:** modules/objdetect/test/test_arucodetection.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -6,6 +6,18 @@
 #include "opencv2/objdetect/aruco_detector.hpp"
 #include "opencv2/calib3d.hpp"
 
+namespace cv {
+    namespace aruco {
+        bool operator==(const Dictionary& d1, const Dictionary& d2);
+        bool operator==(const Dictionary& d1, const Dictionary& d2) {
+            return d1.markerSize == d2.markerSize
+                && std::equal(d1.bytesList.begin<Vec<uint8_t, 4>>(), d1.bytesList.end<Vec<uint8_t, 4>>(), d2.bytesList.begin<Vec<uint8_t, 4>>())
```

Review comment:
I propose to add assertion to `removeDictionary()` call and not allow the case without dictionaries, because we get detector with invalid state and it's definitely a bug.
**File:** modules/objdetect/misc/python/test/test_objdetect_aruco.py
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -458,5 +458,30 @@ def test_draw_detected_diamonds(self):
         with self.assertRaises(Exception):
             img = cv.aruco.drawDetectedDiamonds(img, points2, borderColor=255)
 
+    def test_multi_dict_arucodetector(self):
+        aruco_params = cv.aruco.DetectorParameters()
+        aruco_dicts = [
+                cv.aruco.getPredefinedDictionary(cv.aruco.DICT_4X4_250),
+                cv.aruco.getPredefinedDictionary(cv.aruco.DICT_5X5_250)
+            ]
```

Review comment:
It breaks compatibility. M.b. rename the method to detectMarkersMultiDict?
**File:** modules/objdetect/src/aruco/aruco_detector.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -10,6 +10,7 @@
 #include "apriltag/apriltag_quad_thresh.hpp"
 #include "aruco_utils.hpp"
 #include <cmath>
+#include <map>
 
 namespace cv {
 namespace aruco {
@@ -640,9 +641,14 @@ static inline void findCornerInPyrImage(const float scale_init, const int closes
     }
```

Review comment:
Add `index>= 0` to assert.
**File:** modules/objdetect/src/aruco/aruco_detector.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -10,6 +10,7 @@
 #include "apriltag/apriltag_quad_thresh.hpp"
 #include "aruco_utils.hpp"
 #include <cmath>
+#include <map>
 
 namespace cv {
 namespace aruco {
@@ -640,9 +641,14 @@ static inline void findCornerInPyrImage(const float scale_init, const int closes
     }
```

Review comment:
Add index>= 0 to assert.
**File:** modules/objdetect/src/aruco/aruco_detector.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 1117

**Code Changes:**
```diff
@@ -10,6 +10,7 @@
 #include "apriltag/apriltag_quad_thresh.hpp"
 #include "aruco_utils.hpp"
 #include <cmath>
+#include <map>
 
 namespace cv {
 namespace aruco {
@@ -640,9 +641,14 @@ static inline void findCornerInPyrImage(const float scale_init, const int closes
     }
 }
 
+enum class DictionaryMode {
+    Single,
+    Multi
```

Review comment:
I propose to add `refineDetectedMarkersMultiDict` overload with dictionaries id like in detect. May be useful for multi-scale markers.
**File:** modules/objdetect/misc/python/test/test_objdetect_aruco.py
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -458,5 +458,30 @@ def test_draw_detected_diamonds(self):
         with self.assertRaises(Exception):
             img = cv.aruco.drawDetectedDiamonds(img, points2, borderColor=255)
 
+    def test_multi_dict_arucodetector(self):
+        aruco_params = cv.aruco.DetectorParameters()
+        aruco_dicts = [
+                cv.aruco.getPredefinedDictionary(cv.aruco.DICT_4X4_250),
+                cv.aruco.getPredefinedDictionary(cv.aruco.DICT_5X5_250)
+            ]
```

Review comment:
Unfortunate, but I managed to do create a detectMarkersMultiDict function with relative little redundant code.
**File:** modules/objdetect/src/aruco/aruco_detector.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 1117

**Code Changes:**
```diff
@@ -10,6 +10,7 @@
 #include "apriltag/apriltag_quad_thresh.hpp"
 #include "aruco_utils.hpp"
 #include <cmath>
+#include <map>
 
 namespace cv {
 namespace aruco {
@@ -640,9 +641,14 @@ static inline void findCornerInPyrImage(const float scale_init, const int closes
     }
 }
 
+enum class DictionaryMode {
+    Single,
+    Multi
```

Review comment:
Made sure refine is now looping over the markers and checked the output. Looks like this can be done safely without having to have two functions.
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -285,6 +285,16 @@ class CV_EXPORTS_W ArucoDetector : public Algorithm
                           const DetectorParameters &detectorParams = DetectorParameters(),
                           const RefineParameters& refineParams = RefineParameters());
 
+    /** @brief ArucoDetector constructor for multiple dictionaries
+     *
+     * @param dictionaries indicates the type of markers that will be searched. Empty dictionaries will throw an error.
+     * @param detectorParams marker detection parameters
+     * @param refineParams marker refine detection parameters
+     */
```

Review comment:
1. In my opinion, methods `get(set)Dictionary`, `add(remove)Dictionary` are redundant. It is enough to have `get(set)Dictionaries`. Perhaps it would be better to preserve old `get(set)Dictionary`, so that they would return the first one. 2. Is it safe to return reference to internal vector in method `getDictionaries`? Maybe it would be better to return a copy. 3. What about corner cases: empty vector, duplicates? 4. Methods should be documented.
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 373

**Code Changes:**
```diff
+     * Note that this function does not perform pose estimation.
+     * @note The function does not correct lens distortion or takes it into account. It's recommended to undistort
+     * input image with corresponding camera model, if camera parameters are known
+     * @sa undistort, estimatePoseSingleMarkers,  estimatePoseBoard
+     */
+    CV_WRAP void detectMarkersMultiDict(InputArray image, OutputArrayOfArrays corners, OutputArray ids,
+                               OutputArrayOfArrays rejectedImgPoints = noArray(), OutputArray dictIndices = noArray()) const;
+
+    /** @brief Returns first dictionary from internal list used for marker detection.
+     *
+     * @return The first dictionary from the configured ArucoDetector.
```

Review comment:
Wouldn't it be more convenient to modify Dictionary class, so that it would be able to combine several dictionaries underneath. It could also handle duplicate markers and provide convenient indexing. Detector interface would stay the same and users would require minimal changes in their code.
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 373

**Code Changes:**
```diff
+     * Note that this function does not perform pose estimation.
+     * @note The function does not correct lens distortion or takes it into account. It's recommended to undistort
+     * input image with corresponding camera model, if camera parameters are known
+     * @sa undistort, estimatePoseSingleMarkers,  estimatePoseBoard
+     */
+    CV_WRAP void detectMarkersMultiDict(InputArray image, OutputArrayOfArrays corners, OutputArray ids,
+                               OutputArrayOfArrays rejectedImgPoints = noArray(), OutputArray dictIndices = noArray()) const;
+
+    /** @brief Returns first dictionary from internal list used for marker detection.
+     *
+     * @return The first dictionary from the configured ArucoDetector.
```

Review comment:
Not a bad idea, but the Dictionary class is also used for these calibration boards and the Charuco stuff as well. Its public members (`errorCorrection`, `markerSize`, `bytesList`) would all need to change because they would be ambiguous. Just from a quick check I think such a change would be more disruptive than the interface change suggested in this PR.
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 373

**Code Changes:**
```diff
+     * Note that this function does not perform pose estimation.
+     * @note The function does not correct lens distortion or takes it into account. It's recommended to undistort
+     * input image with corresponding camera model, if camera parameters are known
+     * @sa undistort, estimatePoseSingleMarkers,  estimatePoseBoard
+     */
+    CV_WRAP void detectMarkersMultiDict(InputArray image, OutputArrayOfArrays corners, OutputArray ids,
+                               OutputArrayOfArrays rejectedImgPoints = noArray(), OutputArray dictIndices = noArray()) const;
+
+    /** @brief Returns first dictionary from internal list used for marker detection.
+     *
+     * @return The first dictionary from the configured ArucoDetector.
```

Review comment:
> I think such a change would be more disruptive than the interface change suggested in this PR. Agree and support
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 373

**Code Changes:**
```diff
+     * Note that this function does not perform pose estimation.
+     * @note The function does not correct lens distortion or takes it into account. It's recommended to undistort
+     * input image with corresponding camera model, if camera parameters are known
+     * @sa undistort, estimatePoseSingleMarkers,  estimatePoseBoard
+     */
+    CV_WRAP void detectMarkersMultiDict(InputArray image, OutputArrayOfArrays corners, OutputArray ids,
+                               OutputArrayOfArrays rejectedImgPoints = noArray(), OutputArray dictIndices = noArray()) const;
+
+    /** @brief Returns first dictionary from internal list used for marker detection.
+     *
+     * @return The first dictionary from the configured ArucoDetector.
```

Review comment:
We already have function `extendDictionary` which adds randomized markers to the existing dictionary, so I believe creating similar function to combine several dictionaries with the same marker size would be quite easy. Or do we need to have dictionaries with different marker sizes?
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -285,6 +285,16 @@ class CV_EXPORTS_W ArucoDetector : public Algorithm
                           const DetectorParameters &detectorParams = DetectorParameters(),
                           const RefineParameters& refineParams = RefineParameters());
 
+    /** @brief ArucoDetector constructor for multiple dictionaries
+     *
+     * @param dictionaries indicates the type of markers that will be searched. Empty dictionaries will throw an error.
+     * @param detectorParams marker detection parameters
+     * @param refineParams marker refine detection parameters
+     */
```

Review comment:
1. Old get/setDictionary API would work, yes. But ABI compatibility would be broken. Can we avoid it? 2. No I meant safety in terms of exposing internal structure. For example it allows user to create iterator which might become invalid suddenly. Also we won't be able to change internal data structure. 3. Each access function must be tested for possible errors then.
**File:** modules/objdetect/src/aruco/aruco_detector.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 1386

**Code Changes:**
```diff
 }
 
-void ArucoDetector::write(FileStorage &fs) const
-{
-    arucoDetectorImpl->dictionary.writeDictionary(fs);
+void ArucoDetector::write(FileStorage &fs) const {
+    // preserve old format for single dictionary case
+    if (1 == arucoDetectorImpl->dictionaries.size()) {
+        arucoDetectorImpl->dictionaries[0].writeDictionary(fs);
+    } else {
+        fs << "dictionaries" << "[";
```

Review comment:
I believe (de)serialization is not tested. Is old format supported? I.e. if we have just one dictionary, would older versions of OpenCV be able to read it?
**File:** modules/objdetect/src/aruco/aruco_detector.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 1386

**Code Changes:**
```diff
 }
 
-void ArucoDetector::write(FileStorage &fs) const
-{
-    arucoDetectorImpl->dictionary.writeDictionary(fs);
+void ArucoDetector::write(FileStorage &fs) const {
+    // preserve old format for single dictionary case
+    if (1 == arucoDetectorImpl->dictionaries.size()) {
+        arucoDetectorImpl->dictionaries[0].writeDictionary(fs);
+    } else {
+        fs << "dictionaries" << "[";
```

Review comment:
True, I couldn't find a unit test for it, but I tested it locally. I can clean the code up and add it as a test. I made sure it could read the old format, but it wouldn't produce the old format if there's only one dictionary. I'll add that, so both read and write support the old format if there is only on dict.
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 373

**Code Changes:**
```diff
+     * Note that this function does not perform pose estimation.
+     * @note The function does not correct lens distortion or takes it into account. It's recommended to undistort
+     * input image with corresponding camera model, if camera parameters are known
+     * @sa undistort, estimatePoseSingleMarkers,  estimatePoseBoard
+     */
+    CV_WRAP void detectMarkersMultiDict(InputArray image, OutputArrayOfArrays corners, OutputArray ids,
+                               OutputArrayOfArrays rejectedImgPoints = noArray(), OutputArray dictIndices = noArray()) const;
+
+    /** @brief Returns first dictionary from internal list used for marker detection.
+     *
+     * @return The first dictionary from the configured ArucoDetector.
```

Review comment:
At least for the use case we have in mind you would want to scan dictionaries of different marker sizes, yes.
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -285,6 +285,16 @@ class CV_EXPORTS_W ArucoDetector : public Algorithm
                           const DetectorParameters &detectorParams = DetectorParameters(),
                           const RefineParameters& refineParams = RefineParameters());
 
+    /** @brief ArucoDetector constructor for multiple dictionaries
+     *
+     * @param dictionaries indicates the type of markers that will be searched. Empty dictionaries will throw an error.
+     * @param detectorParams marker detection parameters
+     * @param refineParams marker refine detection parameters
+     */
```

Review comment:
1. Alright, I've updated the PR to keep the behavior of the set/get functions and the ABI the same. 2. Yeah, good point with the iterators. I make it return a copy now. 3. I think I had tests already, but since you asked about it earlier, the most current version now has no add/remove functions and thus it's a lot easier to use and also easier to test. I hope this addresses all the concerns. I left a bit of documentation for the set/getDictionary functions so it's clear what they do with the dictionaries list.
**File:** modules/objdetect/src/aruco/aruco_detector.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -10,6 +10,7 @@
 #include "apriltag/apriltag_quad_thresh.hpp"
 #include "aruco_utils.hpp"
 #include <cmath>
+#include <map>
 
 namespace cv {
 namespace aruco {
@@ -640,9 +641,14 @@ static inline void findCornerInPyrImage(const float scale_init, const int closes
     }
```

Review comment:
Why not regular `std::set`?
**File:** modules/objdetect/test/test_arucodetection.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -6,6 +6,18 @@
 #include "opencv2/objdetect/aruco_detector.hpp"
 #include "opencv2/calib3d.hpp"
 
+namespace cv {
+    namespace aruco {
+        bool operator==(const Dictionary& d1, const Dictionary& d2);
+        bool operator==(const Dictionary& d1, const Dictionary& d2) {
+            return d1.markerSize == d2.markerSize
+                && std::equal(d1.bytesList.begin<Vec<uint8_t, 4>>(), d1.bytesList.end<Vec<uint8_t, 4>>(), d2.bytesList.begin<Vec<uint8_t, 4>>())
```

Review comment:
Please use `cv::tempfile` for file name and make sure file is removed using `remove` at the end (no `ASSERT_` can be used). Alternatively you can try to use in-memory storage: https://github.com/opencv/opencv/blob/dbd3ef9a6f838d3ac42f8cf4d9d1dd5c709cb807/modules/features2d/test/test_matchers_algorithmic.cpp#L591-L595
**File:** modules/objdetect/test/test_arucodetection.cpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.

**Code Changes:**
```diff
@@ -6,6 +6,18 @@
 #include "opencv2/objdetect/aruco_detector.hpp"
 #include "opencv2/calib3d.hpp"
 
+namespace cv {
+    namespace aruco {
+        bool operator==(const Dictionary& d1, const Dictionary& d2);
+        bool operator==(const Dictionary& d1, const Dictionary& d2) {
+            return d1.markerSize == d2.markerSize
+                && std::equal(d1.bytesList.begin<Vec<uint8_t, 4>>(), d1.bytesList.end<Vec<uint8_t, 4>>(), d2.bytesList.begin<Vec<uint8_t, 4>>())
```

Review comment:
Failure to open file should become test failure. Here and in other places.
**File:** modules/objdetect/include/opencv2/objdetect/aruco_detector.hpp
**Change Type:** modified
**Context:** PR #26934: Extend ArUcoDetector to run multiple dictionaries in an efficient manner.
**Review Line:** 365

**Code Changes:**
```diff
+     * @param rejectedImgPoints contains the imgPoints of those squares whose inner code has not a
+     * correct codification. Useful for debugging purposes.
+     * @param dictIndices vector of dictionary indices for each detected marker. Use getDictionaries() to get the
+     * list of corresponding dictionaries.
+     *
+     * Performs marker detection in the input image. Only markers included in the specific dictionaries
+     * are searched. For each detected marker, it returns the 2D position of its corner in the image
+     * and its corresponding identifier.
+     * Note that this function does not perform pose estimation.
+     * @note The function does not correct lens distortion or takes it into account. It's recommended to undistort
+     * input image with corresponding camera model, if camera parameters are known
```

Review comment:
Perhaps it would be useful to define and test behavior in case when several dictionaries contain same markers.