Make sure serialization with single dict preserves old behavior

This commit is contained in:
Benjamin Knecht 2025-02-24 17:33:09 +01:00
parent 3c88a001a2
commit 6c3b195a57
2 changed files with 53 additions and 6 deletions

View File

@ -1407,13 +1407,18 @@ void ArucoDetector::refineDetectedMarkers(InputArray _image, const Board& _board
}
void ArucoDetector::write(FileStorage &fs) const {
fs << "dictionaries" << "[";
for (auto& dictionary : arucoDetectorImpl->dictionaries) {
fs << "{";
dictionary.writeDictionary(fs);
fs << "}";
// preserve old format for single dictionary case
if (1 == arucoDetectorImpl->dictionaries.size()) {
arucoDetectorImpl->dictionaries[0].writeDictionary(fs);
} else {
fs << "dictionaries" << "[";
for (auto& dictionary : arucoDetectorImpl->dictionaries) {
fs << "{";
dictionary.writeDictionary(fs);
fs << "}";
}
fs << "]";
}
fs << "]";
arucoDetectorImpl->detectorParams.writeDetectorParameters(fs);
arucoDetectorImpl->refineParams.writeRefineParameters(fs);
}

View File

@ -6,6 +6,15 @@
#include "opencv2/objdetect/aruco_detector.hpp"
#include "opencv2/calib3d.hpp"
namespace cv::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<uchar>(), d1.bytesList.end<uchar>(), d2.bytesList.begin<uchar>())
&& d1.maxCorrectionBits == d2.maxCorrectionBits;
};
}
namespace opencv_test { namespace {
/**
@ -675,6 +684,9 @@ TEST(CV_ArucoMultiDict, noDict)
EXPECT_THROW({
detector.removeDictionary(0);
}, Exception);
EXPECT_THROW({
detector.setDictionaries({});
}, Exception);
}
@ -717,6 +729,36 @@ TEST(CV_ArucoMultiDict, multiMarkerDetection)
}
TEST(CV_ArucoMultiDict, serialization)
{
const std::string fileName("test_aruco_serialization.json");
aruco::ArucoDetector detector;
{
FileStorage fs(fileName, FileStorage::Mode::WRITE);
detector.write(fs);
fs.release();
FileStorage test_fs(fileName, FileStorage::Mode::READ);
aruco::ArucoDetector test_detector;
test_detector.read(test_fs.root());
// compare default constructor result
EXPECT_EQ(aruco::getPredefinedDictionary(aruco::DICT_4X4_50), test_detector.getDictionary());
}
detector.addDictionary(aruco::getPredefinedDictionary(aruco::DICT_5X5_100));
{
FileStorage fs(fileName, FileStorage::Mode::WRITE);
detector.write(fs);
fs.release();
FileStorage test_fs(fileName, FileStorage::Mode::READ);
aruco::ArucoDetector test_detector;
test_detector.read(test_fs.root());
// check for one additional dictionary
ASSERT_EQ(2ul, test_detector.getDictionaries().size());
EXPECT_EQ(aruco::getPredefinedDictionary(aruco::DICT_4X4_50), test_detector.getDictionary());
EXPECT_EQ(aruco::getPredefinedDictionary(aruco::DICT_5X5_100), test_detector.getDictionary(1));
}
}
struct ArucoThreading: public testing::TestWithParam<aruco::CornerRefineMethod>
{
struct NumThreadsSetter {