1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

Address comments, add Python test

This commit is contained in:
Benjamin Knecht
2025-02-18 17:03:37 +01:00
parent 379b5a2fdb
commit bb07ce7454
4 changed files with 51 additions and 35 deletions
@@ -350,12 +350,12 @@ public:
InputArray cameraMatrix = noArray(), InputArray distCoeffs = noArray(),
OutputArray recoveredIdxs = noArray()) const;
CV_WRAP const Dictionary& getDictionary(size_t index = 0) const;
CV_WRAP void setDictionary(const Dictionary& dictionary, size_t index = 0);
CV_WRAP const Dictionary& getDictionary(int index = 0) const;
CV_WRAP void setDictionary(const Dictionary& dictionary, int index = 0);
CV_WRAP const std::vector<Dictionary>& getDictionaries() const;
CV_WRAP void setDictionaries(const std::vector<Dictionary>& dictionaries);
CV_WRAP void addDictionary(const Dictionary& dictionary);
CV_WRAP void removeDictionary(size_t index);
CV_WRAP void removeDictionary(int index);
CV_WRAP const DetectorParameters& getDetectorParameters() const;
CV_WRAP void setDetectorParameters(const DetectorParameters& detectorParameters);
@@ -156,7 +156,7 @@ class aruco_objdetect_test(NewOpenCVTests):
gold_corners = np.array([[offset, offset],[marker_size+offset-1.0,offset],
[marker_size+offset-1.0,marker_size+offset-1.0],
[offset, marker_size+offset-1.0]], dtype=np.float32)
corners, ids, rejected = aruco_detector.detectMarkers(img_marker)
corners, ids, rejected, _ = aruco_detector.detectMarkers(img_marker)
self.assertEqual(1, len(ids))
self.assertEqual(id, ids[0])
@@ -171,7 +171,7 @@ class aruco_objdetect_test(NewOpenCVTests):
board = cv.aruco.GridBoard(board_size, 5.0, 1.0, aruco_dict)
board_image = board.generateImage((board_size[0]*50, board_size[1]*50), marginSize=10)
corners, ids, rejected = aruco_detector.detectMarkers(board_image)
corners, ids, rejected, _ = aruco_detector.detectMarkers(board_image)
self.assertEqual(board_size[0]*board_size[1], len(ids))
part_corners, part_ids, part_rejected = corners[:-1], ids[:-1], list(rejected)
@@ -203,7 +203,7 @@ class aruco_objdetect_test(NewOpenCVTests):
gold_corners = np.array(board.getObjPoints())[:, :, 0:2]*cell_size
# detect corners
markerCorners, markerIds, _ = aruco_detector.detectMarkers(image)
markerCorners, markerIds, _, _ = aruco_detector.detectMarkers(image)
# test refine
rejected = [markerCorners[-1]]
@@ -458,5 +458,30 @@ class aruco_objdetect_test(NewOpenCVTests):
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)
]
aruco_detector = cv.aruco.ArucoDetector(aruco_dicts, aruco_params)
id = 2
marker_size = 100
offset = 10
img_marker1 = cv.aruco.generateImageMarker(aruco_dicts[0], id, marker_size, aruco_params.markerBorderBits)
img_marker1 = np.pad(img_marker1, pad_width=offset, mode='constant', constant_values=255)
img_marker2 = cv.aruco.generateImageMarker(aruco_dicts[1], id, marker_size, aruco_params.markerBorderBits)
img_marker2 = np.pad(img_marker2, pad_width=offset, mode='constant', constant_values=255)
img_markers = np.concatenate((img_marker1, img_marker2), axis=1)
corners, ids, rejected, dictIndices = aruco_detector.detectMarkers(img_markers)
self.assertEqual(2, len(ids))
self.assertEqual(id, ids[0])
self.assertEqual(id, ids[1])
self.assertEqual(2, len(dictIndices))
self.assertEqual(0, dictIndices[0])
self.assertEqual(1, dictIndices[1])
if __name__ == '__main__':
NewOpenCVTests.bootstrap()
@@ -654,7 +654,9 @@ struct ArucoDetector::ArucoDetectorImpl {
ArucoDetectorImpl(const std::vector<Dictionary>&_dictionaries, const DetectorParameters &_detectorParams,
const RefineParameters& _refineParams): dictionaries(_dictionaries),
detectorParams(_detectorParams), refineParams(_refineParams) {}
detectorParams(_detectorParams), refineParams(_refineParams) {
CV_Assert(!dictionaries.empty());
}
/**
* @brief Detect square candidates in the input image
*/
@@ -1034,10 +1036,7 @@ void ArucoDetector::detectMarkers(InputArray _image, OutputArrayOfArrays _corner
_copyVector2Output(candidates, _corners);
Mat(ids).copyTo(_ids);
if (_dictIndices.needed()) {
_dictIndices.create(dictIndices.size(), 1, CV_32SC1);
Mat dictIndicesMat = _dictIndices.getMat();
Mat m = cv::Mat1i(dictIndices).t();
m.copyTo(dictIndicesMat);
Mat(dictIndices).copyTo(_dictIndices);
}
}
@@ -1346,12 +1345,12 @@ void ArucoDetector::read(const FileNode &fn) {
arucoDetectorImpl->refineParams.readRefineParameters(fn);
}
const Dictionary& ArucoDetector::getDictionary(size_t index) const {
const Dictionary& ArucoDetector::getDictionary(int index) const {
CV_Assert(index < arucoDetectorImpl->dictionaries.size());
return arucoDetectorImpl->dictionaries[index];
}
void ArucoDetector::setDictionary(const Dictionary& dictionary, size_t index) {
void ArucoDetector::setDictionary(const Dictionary& dictionary, int index) {
// special case: if index is 0, we add the dictionary to the list to preserve the old behavior
CV_Assert(index == 0 || index < arucoDetectorImpl->dictionaries.size());
if (index == 0 && arucoDetectorImpl->dictionaries.empty()) {
@@ -1373,8 +1372,10 @@ void ArucoDetector::addDictionary(const Dictionary& dictionary) {
arucoDetectorImpl->dictionaries.push_back(dictionary);
}
void ArucoDetector::removeDictionary(size_t index) {
void ArucoDetector::removeDictionary(int index) {
CV_Assert(index < arucoDetectorImpl->dictionaries.size());
// disallow no dictionaries
CV_Assert(arucoDetectorImpl->dictionaries.size() > 1);
arucoDetectorImpl->dictionaries.erase(arucoDetectorImpl->dictionaries.begin() + index);
}
+11 -21
View File
@@ -640,6 +640,7 @@ TEST(CV_ArucoDetectMarkers, regression_contour_24220)
TEST(CV_ArucoMultiDict, addRemoveDictionary)
{
// using default constructor that pre-configures DICT_4X4_50
aruco::ArucoDetector detector;
detector.addDictionary(aruco::getPredefinedDictionary(aruco::DICT_5X5_100));
const auto& dicts = detector.getDictionaries();
@@ -649,11 +650,10 @@ TEST(CV_ArucoMultiDict, addRemoveDictionary)
detector.removeDictionary(0);
ASSERT_EQ(dicts.size(), 1ul);
EXPECT_EQ(dicts[0].markerSize, 5);
detector.removeDictionary(0);
EXPECT_EQ(dicts.size(), 0ul);
detector.addDictionary(aruco::getPredefinedDictionary(aruco::DICT_6X6_100));
detector.addDictionary(aruco::getPredefinedDictionary(aruco::DICT_7X7_250));
detector.addDictionary(aruco::getPredefinedDictionary(aruco::DICT_APRILTAG_25h9));
detector.removeDictionary(0);
ASSERT_EQ(dicts.size(), 3ul);
EXPECT_EQ(dicts[0].markerSize, 6);
EXPECT_EQ(dicts[1].markerSize, 7);
@@ -672,27 +672,17 @@ TEST(CV_ArucoMultiDict, addRemoveDictionary)
TEST(CV_ArucoMultiDict, noDict)
{
aruco::ArucoDetector detector;
detector.removeDictionary(0);
vector<vector<Point2f> > markerCorners;
vector<int> markerIds;
string img_path = cvtest::findDataFile("aruco/singlemarkersoriginal.jpg");
Mat image = imread(img_path);
detector.detectMarkers(image, markerCorners, markerIds);
EXPECT_EQ(markerIds.size(), 0u);
EXPECT_THROW({
detector.removeDictionary(0);
}, Exception);
}
TEST(CV_ArucoMultiDict, multiMarkerDetection)
{
aruco::ArucoDetector detector;
detector.removeDictionary(0);
const int markerSidePixels = 100;
const int imageSize = markerSidePixels * 2 + 3 * (markerSidePixels / 2);
vector<aruco::Dictionary> usedDictionaries;
// draw synthetic image
Mat img = Mat(imageSize, imageSize, CV_8UC1, Scalar::all(255));
@@ -702,18 +692,18 @@ TEST(CV_ArucoMultiDict, multiMarkerDetection)
int id = y * 2 + x;
int dictId = x * 4 + y * 8;
auto dict = aruco::getPredefinedDictionary(dictId);
detector.addDictionary(dict);
usedDictionaries.push_back(dict);
aruco::generateImageMarker(dict, id, markerSidePixels, marker);
Point2f firstCorner =
Point2f(markerSidePixels / 2.f + x * (1.5f * markerSidePixels),
Point2f firstCorner(markerSidePixels / 2.f + x * (1.5f * markerSidePixels),
markerSidePixels / 2.f + y * (1.5f * markerSidePixels));
Mat aux = img.colRange((int)firstCorner.x, (int)firstCorner.x + markerSidePixels)
.rowRange((int)firstCorner.y, (int)firstCorner.y + markerSidePixels);
Mat aux = img(Rect((int)firstCorner.x, (int)firstCorner.y, markerSidePixels, markerSidePixels));
marker.copyTo(aux);
}
}
img.convertTo(img, CV_8UC3);
aruco::ArucoDetector detector(usedDictionaries);
vector<vector<Point2f> > markerCorners;
vector<int> markerIds;
vector<vector<Point2f> > rejectedImgPts;