Skip to content

Commit c9f6d33

Browse files
authored
Merge pull request #60 from rainyl/Innerverz-AI/main
New API: cv.Subdiv2D
2 parents 97a7d1d + d469061 commit c9f6d33

File tree

8 files changed

+996
-25
lines changed

8 files changed

+996
-25
lines changed

lib/src/imgproc/subdiv2d.dart

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
// ignore_for_file: constant_identifier_names
2+
3+
import 'dart:ffi' as ffi;
4+
import 'package:ffi/ffi.dart';
5+
6+
import '../core/base.dart';
7+
import '../core/cv_vec.dart';
8+
import '../core/point.dart';
9+
import '../core/rect.dart';
10+
import '../core/vec.dart';
11+
import '../opencv.g.dart' as cvg;
12+
13+
class Subdiv2D extends CvStruct<cvg.Subdiv2D> {
14+
Subdiv2D._(cvg.Subdiv2DPtr ptr) : super.fromPointer(ptr) {
15+
finalizer.attach(this, ptr.cast());
16+
}
17+
18+
factory Subdiv2D.empty() {
19+
final p = calloc<cvg.Subdiv2D>();
20+
cvRun(() => CFFI.Subdiv2D_NewEmpty(p));
21+
return Subdiv2D._(p);
22+
}
23+
24+
factory Subdiv2D.fromRect(Rect rect) {
25+
final p = calloc<cvg.Subdiv2D>();
26+
cvRun(() => CFFI.Subdiv2D_NewWithRect(rect.ref, p));
27+
return Subdiv2D._(p);
28+
}
29+
30+
static final finalizer = OcvFinalizer<cvg.Subdiv2DPtr>(CFFI.addresses.Subdiv2D_Close);
31+
32+
/// Returns the edge destination.
33+
///
34+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#aee192f95bf19c74619641496c457586d
35+
(int rval, Point2f dstpt) edgeDst(int edge) {
36+
return using<(int, Point2f)>((arena) {
37+
final pp = calloc<cvg.Point2f>();
38+
final p = arena<ffi.Int>();
39+
cvRun(() => CFFI.Subdiv2D_EdgeDst(ref, edge, pp, p));
40+
return (p.value, Point2f.fromPointer(pp));
41+
});
42+
}
43+
44+
/// Returns the edge origin.
45+
///
46+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a5563e3cae0a9b95df63e72f0c12f9389
47+
(int rval, Point2f orgpt) edgeOrg(int edge) {
48+
return using<(int, Point2f)>((arena) {
49+
final pp = calloc<cvg.Point2f>();
50+
final p = arena<ffi.Int>();
51+
cvRun(() => CFFI.Subdiv2D_EdgeOrg(ref, edge, pp, p));
52+
return (p.value, Point2f.fromPointer(pp));
53+
});
54+
}
55+
56+
/// Finds the subdivision vertex closest to the given point.
57+
///
58+
/// The function is another function that locates the input point within the subdivision.
59+
/// It finds the subdivision vertex that is the closest to the input point.
60+
/// It is not necessarily one of vertices of the facet containing the input point,
61+
/// though the facet (located using locate() ) is used as a starting point.
62+
///
63+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a3ec256af000e129e08eb5f269ccdeb0f
64+
(int rval, Point2f nearestPt) findNearest(Point2f pt) {
65+
return using<(int, Point2f)>((arena) {
66+
final pp = calloc<cvg.Point2f>();
67+
final p = arena<ffi.Int>();
68+
cvRun(() => CFFI.Subdiv2D_FindNearest(ref, pt.ref, pp, p));
69+
return (p.value, Point2f.fromPointer(pp));
70+
});
71+
}
72+
73+
/// Returns one of the edges related to the given edge.
74+
///
75+
/// [nextEdgeType] : Parameter specifying which of the related edges to return.
76+
/// The following values are possible:
77+
///
78+
/// - [NEXT_AROUND_ORG] next around the edge origin ( eOnext on the picture below if e is the input edge)
79+
/// - [NEXT_AROUND_DST] next around the edge vertex ( eDnext )
80+
/// - [PREV_AROUND_ORG] previous around the edge origin (reversed eRnext )
81+
/// - [PREV_AROUND_DST] previous around the edge destination (reversed eLnext )
82+
/// - [NEXT_AROUND_LEFT] next around the left facet ( eLnext )
83+
/// - [NEXT_AROUND_RIGHT] next around the right facet ( eRnext )
84+
/// - [PREV_AROUND_LEFT] previous around the left facet (reversed eOnext )
85+
/// - [PREV_AROUND_RIGHT] previous around the right facet (reversed eDnext )
86+
///
87+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#af73f08576709bad7a36f8f8e5fc43c84
88+
int getEdge(int edge, int nextEdgeType) {
89+
return using<int>((arena) {
90+
final p = arena<ffi.Int>();
91+
cvRun(() => CFFI.Subdiv2D_GetEdge(ref, edge, nextEdgeType, p));
92+
return p.value;
93+
});
94+
}
95+
96+
/// Returns a list of all edges.
97+
///
98+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#ab527c11e9938eed53cf9c790afa9416d
99+
List<Vec4f> getEdgeList() {
100+
return using<List<Vec4f>>((arena) {
101+
final pv = arena<ffi.Pointer<cvg.Vec4f>>();
102+
final psize = arena<ffi.Int>();
103+
cvRun(() => CFFI.Subdiv2D_GetEdgeList(ref, pv, psize));
104+
return List.generate(psize.value, (i) {
105+
final v = pv.value[i];
106+
return Vec4f(v.val1, v.val2, v.val3, v.val4);
107+
});
108+
});
109+
}
110+
111+
/// Returns a list of the leading edge ID connected to each triangle.
112+
///
113+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a2d02a1d66ef7f8f267beb549cb2823f1
114+
VecInt getLeadingEdgeList() {
115+
return using<VecInt>((arena) {
116+
final pv = VecInt();
117+
cvRun(() => CFFI.Subdiv2D_GetLeadingEdgeList(ref, pv.ptr));
118+
return pv;
119+
});
120+
}
121+
122+
/// Returns a list of all triangles.
123+
///
124+
/// The function gives each triangle as a 6 numbers vector, where each two are one of the triangle vertices.
125+
/// i.e. p1_x = v[0], p1_y = v[1], p2_x = v[2], p2_y = v[3], p3_x = v[4], p3_y = v[5].
126+
///
127+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a26bfe32209bc8ae9ecc53e93da01e466
128+
List<Vec6f> getTriangleList() {
129+
return using<List<Vec6f>>((arena) {
130+
final pv = arena<ffi.Pointer<cvg.Vec6f>>();
131+
final psize = arena<ffi.Int>();
132+
cvRun(() => CFFI.Subdiv2D_GetTriangleList(ref, pv, psize));
133+
return List.generate(psize.value, (i) {
134+
final v = pv.value[i];
135+
return Vec6f(v.val1, v.val2, v.val3, v.val4, v.val5, v.val6);
136+
});
137+
});
138+
}
139+
140+
/// Returns vertex location from vertex ID.
141+
///
142+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a5297daca30f90d1e6d0cc5a75ba76351
143+
(Point2f rval, int firstEdge) getVertex(int vertex) {
144+
return using<(Point2f, int)>((arena) {
145+
final pp = calloc<cvg.Point2f>();
146+
final p = arena<ffi.Int>();
147+
cvRun(() => CFFI.Subdiv2D_GetVertex(ref, vertex, p, pp));
148+
return (Point2f.fromPointer(pp), p.value);
149+
});
150+
}
151+
152+
/// Returns a list of all Voronoi facets.
153+
///
154+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a3a9e080423475be056a79da4c04741ea
155+
(VecVecPoint2f facetList, VecPoint2f facetCenters) getVoronoiFacetList(VecInt idx) {
156+
return using<(VecVecPoint2f, VecPoint2f)>((arena) {
157+
final pf = VecVecPoint2f.fromList([]);
158+
final pfc = VecPoint2f();
159+
cvRun(() => CFFI.Subdiv2D_GetVoronoiFacetList(ref, idx.ref, pf.ptr, pfc.ptr));
160+
return (pf, pfc);
161+
});
162+
}
163+
164+
/// Creates a new empty Delaunay subdivision.
165+
///
166+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#ae4a3d65e798c46fd6ce64370f24b0287
167+
void initDelaunay(Rect rect) {
168+
return using<void>((arena) {
169+
cvRun(() => CFFI.Subdiv2D_InitDelaunay(ref, rect.ref));
170+
});
171+
}
172+
173+
/// Insert multiple points into a Delaunay triangulation.
174+
///
175+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a37223a499032ef57364f1372ad0c9c2e
176+
int insert(Point2f pt) {
177+
return using<int>((arena) {
178+
final p = arena<ffi.Int>();
179+
cvRun(() => CFFI.Subdiv2D_Insert(ref, pt.ref, p));
180+
return p.value;
181+
});
182+
}
183+
184+
/// Insert a single point into a Delaunay triangulation.
185+
///
186+
/// The function locates the input point within the subdivision and gives one of the triangle edges or vertices.
187+
///
188+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a18a6c9999210d769538297d843c613f2
189+
void insertVec(VecPoint2f pv) {
190+
return using<void>((arena) {
191+
cvRun(() => CFFI.Subdiv2D_InsertVec(ref, pv.ref));
192+
});
193+
}
194+
195+
/// Returns the location of a point within a Delaunay triangulation.
196+
///
197+
/// [rval] an integer which specify one of the following five cases for point location:
198+
///
199+
/// - The point falls into some facet. The function returns [PTLOC_INSIDE] and edge will contain one of edges of the facet.
200+
/// - The point falls onto the edge. The function returns [PTLOC_ON_EDGE] and edge will contain this edge.
201+
/// - The point coincides with one of the subdivision vertices. The function returns [PTLOC_VERTEX] and vertex will contain a pointer to the vertex.
202+
/// - The point is outside the subdivision reference rectangle. The function returns [PTLOC_OUTSIDE_RECT] and no pointers are filled.
203+
/// - One of input arguments is invalid. A runtime error is raised or, if silent or "parent" error processing mode is selected, [PTLOC_ERROR] is returned.
204+
///
205+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#aec8f1fd5a802f62faa97520b465897d7
206+
(int rval, int edge, int vertex) locate(Point2f pt) {
207+
return using<(int, int, int)>((arena) {
208+
final edge = arena<ffi.Int>();
209+
final vertex = arena<ffi.Int>();
210+
final rval = arena<ffi.Int>();
211+
cvRun(() => CFFI.Subdiv2D_Locate(ref, pt.ref, edge, vertex, rval));
212+
return (rval.value, edge.value, vertex.value);
213+
});
214+
}
215+
216+
/// Returns next edge around the edge origin.
217+
///
218+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#a36ebf478e2546615c2db457106393acb
219+
int nextEdge(int edge) {
220+
return using<int>((arena) {
221+
final p = arena<ffi.Int>();
222+
cvRun(() => CFFI.Subdiv2D_NextEdge(ref, edge, p));
223+
return p.value;
224+
});
225+
}
226+
227+
/// Returns another edge of the same quad-edge.
228+
///
229+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#aa1179507f651b67c22e06517fbc6a145
230+
int rotateEdge(int edge, int rotate) {
231+
return using<int>((arena) {
232+
final p = arena<ffi.Int>();
233+
cvRun(() => CFFI.Subdiv2D_RotateEdge(ref, edge, rotate, p));
234+
return p.value;
235+
});
236+
}
237+
238+
/// https://docs.opencv.org/4.x/df/dbf/classcv_1_1Subdiv2D.html#aabbb10b8d5b0311b7e22040fc0db56b4
239+
int symEdge(int edge) {
240+
return using<int>((arena) {
241+
final p = arena<ffi.Int>();
242+
cvRun(() => CFFI.Subdiv2D_SymEdge(ref, edge, p));
243+
return p.value;
244+
});
245+
}
246+
247+
@override
248+
List<int> get props => [ptr.address];
249+
250+
@override
251+
cvg.Subdiv2D get ref => ptr.ref;
252+
253+
static const int NEXT_AROUND_ORG = 0x00;
254+
static const int NEXT_AROUND_DST = 0x22;
255+
static const int PREV_AROUND_ORG = 0x11;
256+
static const int PREV_AROUND_DST = 0x33;
257+
static const int NEXT_AROUND_LEFT = 0x13;
258+
static const int NEXT_AROUND_RIGHT = 0x31;
259+
static const int PREV_AROUND_LEFT = 0x20;
260+
static const int PREV_AROUND_RIGHT = 0x02;
261+
262+
static const int PTLOC_ERROR = -2;
263+
static const int PTLOC_OUTSIDE_RECT = -1;
264+
static const int PTLOC_INSIDE = 0;
265+
static const int PTLOC_VERTEX = 1;
266+
static const int PTLOC_ON_EDGE = 2;
267+
}

lib/src/opencv.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ export 'dnn/dnn.dart';
3232
export 'features2d/features2d.dart';
3333
export 'highgui/highgui.dart';
3434
export 'imgcodecs/imgcodecs.dart';
35+
3536
export 'imgproc/imgproc.dart';
37+
export 'imgproc/clahe.dart';
38+
export 'imgproc/subdiv2d.dart';
39+
3640
export 'objdetect/objdetect.dart';
3741
export 'photo/photo.dart';
3842
export 'svd/svd.dart';

0 commit comments

Comments
 (0)