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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user