1 /*
2 Copyright (c) 2019 Ferhat Kurtulmuş
3 Boost Software License - Version 1.0 - August 17th, 2003
4 Permission is hereby granted, free of charge, to any person or organization
5 obtaining a copy of the software and accompanying documentation covered by
6 this license (the "Software") to use, reproduce, display, distribute,
7 execute, and transmit the Software, and to prepare derivative works of the
8 Software, and to permit third-parties to whom the Software is furnished to
9 do so, all subject to the following:
10 The copyright notices in the Software and this entire statement, including
11 the above license grant, this restriction and the following disclaimer,
12 must be included in all copies of the Software, in whole or in part, and
13 all derivative works of the Software, unless such copies or derivative
14 works are solely in the form of machine-executable object code generated by
15 a source language processor.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
19 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
20 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
21 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24 
25 module opencvd.features2d;
26 
27 import std.conv;
28 
29 import opencvd.cvcore;
30 
31 private extern (C){
32     AKAZE AKAZE_Create();
33     void AKAZE_Close(AKAZE a);
34     KeyPoints AKAZE_Detect(AKAZE a, Mat src);
35     KeyPoints AKAZE_DetectAndCompute(AKAZE a, Mat src, Mat mask, Mat desc);
36     
37     AgastFeatureDetector AgastFeatureDetector_Create();
38     void AgastFeatureDetector_Close(AgastFeatureDetector a);
39     KeyPoints AgastFeatureDetector_Detect(AgastFeatureDetector a, Mat src);
40 
41     BRISK BRISK_Create();
42     void BRISK_Close(BRISK b);
43     KeyPoints BRISK_Detect(BRISK b, Mat src);
44     KeyPoints BRISK_DetectAndCompute(BRISK b, Mat src, Mat mask, Mat desc);
45 
46     FastFeatureDetector FastFeatureDetector_Create();
47     void FastFeatureDetector_Close(FastFeatureDetector f);
48     KeyPoints FastFeatureDetector_Detect(FastFeatureDetector f, Mat src);
49 
50     GFTTDetector GFTTDetector_Create();
51     void GFTTDetector_Close(GFTTDetector a);
52     KeyPoints GFTTDetector_Detect(GFTTDetector a, Mat src);
53 
54     KAZE KAZE_Create();
55     void KAZE_Close(KAZE a);
56     KeyPoints KAZE_Detect(KAZE a, Mat src);
57     KeyPoints KAZE_DetectAndCompute(KAZE a, Mat src, Mat mask, Mat desc);
58 
59     MSER MSER_Create();
60     void MSER_Close(MSER a);
61     KeyPoints MSER_Detect(MSER a, Mat src);
62 
63     ORB ORB_Create();
64     void ORB_Close(ORB o);
65     KeyPoints ORB_Detect(ORB o, Mat src);
66     KeyPoints ORB_DetectAndCompute(ORB o, Mat src, Mat mask, Mat desc);
67 
68     SimpleBlobDetector SimpleBlobDetector_Create();
69     void SimpleBlobDetector_Close(SimpleBlobDetector b);
70     KeyPoints SimpleBlobDetector_Detect(SimpleBlobDetector b, Mat src);
71 
72     BFMatcher BFMatcher_Create();
73     BFMatcher BFMatcher_CreateWithParams(int normType, bool crossCheck);
74     void BFMatcher_Close(BFMatcher b);
75     MultiDMatches BFMatcher_KnnMatch(BFMatcher b, Mat query, Mat train, int k);
76 
77     void DrawKeyPoints(Mat src, KeyPoints kp, Mat dst, const Scalar s, int flags);
78 }
79 
80 struct _AKAZE {
81     void* p;
82     
83     void close(){
84         AKAZE_Close(&this);
85     }
86     
87     KeyPoint[] detect(Mat src){
88         KeyPoints kpts = AKAZE_Detect(&this, src);
89         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
90         KeyPoints_Close(kpts);
91         return ret;
92     }
93     
94     KeyPoint[] detectAndCompute(Mat src, Mat mask, Mat desc){
95         KeyPoints kpts = AKAZE_DetectAndCompute(&this, src, mask, desc);
96         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
97         KeyPoints_Close(kpts);
98         return ret;
99     }
100 }
101 
102 alias AKAZE = _AKAZE*;
103 
104 AKAZE newAKAZE(){
105     return AKAZE_Create();
106 }
107 
108 struct _AgastFeatureDetector{
109     void* p;
110     
111     void close(AgastFeatureDetector a){
112         AgastFeatureDetector_Close(&this);
113     }
114     
115     KeyPoint[] detect(Mat src){
116         KeyPoints kpts = AgastFeatureDetector_Detect(&this, src);
117         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
118         KeyPoints_Close(kpts);
119         return ret;
120     }
121 }
122 
123 alias AgastFeatureDetector = _AgastFeatureDetector*;
124 
125 AgastFeatureDetector newAgastFeatureDetector(){
126     return AgastFeatureDetector_Create();
127 }
128 
129 struct _BRISK {
130     void* p;
131     
132     void close(){
133         BRISK_Close(&this);
134     }
135     
136     KeyPoint[] detect(Mat src){
137         KeyPoints kpts = BRISK_Detect(&this, src);
138         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
139         KeyPoints_Close(kpts);
140         return ret;
141     }
142     
143     KeyPoint[] detectAndCompute(Mat src, Mat mask, Mat desc){
144         KeyPoints kpts = BRISK_DetectAndCompute(&this, src, mask, desc);
145         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
146         KeyPoints_Close(kpts);
147         return ret;
148     }
149 }
150 
151 alias BRISK = _BRISK*;
152 
153 BRISK newBRISK(){
154     return BRISK_Create();
155 }
156 
157 struct _FastFeatureDetector {
158     void* p;
159     
160     void close(){
161         FastFeatureDetector_Close(&this);
162     }
163     
164     KeyPoint[] detect(Mat src){
165         KeyPoints kpts = FastFeatureDetector_Detect(&this, src);
166         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
167         KeyPoints_Close(kpts);
168         return ret;
169     }
170 }
171 
172 alias FastFeatureDetector = _FastFeatureDetector*;
173 
174 FastFeatureDetector newFastFeatureDetector(){
175     return FastFeatureDetector_Create();
176 }
177 
178 struct _GFTTDetector {
179     void* p;
180     
181     void close(){
182         GFTTDetector_Close(&this);
183     }
184     
185     KeyPoint[] detect(Mat src){
186         KeyPoints kpts = GFTTDetector_Detect(&this, src);
187         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
188         KeyPoints_Close(kpts);
189         return ret;
190     }
191 }
192 
193 alias GFTTDetector = _GFTTDetector*;
194 
195 GFTTDetector newGFTTDetector(){
196     return GFTTDetector_Create();
197 }
198 
199 struct _KAZE {
200     void* p;
201     
202     void close(){
203         KAZE_Close(&this);
204     }
205     
206     KeyPoint[] detect(Mat src){
207         KeyPoints kpts = KAZE_Detect(&this, src);
208         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
209         KeyPoints_Close(kpts);
210         return ret;
211     }
212     
213     KeyPoint[] detectAndCompute(Mat src, Mat mask, Mat desc){
214         KeyPoints kpts = KAZE_DetectAndCompute(&this, src, mask, desc);
215         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
216         KeyPoints_Close(kpts);
217         return ret;
218     }
219 }
220 
221 alias KAZE = _KAZE*;
222 
223 KAZE newKAZE(){
224     return KAZE_Create();
225 }
226 
227 struct _MSER {
228     void* p;
229     
230     void close(){
231         MSER_Close(&this);
232     }
233     
234     KeyPoint[] detect(Mat src){
235         KeyPoints kpts = MSER_Detect(&this, src);
236         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
237         KeyPoints_Close(kpts);
238         return ret;
239     }
240 }
241 alias MSER = _MSER*;
242 
243 MSER newMSER(){
244     return MSER_Create();
245 }
246 
247 struct _ORB {
248     void* p;
249     
250     void close(){
251         ORB_Close(&this);
252     }
253     
254     KeyPoint[] detect(Mat src){
255         KeyPoints kpts = ORB_Detect(&this, src);
256         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
257         KeyPoints_Close(kpts);
258         return ret;
259     }
260     
261     KeyPoint[] detectAndCompute(Mat src, Mat mask, Mat desc){
262         KeyPoints kpts = ORB_DetectAndCompute(&this, src, mask, desc);
263         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
264         KeyPoints_Close(kpts);
265         return ret;
266     }
267 }
268 
269 alias ORB = _ORB*;
270 
271 ORB newORB(){
272     return ORB_Create();
273 }
274 
275 struct _SimpleBlobDetector {
276     void* p;
277     
278     void close(){
279         SimpleBlobDetector_Close(&this);
280     }
281     
282     KeyPoint[] detect(Mat src){
283         KeyPoints kpts = SimpleBlobDetector_Detect(&this, src);
284         KeyPoint[] ret = kpts.keypoints[0..kpts.length].dup;
285         KeyPoints_Close(kpts);
286         return ret;
287     }
288 }
289 
290 alias SimpleBlobDetector = _SimpleBlobDetector*;
291 
292 SimpleBlobDetector newSimpleBlobDetector(){
293     return SimpleBlobDetector_Create();
294 }
295 
296 struct _BFMatcher {
297     void* p;
298     
299     void close(){
300         BFMatcher_Close(&this);
301     }
302     
303     DMatch[][] knnMatch(Mat query, Mat train, int k){
304         
305         MultiDMatches mdms = BFMatcher_KnnMatch(&this, query, train, k);
306         
307         DMatch[][] ret;
308         foreach(i; 0..mdms.length){
309             DMatches ds = mdms.dmatches[i];
310             DMatch[] dmats = ds.dmatches[0..ds.length].dup;
311             DMatches_Close(ds);
312             ret ~= dmats;
313         }
314         MultiDMatches_Close(mdms);
315         return ret;
316     }
317 }
318 
319 alias BFMatcher = _BFMatcher*;
320 
321 BFMatcher newBFMatcher(){
322     return BFMatcher_Create();
323 }
324 
325 BFMatcher newBFMatcherWithParams(int normType, bool crossCheck){
326     return BFMatcher_CreateWithParams(normType, crossCheck);
327 }
328 
329 enum: int { // cv::DrawMatchesFlags 
330     DrawMatchesFlags_DEFAULT = 0, 
331     DrawMatchesFlags_DRAW_OVER_OUTIMG = 1, 
332     DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS = 2, 
333     DrawMatchesFlags_DRAW_RICH_KEYPOINTS = 4 
334 }
335 
336 void drawKeyPoints(Mat src, KeyPoint[] kp, Mat dst,
337         const Scalar s = Scalar.all(-1), int flags = DrawMatchesFlags_DEFAULT){
338     DrawKeyPoints(src, KeyPoints(kp.ptr, kp.length.to!int), dst, s, flags);
339 }