diff --git a/modules/objdetect/src/aruco/charuco_detector.cpp b/modules/objdetect/src/aruco/charuco_detector.cpp index 6b19114183..88a567a7a3 100644 --- a/modules/objdetect/src/aruco/charuco_detector.cpp +++ b/modules/objdetect/src/aruco/charuco_detector.cpp @@ -414,7 +414,12 @@ void CharucoDetector::detectDiamonds(InputArray image, OutputArrayOfArrays _diam // stores if the detected markers have been assigned or not to a diamond vector assigned(_markerIds.total(), false); - if(_markerIds.total() < 4ull) return; // a diamond need at least 4 markers + if(_markerIds.total() < 4ull) + { + if (_diamondCorners.needed()) _diamondCorners.release(); + if (_diamondIds.needed()) _diamondIds.release(); + return; // a diamond need at least 4 markers + } // convert input image to grey Mat grey; @@ -518,16 +523,27 @@ void CharucoDetector::detectDiamonds(InputArray image, OutputArrayOfArrays _diam if(diamondIds.size() > 0ull) { // parse output - Mat(diamondIds).copyTo(_diamondIds); + if (_diamondIds.needed()) + { + Mat(diamondIds).copyTo(_diamondIds); + } - _diamondCorners.create((int)diamondCorners.size(), 1, CV_32FC2); - for(unsigned int i = 0; i < diamondCorners.size(); i++) { - _diamondCorners.create(4, 1, CV_32FC2, i, true); - for(int j = 0; j < 4; j++) { - _diamondCorners.getMat(i).at(j) = diamondCorners[i][j]; + if (_diamondCorners.needed()) + { + _diamondCorners.create((int)diamondCorners.size(), 1, CV_32FC2); + for(unsigned int i = 0; i < diamondCorners.size(); i++) { + _diamondCorners.create(4, 1, CV_32FC2, i, true); + for(int j = 0; j < 4; j++) { + _diamondCorners.getMat(i).at(j) = diamondCorners[i][j]; + } } } } + else + { + if (_diamondCorners.needed()) _diamondCorners.release(); + if (_diamondIds.needed()) _diamondIds.release(); + } } void drawDetectedCornersCharuco(InputOutputArray _image, InputArray _charucoCorners, diff --git a/modules/objdetect/test/test_charucodetection.cpp b/modules/objdetect/test/test_charucodetection.cpp index 0e91c69ea9..2d27abcd37 100644 --- a/modules/objdetect/test/test_charucodetection.cpp +++ b/modules/objdetect/test/test_charucodetection.cpp @@ -703,6 +703,27 @@ TEST(Charuco, testmatchImagePoints) } } +TEST(Charuco, detectDiamondsClearsOutputsWithLessThanFourMarkers) +{ + aruco::CharucoBoard board(Size(3, 3), 1.f, 0.5f, aruco::getPredefinedDictionary(aruco::DICT_4X4_50)); + aruco::CharucoDetector detector(board); + + vector> markerCorners = { + {Point2f(10.f, 10.f), Point2f(20.f, 10.f), Point2f(20.f, 20.f), Point2f(10.f, 20.f)}, + {Point2f(30.f, 10.f), Point2f(40.f, 10.f), Point2f(40.f, 20.f), Point2f(30.f, 20.f)}, + {Point2f(10.f, 30.f), Point2f(20.f, 30.f), Point2f(20.f, 40.f), Point2f(10.f, 40.f)} + }; + vector markerIds = {0, 1, 2}; + + vector> diamondCorners = {{Point2f(1.f, 1.f), Point2f(2.f, 1.f), Point2f(2.f, 2.f), Point2f(1.f, 2.f)}}; + vector diamondIds = {Vec4i(0, 1, 2, 3)}; + + detector.detectDiamonds(Mat(), diamondCorners, diamondIds, markerCorners, markerIds); + + EXPECT_TRUE(diamondCorners.empty()); + EXPECT_TRUE(diamondIds.empty()); +} + typedef testing::TestWithParam CharucoDraw; INSTANTIATE_TEST_CASE_P(/**/, CharucoDraw, testing::Values(CV_8UC2, CV_8SC2, CV_16UC2, CV_16SC2, CV_32SC2, CV_32FC2, CV_64FC2)); TEST_P(CharucoDraw, testDrawDetected) {