Skip to content

Commit 87c8d92

Browse files
shimatclaude
andcommitted
Merge origin/main (LSDDetector enable #1996, ffmpeg dll fix #1997)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2 parents 91c5458 + f0b9262 commit 87c8d92

9 files changed

Lines changed: 116 additions & 123 deletions

File tree

src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods_stdvector.cs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -332,22 +332,17 @@ public static partial void vector_ImageFeatures_getKeypointsSize(
332332

333333
#endregion
334334
#region cv::line_descriptor::KeyLine
335-
#if false
336-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
337-
public static partial IntPtr vector_KeyLine_new1();
338-
339-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
340-
public static partial nuint vector_KeyLine_getSize(OpenCvSafeHandle vector);
335+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
336+
public static partial IntPtr vector_KeyLine_new1();
341337

342-
//[DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
343-
//public static extern void vector_KeyLine_getElements(IntPtr vector, [Out] KeyLine[] dst);
338+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
339+
public static partial nuint vector_KeyLine_getSize(OpenCvSafeHandle vector);
344340

345-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
346-
public static partial IntPtr vector_KeyLine_getPointer(OpenCvSafeHandle vector);
341+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
342+
public static partial IntPtr vector_KeyLine_getPointer(OpenCvSafeHandle vector);
347343

348-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
349-
public static partial void vector_KeyLine_delete(IntPtr vector);
350-
#endif
344+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
345+
public static partial void vector_KeyLine_delete(IntPtr vector);
351346
#endregion
352347

353348
#region vector<uchar>
@@ -457,17 +452,15 @@ public static partial void vector_string_getElements(
457452
public static partial void vector_string_delete(IntPtr vector);
458453
#endregion
459454
#region vector<cv::line_descriptor::KeyLine>
460-
#if false
461-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
462-
public static partial IntPtr vector_vector_KeyLine_new1();
463-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
464-
public static partial nuint vector_vector_KeyLine_getSize1(OpenCvSafeHandle vector);
465-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
466-
public static partial void vector_vector_KeyLine_getSize2(OpenCvSafeHandle vector, [In, Out] nuint[] size);
467-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
468-
public static partial void vector_vector_KeyLine_copy(OpenCvSafeHandle vec, IntPtr[] dst);
469-
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
470-
public static partial void vector_vector_KeyLine_delete(IntPtr vector);
471-
#endif
455+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
456+
public static partial IntPtr vector_vector_KeyLine_new1();
457+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
458+
public static partial nuint vector_vector_KeyLine_getSize1(OpenCvSafeHandle vector);
459+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
460+
public static partial void vector_vector_KeyLine_getSize2(OpenCvSafeHandle vector, [In, Out] nuint[] size);
461+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
462+
public static partial void vector_vector_KeyLine_copy(OpenCvSafeHandle vec, IntPtr[] dst);
463+
[LibraryImport(DllExtern), UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
464+
public static partial void vector_vector_KeyLine_delete(IntPtr vector);
472465
#endregion
473466
}

src/OpenCvSharp/Internal/Vectors/VectorOfKeyLine.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#if false
1+
using OpenCvSharp.LineDescriptor;
22

33
namespace OpenCvSharp.Internal.Vectors
44
{
5-
/// <summary>
5+
/// <summary>
66
/// </summary>
77
public class VectorOfKeyLine : CvObject, IStdVector<KeyLine>
88
{
@@ -31,8 +31,7 @@ public int Size
3131
{
3232
get
3333
{
34-
var res = NativeMethods.vector_KeyLine_getSize(CvPtr);
35-
GC.KeepAlive(this);
34+
var res = NativeMethods.vector_KeyLine_getSize(Handle);
3635
return (int)res;
3736
}
3837
}
@@ -44,7 +43,7 @@ public IntPtr ElemPtr
4443
{
4544
get
4645
{
47-
var res = NativeMethods.vector_KeyLine_getPointer(CvPtr);
46+
var res = NativeMethods.vector_KeyLine_getPointer(Handle);
4847
GC.KeepAlive(this);
4948
return res;
5049
}
@@ -71,5 +70,3 @@ public KeyLine[] ToArray()
7170
}
7271
}
7372
}
74-
75-
#endif

src/OpenCvSharp/Internal/Vectors/VectorOfVectorKeyLine.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
#if false
1+
using OpenCvSharp.Internal.Util;
2+
using OpenCvSharp.LineDescriptor;
23

34
namespace OpenCvSharp.Internal.Vectors
45
{
5-
/// <summary>
6+
/// <summary>
67
/// </summary>
78
// ReSharper disable once InconsistentNaming
89
public class VectorOfVectorKeyLine : CvObject, IStdVector<KeyLine[]>
@@ -73,5 +74,3 @@ public KeyLine[][] ToArray()
7374
}
7475
}
7576
}
76-
77-
#endif

src/OpenCvSharp/Modules/line_descriptors/LSDDetector.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-

1+
using OpenCvSharp.Internal;
2+
using OpenCvSharp.Internal.Vectors;
23

34
// ReSharper disable UnusedMember.Global
45

56
// https://github.com/opencv/opencv_contrib/blob/33ae078b0989b44ac8d262d210335b04bb268b4d/modules/line_descriptor/src/binary_descriptor.cpp#L1030
6-
#if false
77
namespace OpenCvSharp.LineDescriptor
88
{
99
/// <summary>
@@ -133,5 +133,3 @@ public KeyLine[][] Detect(IEnumerable<Mat> images, int scale, int numOctaves, IE
133133
}
134134
}
135135
}
136-
137-
#endif

src/OpenCvSharpExtern/line_descriptor.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,21 @@ CVAPI(ExceptionStatus) line_descriptor_LSDDetector_detect2(
6363
cv::Mat** masks, int32_t masksSize)
6464
{
6565
return cvTry([&] {
66+
// LSDDetector::detect(images, keylines, ..., masks) indexes both `keylines` and `masks`
67+
// by images.size() without resizing them itself, so both must be pre-sized here.
6668
std::vector<cv::Mat> imagesVec(imagesSize);
67-
std::vector<cv::Mat> masksVec(masksSize);
69+
std::vector<cv::Mat> masksVec(imagesSize);
6870
for (int i = 0; i < imagesSize; i++)
6971
{
7072
imagesVec[i] = *images[i];
7173
}
72-
for (int i = 0; i < masksSize; i++)
74+
const int maskCount = std::min(masksSize, imagesSize);
75+
for (int i = 0; i < maskCount; i++)
7376
{
7477
masksVec[i] = *masks[i];
7578
}
76-
79+
80+
keylines->resize(imagesSize);
7781
obj->detect(imagesVec, *keylines, scale, numOctaves, masksVec);
7882

7983
});

src/OpenCvSharpExtern/my_types.h

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -263,26 +263,6 @@ extern "C"
263263
cv::Mat* descriptors;
264264
};
265265

266-
/*
267-
struct line_descriptor_KeyLine
268-
{
269-
float angle;
270-
int class_id;
271-
int octave;
272-
interop::Point2f pt;
273-
float response;
274-
float size;
275-
float startPointX;
276-
float startPointY;
277-
float endPointX;
278-
float endPointY;
279-
float sPointInOctaveX;
280-
float sPointInOctaveY;
281-
float ePointInOctaveX;
282-
float ePointInOctaveY;
283-
float lineLength;
284-
int numOfPixels;
285-
};*/
286266
}
287267

288268
// bit_cast-based converter pair for layout-identical POD <-> cv:: types.

src/OpenCvSharpExtern/std_vector.h

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,8 @@ CVAPI(void) vector_ImageFeatures_delete(std::vector<cv::detail::ImageFeatures>*
268268
#pragma endregion
269269
#endif // NO_STITCHING
270270

271+
#ifndef NO_CONTRIB
271272
#pragma region cv::line_descriptor::KeyLine
272-
#if 0
273273
CVAPI(std::vector<cv::line_descriptor::KeyLine>*) vector_KeyLine_new1()
274274
{
275275
return new std::vector<cv::line_descriptor::KeyLine>;
@@ -280,26 +280,6 @@ CVAPI(size_t) vector_KeyLine_getSize(std::vector<cv::line_descriptor::KeyLine>*
280280
return vector->size();
281281
}
282282

283-
/*
284-
CVAPI(void) vector_KeyLine_getElements(
285-
std::vector<cv::line_descriptor::KeyLine>* vector, line_descriptor_KeyLine* dst)
286-
{
287-
for (size_t i = 0; i < vector->size(); i++)
288-
{
289-
const auto &k = vector->at(i);
290-
const line_descriptor_KeyLine kl{
291-
k.angle, k.class_id, k.octave,
292-
{k.pt.x, k.pt.y},
293-
k.response, k.size,
294-
k.startPointX, k.startPointY,
295-
k.endPointX, k.endPointY,
296-
k.sPointInOctaveX, k.sPointInOctaveY,
297-
k.ePointInOctaveX, k.ePointInOctaveY,
298-
k.lineLength, k.numOfPixels };
299-
dst[i] = kl;
300-
}
301-
}*/
302-
303283
CVAPI(cv::line_descriptor::KeyLine*) vector_KeyLine_getPointer(std::vector<cv::line_descriptor::KeyLine>* vector)
304284
{
305285
return &(vector->at(0));
@@ -309,5 +289,5 @@ CVAPI(void) vector_KeyLine_delete(std::vector<cv::line_descriptor::KeyLine>* vec
309289
{
310290
delete vector;
311291
}
312-
#endif
313-
#pragma endregion
292+
#pragma endregion
293+
#endif // NO_CONTRIB

src/OpenCvSharpExtern/std_vector_nesting.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,9 +256,9 @@ CVAPI(void) vector_vector_Point2f_delete(std::vector<std::vector<cv::Point2f> >*
256256

257257
#pragma endregion
258258

259+
#ifndef NO_CONTRIB
259260
#pragma region vector<cv::line_descriptor::KeyLine>
260261

261-
#if 0
262262
CVAPI(std::vector<std::vector<cv::line_descriptor::KeyLine> >*) vector_vector_KeyLine_new1()
263263
{
264264
return new std::vector<std::vector<cv::line_descriptor::KeyLine> >;
@@ -286,5 +286,5 @@ CVAPI(void) vector_vector_KeyLine_delete(std::vector<std::vector<cv::line_descri
286286
{
287287
delete vec;
288288
}
289-
#endif
290-
#pragma endregion
289+
#pragma endregion
290+
#endif // NO_CONTRIB

test/OpenCvSharp.Tests/line_descriptor/LSDDetectorTest.cs

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,92 @@
1-
#if false
1+
#pragma warning disable CA5394 // Do not use insecure randomness
22

3-
namespace OpenCvSharp.Tests.LineDescriptor
3+
using System.Diagnostics;
4+
using OpenCvSharp.LineDescriptor;
5+
using Xunit;
6+
7+
namespace OpenCvSharp.Tests.LineDescriptor;
8+
9+
// ReSharper disable once InconsistentNaming
10+
public class LSDDetectorTest : TestBase
411
{
5-
// ReSharper disable once InconsistentNaming
6-
public class LSDDetectorTest
12+
[Fact]
13+
public void New()
14+
{
15+
using var lsd = new LSDDetector();
16+
GC.KeepAlive(lsd);
17+
}
18+
19+
[Fact]
20+
public void NewWithParam()
721
{
8-
[Fact]
9-
public void New()
22+
var lsdParam = new LSDParam();
23+
using var lsd = new LSDDetector(lsdParam);
24+
GC.KeepAlive(lsd);
25+
}
26+
27+
[Fact]
28+
public void Detect()
29+
{
30+
using var src = LoadImage("building.jpg");
31+
using var gray = new Mat();
32+
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
33+
34+
using var lsd = new LSDDetector();
35+
var keyLines = lsd.Detect(gray, 2, 1);
36+
Assert.NotEmpty(keyLines);
37+
38+
foreach (var kl in keyLines)
1039
{
11-
using var lsd = new LSDDetector();
12-
GC.KeepAlive(lsd);
40+
Assert.True(kl.LineLength > 0);
41+
Assert.True(kl.NumOfPixels > 0);
1342
}
1443

15-
[Fact]
16-
public void NewWithParam()
44+
if (Debugger.IsAttached)
1745
{
18-
var lsdParam = new LSDParam();
19-
using var lsd = new LSDDetector(lsdParam);
20-
GC.KeepAlive(lsd);
46+
var random = new Random();
47+
48+
foreach (var kl in keyLines)
49+
{
50+
var color = new Scalar(random.Next(256), random.Next(256), random.Next(256));
51+
Cv2.Line(src, (Point)kl.StartPoint, (Point)kl.EndPoint, color, 3);
52+
}
53+
54+
Window.ShowImages(src);
2155
}
56+
}
2257

23-
[Fact]
24-
public void Detect()
25-
{
26-
using var src = new Mat("_data/image/building.jpg", ImreadModes.Color);
27-
using var gray = new Mat();
28-
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
58+
[Fact]
59+
public void DetectMultipleImages()
60+
{
61+
using var src1 = LoadImage("building.jpg");
62+
using var src2 = LoadImage("lenna.png");
63+
using var gray1 = new Mat();
64+
using var gray2 = new Mat();
65+
Cv2.CvtColor(src1, gray1, ColorConversionCodes.BGR2GRAY);
66+
Cv2.CvtColor(src2, gray2, ColorConversionCodes.BGR2GRAY);
2967

30-
using var lsd = new LSDDetector();
31-
var keyLines = lsd.Detect(gray, 2, 1);
32-
Assert.NotEmpty(keyLines);
68+
using var lsd = new LSDDetector();
69+
var keyLines = lsd.Detect([gray1, gray2], 2, 1);
3370

34-
if (Debugger.IsAttached)
35-
{
36-
var random = new Random();
71+
Assert.Equal(2, keyLines.Length);
72+
Assert.NotEmpty(keyLines[0]);
73+
Assert.NotEmpty(keyLines[1]);
74+
}
3775

38-
foreach (var kl in keyLines)
39-
{
40-
var color = new Scalar(random.Next(256), random.Next(256), random.Next(256));
76+
[Fact]
77+
public void DetectMultipleImagesWithMoreMasksThanImages()
78+
{
79+
using var src1 = LoadImage("building.jpg");
80+
using var gray1 = new Mat();
81+
Cv2.CvtColor(src1, gray1, ColorConversionCodes.BGR2GRAY);
82+
using var mask1 = new Mat(gray1.Size(), MatType.CV_8UC1, Scalar.All(255));
83+
using var mask2 = new Mat(gray1.Size(), MatType.CV_8UC1, Scalar.All(255));
4184

42-
Cv2.Line(src, (Point)kl.GetStartPoint(), (Point)kl.GetEndPoint(), color, 3);
43-
}
85+
using var lsd = new LSDDetector();
86+
// More masks than images: the native wrapper must not write past the
87+
// pre-sized (images.Length) masks vector.
88+
var keyLines = lsd.Detect([gray1], 2, 1, [mask1, mask2]);
4489

45-
Window.ShowImages(src);
46-
}
47-
}
90+
Assert.Single(keyLines);
4891
}
4992
}
50-
#endif

0 commit comments

Comments
 (0)