Skip to content

Commit 5aa0631

Browse files
authored
Merge pull request shimat#1010 from shimat/ComputeImageFeatures
add ComputeImageFeatures
2 parents 45159ec + b6563bd commit 5aa0631

File tree

12 files changed

+404
-18
lines changed

12 files changed

+404
-18
lines changed

src/OpenCvSharp/Modules/xfeatures2d/SIFT.cs renamed to src/OpenCvSharp/Modules/features2d/SIFT.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using System;
22

3-
namespace OpenCvSharp.XFeatures2D
3+
namespace OpenCvSharp.Features2D
44
{
55
// ReSharper disable InconsistentNaming
66

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.InteropServices;
5+
6+
// ReSharper disable UnusedMember.Global
7+
8+
namespace OpenCvSharp.Detail
9+
{
10+
/// <summary>
11+
/// cv::detail functions
12+
/// </summary>
13+
public static class CvDetail
14+
{
15+
/// <summary>
16+
///
17+
/// </summary>
18+
/// <param name="featuresFinder"></param>
19+
/// <param name="images"></param>
20+
/// <param name="features"></param>
21+
/// <param name="masks"></param>
22+
public static void ComputeImageFeatures(
23+
Feature2D featuresFinder,
24+
IEnumerable<Mat> images,
25+
out ImageFeatures[] features,
26+
IEnumerable<Mat>? masks = null)
27+
{
28+
if (featuresFinder == null)
29+
throw new ArgumentNullException(nameof(featuresFinder));
30+
if (images == null)
31+
throw new ArgumentNullException(nameof(images));
32+
featuresFinder.ThrowIfDisposed();
33+
34+
var imagesArray = images as Mat[] ?? images.ToArray();
35+
if (imagesArray.Length == 0)
36+
throw new ArgumentException("Empty array", nameof(images));
37+
38+
var descriptorsMat = new Mat[imagesArray.Length];
39+
var keypointsVec = new VectorOfKeyPoint[imagesArray.Length];
40+
var wImageFeatures = new WImageFeatures[imagesArray.Length];
41+
for (int i = 0; i < imagesArray.Length; i++)
42+
{
43+
descriptorsMat[i] = new Mat();
44+
keypointsVec[i] = new VectorOfKeyPoint();
45+
wImageFeatures[i] = new WImageFeatures
46+
{
47+
Keypoints = keypointsVec[i].CvPtr,
48+
Descriptors = descriptorsMat[i].CvPtr
49+
};
50+
}
51+
52+
var imagesPointers = imagesArray.Select(i => i.CvPtr).ToArray();
53+
var masksPointers = masks?.Select(i => i.CvPtr).ToArray();
54+
if (masksPointers != null && imagesPointers.Length != masksPointers.Length)
55+
throw new ArgumentException("size of images != size of masks");
56+
57+
var wImageFeaturesPointers = new GCHandle[wImageFeatures.Length];
58+
try
59+
{
60+
for (int i = 0; i < wImageFeatures.Length; i++)
61+
{
62+
wImageFeaturesPointers[i] = GCHandle.Alloc(wImageFeatures[i], GCHandleType.Pinned);
63+
}
64+
65+
if (masksPointers == null)
66+
{
67+
NativeMethods.HandleException(
68+
NativeMethods.stitching_computeImageFeatures1_2(
69+
featuresFinder.CvPtr,
70+
imagesPointers,
71+
imagesPointers.Length,
72+
wImageFeaturesPointers.Select(gch => gch.AddrOfPinnedObject()).ToArray(),
73+
IntPtr.Zero));
74+
}
75+
else
76+
{
77+
NativeMethods.HandleException(
78+
NativeMethods.stitching_computeImageFeatures1_1(
79+
featuresFinder.CvPtr,
80+
imagesPointers,
81+
imagesPointers.Length,
82+
wImageFeaturesPointers.Select(gch => gch.AddrOfPinnedObject()).ToArray(),
83+
masksPointers));
84+
}
85+
}
86+
finally
87+
{
88+
for (int i = 0; i < wImageFeaturesPointers.Length; i++)
89+
{
90+
wImageFeaturesPointers[i].Free();
91+
}
92+
}
93+
94+
features = new ImageFeatures[wImageFeatures.Length];
95+
for (int i = 0; i < wImageFeaturesPointers.Length; i++)
96+
{
97+
features[i] = new ImageFeatures(
98+
wImageFeatures[i].ImgIdx,
99+
wImageFeatures[i].ImgSize,
100+
keypointsVec[i].ToArray(),
101+
descriptorsMat[i]);
102+
}
103+
104+
GC.KeepAlive(featuresFinder);
105+
GC.KeepAlive(images);
106+
GC.KeepAlive(masks);
107+
GC.KeepAlive(descriptorsMat);
108+
GC.KeepAlive(imagesPointers);
109+
}
110+
111+
/// <summary>
112+
///
113+
/// </summary>
114+
/// <param name="featuresFinder"></param>
115+
/// <param name="image"></param>
116+
/// <param name="features"></param>
117+
/// <param name="mask"></param>
118+
public static void ComputeImageFeatures(
119+
Feature2D featuresFinder,
120+
InputArray image,
121+
out ImageFeatures features,
122+
InputArray? mask = null)
123+
{
124+
if (featuresFinder == null)
125+
throw new ArgumentNullException(nameof(featuresFinder));
126+
if (image == null)
127+
throw new ArgumentNullException(nameof(image));
128+
featuresFinder.ThrowIfDisposed();
129+
image.ThrowIfDisposed();
130+
131+
var descriptorsMat = new Mat();
132+
var keypointsVec = new VectorOfKeyPoint();
133+
var wImageFeatures = new WImageFeatures
134+
{
135+
Keypoints = keypointsVec.CvPtr,
136+
Descriptors = descriptorsMat.CvPtr
137+
};
138+
139+
unsafe
140+
{
141+
NativeMethods.HandleException(
142+
NativeMethods.stitching_computeImageFeatures2(
143+
featuresFinder.CvPtr, image.CvPtr, &wImageFeatures, mask?.CvPtr ?? IntPtr.Zero));
144+
}
145+
146+
features = new ImageFeatures(
147+
wImageFeatures.ImgIdx,
148+
wImageFeatures.ImgSize,
149+
keypointsVec.ToArray(),
150+
descriptorsMat);
151+
152+
GC.KeepAlive(featuresFinder);
153+
GC.KeepAlive(image);
154+
GC.KeepAlive(mask);
155+
GC.KeepAlive(descriptorsMat);
156+
}
157+
}
158+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Runtime.InteropServices;
4+
5+
namespace OpenCvSharp.Detail
6+
{
7+
/// <summary>
8+
/// Structure containing image keypoints and descriptors.
9+
/// </summary>
10+
public class ImageFeatures : IDisposable
11+
{
12+
#pragma warning disable 1591
13+
public int ImgIdx { get; }
14+
public Size ImgSize{ get; }
15+
public IReadOnlyList<KeyPoint> Keypoints{ get; }
16+
public Mat Descriptors{ get; }
17+
#pragma warning restore 1591
18+
19+
/// <summary>
20+
/// Constructor
21+
/// </summary>
22+
/// <param name="imgIdx"></param>
23+
/// <param name="imgSize"></param>
24+
/// <param name="keypoints"></param>
25+
/// <param name="descriptors"></param>
26+
public ImageFeatures(int imgIdx, Size imgSize, IReadOnlyList<KeyPoint> keypoints, Mat descriptors)
27+
{
28+
ImgIdx = imgIdx;
29+
ImgSize = imgSize;
30+
Keypoints = keypoints;
31+
Descriptors = descriptors;
32+
}
33+
34+
~ImageFeatures()
35+
{
36+
Dispose(false);
37+
}
38+
39+
protected virtual void Dispose(bool disposing)
40+
{
41+
if (disposing)
42+
{
43+
Descriptors.Dispose();
44+
}
45+
}
46+
47+
public void Dispose()
48+
{
49+
Dispose(true);
50+
GC.SuppressFinalize(this);
51+
}
52+
}
53+
54+
#pragma warning restore 1591
55+
[StructLayout(LayoutKind.Sequential)]
56+
public struct WImageFeatures
57+
{
58+
public int ImgIdx;
59+
public Size ImgSize;
60+
public IntPtr Keypoints;
61+
public IntPtr Descriptors;
62+
}
63+
#pragma warning restore 1591
64+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System;
2+
using System.Diagnostics.Contracts;
3+
using System.Runtime.InteropServices;
4+
using OpenCvSharp.Detail;
5+
6+
#pragma warning disable 1591
7+
#pragma warning disable CA1401 // P/Invokes should not be visible
8+
#pragma warning disable IDE1006 // Naming style
9+
10+
namespace OpenCvSharp
11+
{
12+
13+
static partial class NativeMethods
14+
{
15+
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
16+
public static extern ExceptionStatus stitching_computeImageFeatures1_1(
17+
IntPtr featuresFinder,
18+
IntPtr[] images,
19+
int imagesLength,
20+
IntPtr[] features,
21+
IntPtr[] masks);
22+
23+
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
24+
public static extern ExceptionStatus stitching_computeImageFeatures1_2(
25+
IntPtr featuresFinder,
26+
IntPtr[] images,
27+
int imagesLength,
28+
IntPtr[] features,
29+
IntPtr masks);
30+
31+
[Pure, DllImport(DllExtern, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
32+
public static extern unsafe ExceptionStatus stitching_computeImageFeatures2(
33+
IntPtr featuresFinder,
34+
IntPtr image,
35+
WImageFeatures* features,
36+
IntPtr mask);
37+
}
38+
}

src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ copy "$(SolutionDir)opencv_files\opencv440_win_x64\x64\vc16\bin\opencv_videoio_f
319319
<ClInclude Include="text_TextDetector.h" />
320320
<ClInclude Include="tracking.h" />
321321
<ClInclude Include="tracking_MultiTracker.h" />
322+
<ClInclude Include="tracking_UnscentedKalmanFilter.h" />
322323
<ClInclude Include="videoio.h" />
323324
<ClInclude Include="video_tracking.h" />
324325
<ClInclude Include="photo.h" />

src/OpenCvSharpExtern/OpenCvSharpExtern.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@
342342
<ClInclude Include="ximgproc_SuperPixel.h">
343343
<Filter>Header Files\ximgproc</Filter>
344344
</ClInclude>
345+
<ClInclude Include="tracking_UnscentedKalmanFilter.h">
346+
<Filter>Header Files\tracking</Filter>
347+
</ClInclude>
345348
</ItemGroup>
346349
<ItemGroup>
347350
<Filter Include="Source Files">

0 commit comments

Comments
 (0)