Skip to content

Commit 71a9a14

Browse files
shimatclaude
andcommitted
Add comprehensive tests for ArucoDetector, CharucoBoard, CharucoDetector, RefineParameters
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 39fce7c commit 71a9a14

1 file changed

Lines changed: 247 additions & 11 deletions

File tree

test/OpenCvSharp.Tests/aruco/ArucoTest.cs

Lines changed: 247 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ namespace OpenCvSharp.Tests.Aruco;
77
// ReSharper disable once InconsistentNaming
88
public class ArucoTest : TestBase
99
{
10+
// ==================== DetectorParameters ====================
11+
1012
[Fact]
1113
public void CreateDetectorParameters()
1214
{
@@ -47,6 +49,28 @@ public void CreateDetectorParameters()
4749
Assert.Equal(0, param.MinMarkerLengthRatioOriginalImg);
4850
}
4951

52+
// ==================== RefineParameters ====================
53+
54+
[Fact]
55+
public void CreateRefineParametersDefaults()
56+
{
57+
var param = new RefineParameters();
58+
Assert.Equal(10f, param.MinRepDistance, 1e-3f);
59+
Assert.Equal(3f, param.ErrorCorrectionRate, 1e-3f);
60+
Assert.True(param.CheckAllOrders);
61+
}
62+
63+
[Fact]
64+
public void CreateRefineParametersCustom()
65+
{
66+
var param = new RefineParameters(5f, 2f, false);
67+
Assert.Equal(5f, param.MinRepDistance, 1e-3f);
68+
Assert.Equal(2f, param.ErrorCorrectionRate, 1e-3f);
69+
Assert.False(param.CheckAllOrders);
70+
}
71+
72+
// ==================== Dictionary ====================
73+
5074
[Fact]
5175
public void GetPredefinedDictionary()
5276
{
@@ -86,16 +110,6 @@ public void ReadDictionaryFromFile()
86110
dict.Dispose();
87111
}
88112

89-
[Fact]
90-
public void DetectMarkers()
91-
{
92-
using var image = LoadImage("markers_6x6_250.png", ImreadModes.Grayscale);
93-
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict6X6_250);
94-
using var detector = new ArucoDetector(dict);
95-
96-
detector.DetectMarkers(image, out _, out _, out _);
97-
}
98-
99113
[Fact]
100114
public void DictionaryProperties()
101115
{
@@ -111,6 +125,69 @@ public void DictionaryProperties()
111125
Assert.Equal(50, dict.MaxCorrectionBits);
112126
}
113127

128+
// ==================== ArucoDetector ====================
129+
130+
[Fact]
131+
public void ArucoDetector_CreateDefault()
132+
{
133+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict6X6_250);
134+
using var detector = new ArucoDetector(dict);
135+
Assert.NotNull(detector);
136+
}
137+
138+
[Fact]
139+
public void ArucoDetector_CreateWithCustomParams()
140+
{
141+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict6X6_250);
142+
var dp = new DetectorParameters { CornerRefinementMethod = CornerRefineMethod.Subpix };
143+
var rp = new RefineParameters(5f, 2f, false);
144+
using var detector = new ArucoDetector(dict, dp, rp);
145+
Assert.NotNull(detector);
146+
}
147+
148+
[Fact]
149+
public void ArucoDetector_DetectMarkers()
150+
{
151+
using var image = LoadImage("markers_6x6_250.png", ImreadModes.Grayscale);
152+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict6X6_250);
153+
using var detector = new ArucoDetector(dict);
154+
155+
detector.DetectMarkers(image, out var corners, out var ids, out var rejectedImgPoints);
156+
157+
Assert.NotNull(corners);
158+
Assert.NotNull(ids);
159+
Assert.NotNull(rejectedImgPoints);
160+
Assert.True(ids.Length > 0, "Expected at least one marker to be detected");
161+
Assert.Equal(ids.Length, corners.Length);
162+
foreach (var markerCorners in corners)
163+
Assert.Equal(4, markerCorners.Length);
164+
}
165+
166+
[Fact]
167+
public void ArucoDetector_DetectMarkersWithCustomParams()
168+
{
169+
using var image = LoadImage("markers_6x6_250.png", ImreadModes.Grayscale);
170+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict6X6_250);
171+
var dp = new DetectorParameters { CornerRefinementMethod = CornerRefineMethod.Subpix };
172+
using var detector = new ArucoDetector(dict, dp, new RefineParameters());
173+
174+
detector.DetectMarkers(image, out var corners, out var ids, out _);
175+
176+
Assert.True(ids.Length > 0);
177+
Assert.Equal(ids.Length, corners.Length);
178+
}
179+
180+
[Fact]
181+
public void ArucoDetector_Dispose()
182+
{
183+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
184+
var detector = new ArucoDetector(dict);
185+
detector.Dispose();
186+
Assert.True(detector.IsDisposed);
187+
}
188+
189+
// ==================== DrawDetected* ====================
190+
114191
[Fact]
115192
public void DrawDetectedMarker()
116193
{
@@ -121,14 +198,173 @@ public void DrawDetectedMarker()
121198
detector.DetectMarkers(image, out var corners, out var ids, out var rejectedImgPoints);
122199

123200
CvAruco.DrawDetectedMarkers(outputImage, corners, ids, new Scalar(255, 0, 0));
201+
// ids=null path
124202
CvAruco.DrawDetectedMarkers(outputImage, rejectedImgPoints, null, new Scalar(0, 0, 255));
125203

126204
if (Debugger.IsAttached)
127205
{
128-
// If you want to save markers image, you must change the following values.
129206
const string path = "C:\\detected_markers_6x6_250.png";
130207
Cv2.ImWrite(path, outputImage);
131208
Process.Start(path);
132209
}
133210
}
211+
212+
// ==================== CharucoBoard ====================
213+
214+
[Fact]
215+
public void CharucoBoard_Create()
216+
{
217+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
218+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
219+
Assert.NotNull(board);
220+
}
221+
222+
[Fact]
223+
public void CharucoBoard_Properties()
224+
{
225+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
226+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
227+
228+
Assert.Equal(new Size(5, 7), board.ChessboardSize);
229+
Assert.Equal(0.04f, board.SquareLength, 1e-5f);
230+
Assert.Equal(0.02f, board.MarkerLength, 1e-5f);
231+
}
232+
233+
[Fact]
234+
public void CharucoBoard_LegacyPattern()
235+
{
236+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
237+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
238+
239+
Assert.False(board.LegacyPattern);
240+
board.LegacyPattern = true;
241+
Assert.True(board.LegacyPattern);
242+
board.LegacyPattern = false;
243+
Assert.False(board.LegacyPattern);
244+
}
245+
246+
[Fact]
247+
public void CharucoBoard_GenerateImage()
248+
{
249+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
250+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
251+
using var img = new Mat();
252+
253+
board.GenerateImage(new Size(500, 700), img);
254+
255+
Assert.False(img.Empty());
256+
Assert.Equal(700, img.Rows);
257+
Assert.Equal(500, img.Cols);
258+
}
259+
260+
[Fact]
261+
public void CharucoBoard_CheckCharucoCornersCollinear_Collinear()
262+
{
263+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
264+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
265+
266+
// IDs on the same row are collinear
267+
var collinearIds = new[] { 0, 1, 2, 3 };
268+
using var idsMat = Mat.FromArray(collinearIds);
269+
Assert.True(board.CheckCharucoCornersCollinear(idsMat));
270+
}
271+
272+
[Fact]
273+
public void CharucoBoard_Dispose()
274+
{
275+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
276+
var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
277+
board.Dispose();
278+
Assert.True(board.IsDisposed);
279+
}
280+
281+
// ==================== CharucoDetector ====================
282+
283+
[Fact]
284+
public void CharucoDetector_Create()
285+
{
286+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
287+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
288+
using var detector = new CharucoDetector(board);
289+
Assert.NotNull(detector);
290+
}
291+
292+
[Fact]
293+
public void CharucoDetector_CreateWithAllParams()
294+
{
295+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
296+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
297+
var dp = new DetectorParameters();
298+
var rp = new RefineParameters();
299+
using var detector = new CharucoDetector(board, null, null, 2, false, true, dp, rp);
300+
Assert.NotNull(detector);
301+
}
302+
303+
[Fact]
304+
public void CharucoDetector_DetectBoard()
305+
{
306+
// Generate a synthetic charuco board image and detect from it
307+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
308+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
309+
using var boardImage = new Mat();
310+
board.GenerateImage(new Size(600, 800), boardImage, 10, 1);
311+
312+
using var detector = new CharucoDetector(board);
313+
detector.DetectBoard(boardImage, out var charucoCorners, out var charucoIds,
314+
out var markerCorners, out var markerIds);
315+
316+
Assert.NotNull(charucoCorners);
317+
Assert.NotNull(charucoIds);
318+
Assert.NotNull(markerCorners);
319+
Assert.NotNull(markerIds);
320+
Assert.True(charucoIds.Length > 0, "Expected at least one charuco corner detected");
321+
Assert.Equal(charucoCorners.Length, charucoIds.Length);
322+
Assert.Equal(markerCorners.Length, markerIds.Length);
323+
}
324+
325+
[Fact]
326+
public void CharucoDetector_DetectBoard_EmptyImage()
327+
{
328+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
329+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
330+
using var emptyImage = Mat.Zeros(300, 300, MatType.CV_8UC1);
331+
332+
using var detector = new CharucoDetector(board);
333+
detector.DetectBoard(emptyImage, out var charucoCorners, out var charucoIds,
334+
out var markerCorners, out var markerIds);
335+
336+
// No markers or corners should be detected in a blank image
337+
Assert.Equal(0, charucoIds.Length);
338+
Assert.Equal(0, markerIds.Length);
339+
}
340+
341+
[Fact]
342+
public void CharucoDetector_Dispose()
343+
{
344+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
345+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
346+
var detector = new CharucoDetector(board);
347+
detector.Dispose();
348+
Assert.True(detector.IsDisposed);
349+
}
350+
351+
// ==================== DrawDetectedCornersCharuco / DrawDetectedDiamonds ====================
352+
353+
[Fact]
354+
public void DrawDetectedCornersCharuco()
355+
{
356+
using var dict = CvAruco.GetPredefinedDictionary(PredefinedDictionaryType.Dict4X4_50);
357+
using var board = new CharucoBoard(5, 7, 0.04f, 0.02f, dict);
358+
using var boardImage = new Mat();
359+
board.GenerateImage(new Size(600, 800), boardImage, 10, 1);
360+
using var outputImage = boardImage.CvtColor(ColorConversionCodes.GRAY2RGB);
361+
362+
using var detector = new CharucoDetector(board);
363+
detector.DetectBoard(boardImage, out var charucoCorners, out var charucoIds, out _, out _);
364+
365+
// With ids
366+
CvAruco.DrawDetectedCornersCharuco(outputImage, charucoCorners, charucoIds, new Scalar(0, 255, 0));
367+
// Without ids (null path)
368+
CvAruco.DrawDetectedCornersCharuco(outputImage, charucoCorners, null);
369+
}
134370
}

0 commit comments

Comments
 (0)