CVB++ 15.0
training_set.hpp
1#pragma once
2
3#include "../_cexports/c_minos.h"
4
5#include "../global.hpp"
6#include "../image.hpp"
7#include "../matrix_2d.hpp"
8#include "../point_2d.hpp"
9#include "../rect.hpp"
10#include "../area_2d.hpp"
11
12#include "search_result.hpp"
13
14#include <vector>
15#include <climits>
16#include <utility>
17#include <memory>
18
19namespace Cvb
20{
21 CVB_BEGIN_INLINE_NS
22
23 namespace Minos
24 {
25 class TrainingSet;
26 }
27
28 template <>
29 inline HandleGuard<Minos::TrainingSet>::HandleGuard(void *handle) noexcept
30 : HandleGuard<Minos::TrainingSet>(handle, [](void *h) { CVB_CALL_CAPI(ReleaseObject(h)); })
31 {
32 }
33
35 namespace Minos
36 {
37
38 // forward declarations
39 class ImageInfo;
40 class ModelInfo;
41
43
45 class InstanceInfo
46 {
47 friend class InstanceInfoCollectionGeneric;
48 friend class ImageInstanceInfoCollection;
49 struct PrivateTag
50 {
51 };
52
53 public:
54 InstanceInfo(const InstanceInfo &other) = delete;
55 InstanceInfo &operator=(const InstanceInfo &other) = delete;
56 InstanceInfo(InstanceInfo &&other) = delete;
57 InstanceInfo &operator=(InstanceInfo &&other) = delete;
58 virtual ~InstanceInfo() = default;
59
60 InstanceInfo(const SharedHandleGuard<TrainingSet> &sguardTrSet, CExports::MTSINSTANCE nativeHandle, PrivateTag)
61 : sguardTrSet_(sguardTrSet)
62 , nativeHandle_(nativeHandle)
63 {
64 }
65
67
72 int Index() const
73 {
74 return static_cast<int>(CVB_CALL_CAPI(InstanceIndex(Handle())));
75 }
76
78
84 {
85 return Internal::DoHandleCallObjectOut<class Image>(CVB_CALL_CAPI(CreateImageFromInstance(Handle())));
86 }
87
89
94#if 0
95 double GetCorrelation () const
96 {
97 }
98#endif
99
101
107
109
115 {
116 double dX = CVB_CALL_CAPI(InstanceX(Handle()));
117 double dY = CVB_CALL_CAPI(InstanceY(Handle()));
118 return Point2D<double>(dX, dY);
119 }
120
122
128
130
136 void *Handle() const noexcept
137 {
138 return nativeHandle_;
139 }
140
141 private:
142 SharedHandleGuard<TrainingSet> sguardTrSet_;
143 CExports::MTSINSTANCE nativeHandle_;
144 }; /* class InstanceInfo */
145
147
154 inline bool operator==(const InstanceInfo &lhs, const InstanceInfo &rhs) noexcept
155 {
156 return (lhs.Handle() == rhs.Handle());
157 }
158
160
167 inline bool operator!=(const InstanceInfo &lhs, const InstanceInfo &rhs) noexcept
168 {
169 return (!(lhs == rhs));
170 }
171
172 namespace Private
173 {
174 template <class T>
175 auto ReadInfos(const T &collection) -> std::vector<decltype(collection.ReadInfo(0))>
176 {
177 auto count = collection.Count();
178 std::vector<decltype(collection.ReadInfo(0))> info;
179 for (decltype(count) i = 0; i < count; ++i)
180 {
181 info.push_back(collection.ReadInfo(i));
182 }
183
184 return info;
185 }
186
187 template <class Tcol, class Tobj>
188 int IndexOf(const Tcol &collection, const Tobj &obj)
189 {
190 auto count = collection.Count();
191 for (decltype(count) i = 0; i < count; ++i)
192 {
193 auto readInfo = collection.ReadInfo(i);
194 if (*readInfo == obj)
195 {
196 return i;
197 }
198 }
199 return -1;
200 }
201 } /* namespace Private */
202
204
206 class InstanceInfoCollectionGeneric
207 {
208 public:
209 explicit InstanceInfoCollectionGeneric(const SharedHandleGuard<TrainingSet> &sguard)
210 : shandle_(sguard)
211 {
212 }
213
214 InstanceInfoCollectionGeneric(const InstanceInfoCollectionGeneric &other) = delete;
215 InstanceInfoCollectionGeneric &operator=(const InstanceInfoCollectionGeneric &other) = delete;
216 InstanceInfoCollectionGeneric(InstanceInfoCollectionGeneric &&other) = delete;
217 InstanceInfoCollectionGeneric &operator=(InstanceInfoCollectionGeneric &&other) = delete;
218 virtual ~InstanceInfoCollectionGeneric() = default;
219
221
226 int Count() const
227 {
228 return GetCount();
229 }
230
232
239 {
240 auto instHandle = GetInstanceNativeHandle(index);
241 if (instHandle == nullptr)
242 {
243 Utilities::SystemInfo::ThrowLastError();
244 }
245 return std::make_unique<InstanceInfo>(shandle_, instHandle, InstanceInfo::PrivateTag{});
246 }
247
249
255 {
256 return Private::ReadInfos(*this);
257 }
258
260
268 int IndexOf(const InstanceInfo &obj) const
269 {
270 return Private::IndexOf(*this, obj);
271 }
272
274
284 bool Remove(const InstanceInfo &instance)
285 {
286 auto count = Count();
287 for (decltype(count) i = 0; i < count; ++i)
288 {
289 if (*ReadInfo(i) == instance)
290 {
291 CVB_CALL_CAPI_CHECKED(RemoveMTSInstance(instance.Handle()));
292 return true;
293 }
294 }
295 return false;
296 }
297
299
309 bool RemoveAt(int index)
310 {
311 return Remove(*ReadInfo(index));
312 }
313
314 protected:
315 virtual int GetCount() const = 0;
316 virtual CExports::MTSINSTANCE GetInstanceNativeHandle(int index) const = 0;
317
318 protected:
319 SharedHandleGuard<TrainingSet> shandle_; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
320 }; /* class InstanceInfoCollectionGeneric */
321
323
325 class InstanceInfoCollection : public InstanceInfoCollectionGeneric
326 {
327 public:
328 explicit InstanceInfoCollection(const SharedHandleGuard<TrainingSet> &sguard)
329 : InstanceInfoCollectionGeneric(sguard)
330 , collectionParent_(sguard.Handle())
331 {
332 }
333
334 protected:
335 int GetCount() const override
336 {
337 return static_cast<int>(CVB_CALL_CAPI(NumMTSInstances(collectionParent_)));
338 }
339
340 CExports::MTSINSTANCE GetInstanceNativeHandle(int index) const override
341 {
342 return CVB_CALL_CAPI(MTSInstance(collectionParent_, index));
343 }
344
345 private:
346 CExports::MTSINSTANCE collectionParent_;
347 }; /* class InstanceInfoCollection */
348
350
352 class ImageInstanceInfoCollection : public InstanceInfoCollectionGeneric
353 {
354 public:
355 ImageInstanceInfoCollection(const SharedHandleGuard<TrainingSet> &sguard, CExports::MTSIMAGE collectionParent)
356 : InstanceInfoCollectionGeneric(sguard)
357 , collectionParent_(collectionParent)
358 {
359 }
360
362
374 std::unique_ptr<InstanceInfo> Add(const String &name, bool askForce, Point2D<double> location)
375 {
376 double dX = location.X();
377 double dY = location.Y();
378 CExports::MTSINSTANCE instance = nullptr;
379 CVB_CALL_CAPI_CHECKED(NewMTSInstanceTyped(collectionParent_, name.c_str(), askForce, dX, dY, instance));
380 if (instance == nullptr)
381 {
382 throw std::runtime_error("failed to add sample to the class");
383 }
384 return std::make_unique<InstanceInfo>(shandle_, instance, InstanceInfo::PrivateTag{});
385 }
386
387 protected:
388 int GetCount() const override
389 {
390 return static_cast<int>(CVB_CALL_CAPI(NumMTSImageInstances(collectionParent_)));
391 }
392
393 CExports::MTSINSTANCE GetInstanceNativeHandle(int index) const override
394 {
395 return CVB_CALL_CAPI(MTSImageInstance(collectionParent_, index));
396 }
397
398 private:
399 CExports::MTSIMAGE collectionParent_;
400 }; /* class ImageInstanceInfoCollection */
401
403
405 class ModelInstanceInfoCollection : public InstanceInfoCollectionGeneric
406 {
407 public:
408 ModelInstanceInfoCollection(const SharedHandleGuard<TrainingSet> &sguard, CExports::MTSMODEL collectionParent)
409 : InstanceInfoCollectionGeneric(sguard)
410 , collectionParent_(collectionParent)
411 {
412 }
413
414 protected:
415 int GetCount() const override
416 {
417 return static_cast<int>(CVB_CALL_CAPI(NumMTSModelInstances(collectionParent_)));
418 }
419
420 CExports::MTSINSTANCE GetInstanceNativeHandle(int index) const override
421 {
422 return CVB_CALL_CAPI(MTSModelInstance(collectionParent_, index));
423 }
424
425 private:
426 CExports::MTSMODEL collectionParent_;
427 }; /* class ModelInstanceInfoCollection */
428
430
432 class ImageInfo
433 {
434 friend class InstanceInfo;
435 friend class ImageInfoCollection;
436
437 struct PrivateTag
438 {
439 };
440
441 public:
442 ImageInfo(const ImageInfo &other) = delete;
443 ImageInfo &operator=(const ImageInfo &other) = delete;
444 ImageInfo(ImageInfo &&other) = delete;
445 ImageInfo &operator=(ImageInfo &&other) = delete;
446 virtual ~ImageInfo() = default;
447
448 ImageInfo(const SharedHandleGuard<TrainingSet> &sguardTrSet, int index, PrivateTag)
449 : sguardTrSet_(sguardTrSet)
450 , nativeHandle_(CVB_CALL_CAPI(MTSImage(sguardTrSet.Handle(), index)))
451 , instances_(sguardTrSet_, nativeHandle_)
452 {
453 if (nativeHandle_ == nullptr)
454 {
455 Utilities::SystemInfo::ThrowLastError();
456 }
457 }
458
459 public:
461
466 int Index() const
467 {
468 return static_cast<int>(CVB_CALL_CAPI(MTSImageIndex(Handle())));
469 }
470
472
478 {
479 return Internal::DoBoolCallObjectOut<class Image>([&](void *&resimg) {
480 resimg = CVB_CALL_CAPI(GetImageFromImage(Handle()));
481 return CVB_CALL_CAPI(ShareObject(resimg));
482 });
483 }
484
486
492 {
493 /* Note: the binary compatibility between Matrix and TMatrix is guaranteed, therefore the cast below is legal.
494 */
495 CVB_CALL_CAPI_CHECKED(TransformMTSImage(Handle(), reinterpret_cast<const CExports::TMatrix &>(matrix)));
496 }
497
499
506 std::vector<SearchResult> CheckConsistency(double threshold, double density = 1.0)
507 {
508 CExports::RESULTS hSearchResults = nullptr;
509 CVB_CALL_CAPI_CHECKED(
510 MTSImageCheck(Handle(), threshold, static_cast<int>(density * 1000.0), nullptr, nullptr, hSearchResults));
511 ReleaseObjectGuard hSearchResHolder(hSearchResults);
512 return Private::SearchResultsToArray(hSearchResults);
513 }
514
516
524 {
525 return instances_;
526 }
527
529
535 void *Handle() const noexcept
536 {
537 return nativeHandle_;
538 }
539
540 private:
541 SharedHandleGuard<TrainingSet> sguardTrSet_;
542 CExports::MTSIMAGE nativeHandle_;
544 }; /* class ImageInfo*/
545
547
554 inline bool operator==(const ImageInfo &lhs, const ImageInfo &rhs) noexcept
555 {
556 return (lhs.Handle() == rhs.Handle());
557 }
558
560
567 inline bool operator!=(const ImageInfo &lhs, const ImageInfo &rhs) noexcept
568 {
569 return (!(lhs == rhs));
570 }
571
573 {
574 auto imageIndex = CVB_CALL_CAPI(GetImageFromInstance(Handle()));
575 return std::make_unique<ImageInfo>(sguardTrSet_, CVB_CALL_CAPI(MTSImageIndex(imageIndex)),
576 ImageInfo::PrivateTag{});
577 }
578
580
582 class ImageInfoCollection
583 {
584 public:
585 explicit ImageInfoCollection(const SharedHandleGuard<TrainingSet> &sguard)
586 : shandle_(sguard)
587 {
588 }
589
590 ImageInfoCollection(const ImageInfoCollection &other) = delete;
591 ImageInfoCollection &operator=(const ImageInfoCollection &other) = delete;
592 ImageInfoCollection(ImageInfoCollection &&other) = delete;
593 ImageInfoCollection &operator=(ImageInfoCollection &&other) = delete;
594 virtual ~ImageInfoCollection() = default;
595
597
602 int Count() const
603 {
604 return static_cast<int>(CVB_CALL_CAPI(NumMTSImages(shandle_.Handle())));
605 }
606
608
615 {
616 return std::make_unique<ImageInfo>(shandle_, index, ImageInfo::PrivateTag{});
617 }
618
620
626 {
627 return Private::ReadInfos(*this);
628 }
629
631
639 int IndexOf(const ImageInfo &obj) const
640 {
641 return Private::IndexOf(*this, obj);
642 }
643
645
653 void Add(const ImagePlane &plane)
654 {
655 auto h = CVB_CALL_CAPI(NewMTSImageIndex(shandle_.Handle(), plane.Parent().Handle(), plane.Plane()));
656 if (h == nullptr)
657 {
658 Utilities::SystemInfo::ThrowLastError();
659 }
660 }
661
663
673 bool Remove(const ImageInfo &image)
674 {
675 auto count = Count();
676 for (decltype(count) i = 0; i < count; ++i)
677 {
678 if (*ReadInfo(i) == image)
679 {
680 CVB_CALL_CAPI_CHECKED(RemoveMTSImage(image.Handle()));
681 return true;
682 }
683 }
684 return false;
685 }
686
688
698 bool RemoveAt(int index)
699 {
700 return Remove(*ReadInfo(index));
701 }
702
703 private:
704 SharedHandleGuard<TrainingSet> shandle_;
705 }; /* class ImageInfoCollection */
706
708
710 class ModelInfo
711 {
712 friend class InstanceInfo;
713 friend class ModelInfoCollection;
714 struct PrivateTag
715 {
716 };
717
718 public:
719 ModelInfo(const ModelInfo &other) = delete;
720 ModelInfo &operator=(const ModelInfo &other) = delete;
721 ModelInfo(ModelInfo &&other) = delete;
722 ModelInfo &operator=(ModelInfo &&other) = delete;
723 virtual ~ModelInfo() = default;
724
725 ModelInfo(const SharedHandleGuard<TrainingSet> &sguardTrSet, int index, PrivateTag)
726 : sguardTrSet_(sguardTrSet)
727 , nativeHandle_(CVB_CALL_CAPI(MTSModel(sguardTrSet.Handle(), index)))
728 , instances_(sguardTrSet_, nativeHandle_)
729 {
730 if (nativeHandle_ == nullptr)
731 {
732 Utilities::SystemInfo::ThrowLastError();
733 }
734 }
735
736 public:
738
743 int Index() const
744 {
745 return static_cast<int>(CVB_CALL_CAPI(MTSModelIndex(Handle())));
746 }
747
749
755 {
756 return Internal::DoBoolCallObjectOut<class Image>([&](void *&resimg) {
757 resimg = CVB_CALL_CAPI(GetImageFromModel(Handle()));
758 return CVB_CALL_CAPI(ShareObject(resimg));
759 });
760 }
761
763
767 String Name() const
768 {
769 const Char *name = nullptr;
770 CVB_CALL_CAPI(GetModelNameTyped(Handle(), name));
771 return (name != nullptr) ? String(name) : String();
772 }
773
775
784 void SetName(const String &name)
785 {
786 CVB_CALL_CAPI_CHECKED(SetModelNameTyped(Handle(), name.c_str()));
787 }
788
790
795 {
797 CVB_CALL_CAPI_CHECKED(GetModelAdvance(Handle(), advX, advY));
798 return Point2D<double>(advX, advY);
799 }
800
802
807 {
808 CVB_CALL_CAPI_CHECKED(SetModelAdvance(Handle(), advanceVector.X(), advanceVector.Y()));
809 }
810
812
817 {
818 /* Note: the binary compatibility between Area2D and TArea is guaranteed, therefore the cast below is legal. */
819 Area2D featureWindowNative;
820 CVB_CALL_CAPI_CHECKED(GetFeatureWindow(Handle(), reinterpret_cast<CExports::TArea &>(featureWindowNative)));
821 return Round(Rect<double>(featureWindowNative.P0().X(), featureWindowNative.P0().Y(),
822 featureWindowNative.P1().X(), featureWindowNative.P2().Y()));
823 }
824
826
830 void SetFeatureWindow(Rect<int> featureWindow)
831 {
832 /* Note: the binary compatibility between Area2D and TArea is guaranteed, therefore the cast below is legal. */
833 auto featureWindowNative = Area2D(static_cast<Rect<double>>(featureWindow));
834 CVB_CALL_CAPI_CHECKED(SetFeatureWindow(Handle(), reinterpret_cast<CExports::TArea &>(featureWindowNative)));
835 }
836
838
843 {
844 return Image()->CoordinateSystem().Translation();
845 }
846
848
853 {
854 auto cs = Image()->CoordinateSystem();
855 cs.Translation() = origin;
856 Image()->CoordinateSystem() = cs;
857 CVB_CALL_CAPI_CHECKED(TranslateModelOrigin(Handle()));
858 }
859
861
869 {
870 return instances_;
871 }
872
875
883 std::vector<SearchResult> CheckConsistency(const ImageInfo &trainingSetImage, double threshold,
884 double density = 1.0)
885 {
886 CExports::RESULTS hSearchResults = nullptr;
887 CVB_CALL_CAPI_CHECKED(MTSModelImageCheck(Handle(), trainingSetImage.Handle(), threshold,
888 static_cast<int>(density * 1000.0), nullptr, nullptr, hSearchResults));
889 ReleaseObjectGuard hSearchResHolder(hSearchResults);
890 return Private::SearchResultsToArray(hSearchResults);
891 }
892
895
902 std::vector<SearchResult> CheckConsistency(double threshold, double density = 1.0)
903 {
904 CExports::RESULTS hSearchResults = nullptr;
905 CVB_CALL_CAPI_CHECKED(
906 MTSModelCheck(Handle(), threshold, static_cast<int>(density * 1000.0), nullptr, nullptr, hSearchResults));
907 ReleaseObjectGuard hSearchResHolder(hSearchResults);
908 return Private::SearchResultsToArray(hSearchResults);
909 }
910
912
922 {
923 int left = INT_MAX, top = INT_MAX, right = INT_MAX, bottom = INT_MAX;
924
925 for (auto &&i : instances_.ReadInfos())
926 {
927 auto loc_x = static_cast<int>(std::lround(i->Location().X()));
928 if (loc_x < left)
929 {
930 left = loc_x;
931 }
932 auto loc_y = static_cast<int>(std::lround(i->Location().Y()));
933 if (loc_y < top)
934 {
935 top = loc_y;
936 }
937 auto srcimg_w = i->SourceImage()->Image()->Width();
938 if (srcimg_w - loc_x < right)
939 {
940 right = srcimg_w - loc_x - 1;
941 }
942 auto srcimg_h = i->SourceImage()->Image()->Height();
943 if (srcimg_h - loc_y < bottom)
944 {
945 bottom = srcimg_h - loc_y - 1;
946 }
947 }
948 left = -left;
949 top = -top;
950
951 return Rect<int>(left, top, right, bottom);
952 }
953
956
962 {
963 int left = -FeatureWindow().Left();
964 int top = -FeatureWindow().Top();
965 int right = image.Image()->Width() - FeatureWindow().Right() - 1;
966 int bottom = image.Image()->Height() - FeatureWindow().Bottom() - 1;
967 return Rect<int>(left, top, right, bottom);
968 }
969
971
977 void *Handle() const noexcept
978 {
979 return nativeHandle_;
980 }
981
982 private:
983 SharedHandleGuard<TrainingSet> sguardTrSet_;
984 CExports::MTSMODEL nativeHandle_;
986 }; /* class ModelInfo */
987
989
996 inline bool operator==(const ModelInfo &lhs, const ModelInfo &rhs) noexcept
997 {
998 return (lhs.Handle() == rhs.Handle());
999 }
1000
1002
1009 inline bool operator!=(const ModelInfo &lhs, const ModelInfo &rhs) noexcept
1010 {
1011 return (!(lhs == rhs));
1012 }
1013
1015 {
1016 auto modelIndex = CVB_CALL_CAPI(GetModelFromInstance(nativeHandle_));
1017 return std::make_unique<ModelInfo>(sguardTrSet_, CVB_CALL_CAPI(MTSModelIndex(modelIndex)),
1018 ModelInfo::PrivateTag{});
1019 }
1020
1022
1024 class ModelInfoCollection
1025 {
1026 public:
1027 explicit ModelInfoCollection(const SharedHandleGuard<TrainingSet> &sguard)
1028 : shandle_(sguard)
1029 {
1030 }
1031
1032 ModelInfoCollection(const ModelInfoCollection &) noexcept = delete;
1033 ModelInfoCollection &operator=(const ModelInfoCollection &) noexcept = delete;
1034 ModelInfoCollection(ModelInfoCollection &&other) noexcept = delete;
1035 ModelInfoCollection &operator=(ModelInfoCollection &&other) noexcept = delete;
1036 ~ModelInfoCollection() = default;
1037
1039
1044 int Count() const
1045 {
1046 return static_cast<int>(CVB_CALL_CAPI(NumMTSModels(shandle_.Handle())));
1047 }
1048
1050
1057 {
1058 return std::make_unique<ModelInfo>(shandle_, index, ModelInfo::PrivateTag{});
1059 }
1060
1062
1068 {
1069 return Private::ReadInfos(*this);
1070 }
1071
1073
1081 int IndexOf(const ModelInfo &obj) const
1082 {
1083 return Private::IndexOf(*this, obj);
1084 }
1085
1087
1093 bool Contains(const String &name)
1094 {
1095 auto count = Count();
1096 for (decltype(count) i = 0; i < count; ++i)
1097 {
1098 if (ReadInfo(i)->Name() == name)
1099 {
1100 return true;
1101 }
1102 }
1103 return false;
1104 }
1105
1107
1116 void Add(const ImageInfo &image, const String &name, Point2D<double> location, Rect<int> featureWindow)
1117 {
1118 /* Note: the binary compatibility between Area2D and TArea is guaranteed, therefore the cast below is legal. */
1119 auto featureWindowNative = Area2D(static_cast<Rect<double>>(featureWindow));
1120 auto instance = CVB_CALL_CAPI(NewMTSModelTyped(image.Handle(), name.c_str(), location.X(), location.Y(),
1121 reinterpret_cast<CExports::TArea &>(featureWindowNative)));
1122 if (instance == nullptr)
1123 {
1124 Utilities::SystemInfo::ThrowLastError();
1125 }
1126 }
1127
1129
1139 bool Remove(const ModelInfo &model)
1140 {
1141 auto count = Count();
1142 for (decltype(count) i = 0; i < count; ++i)
1143 {
1144 if (*ReadInfo(i) == model)
1145 {
1146 CVB_CALL_CAPI_CHECKED(RemoveMTSModel(model.Handle()));
1147 return true;
1148 }
1149 }
1150 return false;
1151 }
1152
1154
1164 bool RemoveAt(int index)
1165 {
1166 return Remove(*ReadInfo(index));
1167 }
1168
1170
1176 {
1177 CVB_CALL_CAPI_CHECKED(SetMTSGlobalAdvance(shandle_.Handle(), true, vec.X(), vec.Y()));
1178 }
1179
1180 private:
1181 SharedHandleGuard<TrainingSet> shandle_;
1182 }; /* class ModelInfoCollection */
1183
1185
1187 class TrainingSet
1188 {
1189 private:
1190 // Internal helper constructor version
1191 explicit TrainingSet(HandleGuard<TrainingSet> &&guard, const String &srcFileName = String())
1192 : shandle_(std::move(guard))
1193 , fileName_(srcFileName)
1194 , instances_(shandle_)
1195 , images_(shandle_)
1196 , models_(shandle_)
1197 {
1198 }
1199
1200 // Helper to create an empty training set
1201 static CExports::MTS CreateInternal()
1202 {
1203 CExports::MTS mts = CVB_CALL_CAPI(CreateMTS(3, 0.6));
1204 if (mts == nullptr)
1205 {
1206 Utilities::SystemInfo::ThrowLastError();
1207 }
1208 return mts;
1209 }
1210
1211 // Helper to load a training set from file
1212 static CExports::MTS LoadInternal(const String &fileName)
1213 {
1214 CExports::MTS mts = nullptr;
1215
1216 CVB_CALL_CAPI_CHECKED(LoadMTSFileTyped(fileName.c_str(), mts));
1217 return mts;
1218 }
1219
1220 public:
1222
1226 : TrainingSet(HandleGuard<TrainingSet>(CreateInternal()))
1227 {
1228 }
1229
1231
1235 explicit TrainingSet(const String &fileName)
1236 : TrainingSet(HandleGuard<TrainingSet>(LoadInternal(fileName)), fileName)
1237 {
1238 }
1239
1240 TrainingSet(const TrainingSet &other) = delete;
1241 TrainingSet &operator=(const TrainingSet &other) = delete;
1242 TrainingSet(TrainingSet &&other) = delete;
1243 TrainingSet &operator=(TrainingSet &&other) = delete;
1244 ~TrainingSet() = default;
1245
1246 public:
1248
1254 {
1255 return std::make_unique<TrainingSet>(fileName);
1256 }
1257
1259
1265 static std::unique_ptr<TrainingSet> FromBuffer(const void *buffer, size_t size)
1266 {
1267 return Internal::DoBoolCallObjectOut<TrainingSet>([&](void *&restset) {
1268 /* Note: need to cast-away const of "buffer" parameter to match the C-API, the function does not modify it. */
1269 return CVB_CALL_CAPI(MemoryToMTS(const_cast<void *>(buffer), static_cast<long>(size),
1270 restset)); // NOLINT(cppcoreguidelines-pro-type-const-cast)
1271 });
1272 }
1273
1275
1280 template <class RANGE>
1281 static typename TypedRange<std::unique_ptr<TrainingSet>, std::uint8_t, RANGE>::type
1282 FromBuffer(const RANGE &buffer)
1283 {
1284 auto bufferRange = MakeRangeAdapter<std::uint8_t>(buffer);
1285 return FromBuffer(bufferRange.Data(), bufferRange.Size());
1286 }
1287
1289
1295 void *Handle() const noexcept
1296 {
1297 return shandle_.Handle();
1298 }
1299
1301
1308 static std::unique_ptr<TrainingSet> FromHandle(HandleGuard<TrainingSet> &&guard)
1309 {
1310 if (!guard.Handle())
1311 {
1312 throw std::invalid_argument("invalid training set native handle");
1313 }
1315 }
1316
1318
1324 void Save(const String &fileName) const
1325 {
1326 CVB_CALL_CAPI_CHECKED(WriteMTSFileTyped(Handle(), fileName.c_str()));
1327 fileName_ = fileName;
1328 }
1329
1331
1337 {
1338 auto sizeNeeded = CVB_CALL_CAPI(GetMTSSize(Handle()));
1339 std::vector<std::uint8_t> buffer(sizeNeeded);
1340 CVB_CALL_CAPI_CHECKED(MTSToMemory(Handle(), buffer.data(), sizeNeeded));
1341 return buffer;
1342 }
1343
1345
1352 {
1353 return Internal::DoBoolCallObjectOut<TrainingSet>([&](void *&resclas) {
1354 /* Note: the binary compatibility between Matrix and TMatrix is guaranteed, therefore the cast below is legal.
1355 */
1356 return CVB_CALL_CAPI(
1357 MTSTransform(Handle(), reinterpret_cast<const CExports::TMatrix &>(transformation), resclas));
1358 });
1359 }
1360
1363
1370 std::vector<SearchResult> CheckConsistency(double threshold, double density = 1.0)
1371 {
1372 CExports::RESULTS hSearchResults = nullptr;
1373 CVB_CALL_CAPI_CHECKED(MTSConsistencyCheck(Handle(), threshold, static_cast<int>(density * 1000.0), nullptr,
1374 nullptr, hSearchResults));
1375 ReleaseObjectGuard hSearchResHolder(hSearchResults);
1376 return Private::SearchResultsToArray(hSearchResults);
1377 }
1378
1380
1388 int ClassCount() const
1389 {
1390 return static_cast<int>(CVB_CALL_CAPI(NumMTSClasses(Handle())));
1391 }
1392
1394
1402 {
1403 return instances_;
1404 }
1405
1407
1411 int InstancesTotal() const
1412 {
1413 return instances_.Count();
1414 }
1415
1417
1425 {
1426 return images_;
1427 }
1428
1430
1438 {
1439 return models_;
1440 }
1441
1444
1449 {
1450 return fileName_;
1451 }
1452
1454
1460 bool IsModified() const
1461 {
1462 CExports::cvbbool_t retval = false;
1463 CVB_CALL_CAPI_CHECKED(GetMTSModified(Handle(), retval));
1464 return retval != 0;
1465 }
1466
1468
1474 void SetIsModified(bool isModified)
1475 {
1476 CVB_CALL_CAPI_CHECKED(SetMTSModified(Handle(), isModified));
1477 }
1478
1480
1485 {
1486 CExports::cvbdim_t left = 0, top = 0, right = 0, bottom = 0;
1487 CVB_CALL_CAPI_CHECKED(GetMTSExtent(Handle(), left, top, right, bottom));
1488 return Rect<int>(static_cast<int>(left), static_cast<int>(top), static_cast<int>(right),
1489 static_cast<int>(bottom));
1490 }
1491
1493
1498 {
1499 Area2D area;
1500 /* Note: the binary compatibility between Area2D and TArea is guaranteed, therefore the cast below is legal. */
1501 CVB_CALL_CAPI_CHECKED(GetMTSLastFeatureWnd(Handle(), reinterpret_cast<CExports::TArea &>(area)));
1502 return Round(Rect<double>(area.P0().X(), area.P0().Y(), area.P1().X(), area.P2().Y()));
1503 }
1504
1506
1511 {
1512 const Char *comment = nullptr;
1513 CVB_CALL_CAPI(MTSCommentTyped(Handle(), comment));
1514 return (comment != nullptr) ? String(comment) : String();
1515 }
1516
1518
1522 void SetComment(String comment)
1523 {
1524 CVB_CALL_CAPI_CHECKED(SetMTSCommentTyped(Handle(), comment.c_str()));
1525 }
1526
1529
1533 double ExpectationRadius() const
1534 {
1535 double expectationRadius = std::numeric_limits<double>::quiet_NaN(),
1536 correlationThreshold = std::numeric_limits<double>::quiet_NaN();
1537 CVB_CALL_CAPI_CHECKED(GetMTSCorelParams(Handle(), expectationRadius, correlationThreshold));
1538 return expectationRadius;
1539 }
1540
1543
1547 void SetExpectationRadius(double expectationRadius)
1548 {
1549 CVB_CALL_CAPI_CHECKED(SetMTSCorelParams(Handle(), expectationRadius, CorrelationThreshold()));
1550 }
1551
1554
1559 {
1560 double expectationRadius = std::numeric_limits<double>::quiet_NaN(),
1561 correlationThreshold = std::numeric_limits<double>::quiet_NaN();
1562 CVB_CALL_CAPI_CHECKED(GetMTSCorelParams(Handle(), expectationRadius, correlationThreshold));
1563 return correlationThreshold;
1564 }
1565
1569
1573 void SetCorrelationThreshold(double correlationThreshold)
1574 {
1575 CVB_CALL_CAPI_CHECKED(SetMTSCorelParams(Handle(), ExpectationRadius(), correlationThreshold));
1576 }
1577
1578 private:
1579 SharedHandleGuard<TrainingSet> shandle_;
1580 mutable String fileName_;
1581 InstanceInfoCollection instances_;
1582 ImageInfoCollection images_;
1583 ModelInfoCollection models_;
1584 }; /* class TrainingSet */
1585
1588
1589 } /* namespace Minos */
1590 CVB_END_INLINE_NS
1591} /* namespace Cvb */
Structure that represents an area of interest in the image.
Definition area_2d.hpp:21
Point2D< double > P2() const noexcept
Gets P2 of the area (top right corner).
Definition area_2d.hpp:137
Point2D< double > P0() const noexcept
Gets P0 of the area (top left corner).
Definition area_2d.hpp:97
Point2D< double > P1() const noexcept
Gets P1 of the area (lower left corner).
Definition area_2d.hpp:117
void * Handle() const noexcept
Classic API image handle.
Definition decl_image.hpp:232
Image plane information container.
Definition decl_image_plane.hpp:29
int Plane() const noexcept
Plane index in the image, to which this plane refers to.
Definition decl_image_plane.hpp:147
const Image & Parent() const noexcept
Image to which this plane descriptor refers to.
Definition detail_image_plane.hpp:87
Double precision 2x2 matrix class.
Definition matrix_2d.hpp:16
Class that maintains the collection of Training Images inside a Minos Training Set.
Definition training_set.hpp:583
void Add(const ImagePlane &plane)
Add a new training set image to the parent training set.
Definition training_set.hpp:653
std::vector< std::unique_ptr< ImageInfo > > ReadInfos() const
Retrieves all the items stored in the collection.
Definition training_set.hpp:625
int Count() const
Retrieves the number of elements in the collection.
Definition training_set.hpp:602
int IndexOf(const ImageInfo &obj) const
Determine the index of an image information object inside this collection.
Definition training_set.hpp:639
bool Remove(const ImageInfo &image)
Remove a training set image along with its instances from the training set.
Definition training_set.hpp:673
std::unique_ptr< ImageInfo > ReadInfo(int index) const
Retrieves the indexed image information block.
Definition training_set.hpp:614
bool RemoveAt(int index)
Remove a training set image along with its instances from the training set.
Definition training_set.hpp:698
Image that has been added to a training set.
Definition training_set.hpp:433
std::vector< SearchResult > CheckConsistency(double threshold, double density=1.0)
Test this image for potentially forgotten instances to be trained.
Definition training_set.hpp:506
void TransformImageAndInstances(Matrix2D matrix)
Transform this image and all instances trained from this image using a 2x2 matrix.
Definition training_set.hpp:491
std::unique_ptr< class Image > Image() const
Image representation of this object.
Definition training_set.hpp:477
int Index() const
Index of this object in the parent's collection.
Definition training_set.hpp:466
ImageInstanceInfoCollection & Instances()
The instances belonging to this model.
Definition training_set.hpp:523
void * Handle() const noexcept
Classic API MTSIMAGE handle.
Definition training_set.hpp:535
Class that maintains the collection of Training Images inside a Minos Training Set.
Definition training_set.hpp:353
std::unique_ptr< InstanceInfo > Add(const String &name, bool askForce, Point2D< double > location)
Extract a new instance from the parent image and added it to the model with the specified name.
Definition training_set.hpp:374
std::unique_ptr< InstanceInfo > ReadInfo(int index) const
Retrieves the indexed instance information block.
Definition training_set.hpp:238
int Count() const
Retrieves the number of elements in the collection.
Definition training_set.hpp:226
std::vector< std::unique_ptr< InstanceInfo > > ReadInfos() const
Retrieves all the items stored in the collection.
Definition training_set.hpp:254
bool Remove(const InstanceInfo &instance)
Remove an instance from the training set.
Definition training_set.hpp:284
int IndexOf(const InstanceInfo &obj) const
Determine the index of an image information object inside this collection.
Definition training_set.hpp:268
bool RemoveAt(int index)
Remove an instance from the training set.
Definition training_set.hpp:309
Class that maintains the collection of Training Images inside a Minos Training Set.
Definition training_set.hpp:326
Instance information that has been added to a training set.
Definition training_set.hpp:46
std::unique_ptr< ModelInfo > Model() const
The Training Set Model into which this instance has been trained.
Definition training_set.hpp:1014
std::unique_ptr< class Image > Image() const
Image representation of this object.
Definition training_set.hpp:83
int Index() const
Index of this object in the parent's collection.
Definition training_set.hpp:72
Point2D< double > Location() const
Position in the SourceImage from which this instance has been extracted.
Definition training_set.hpp:114
std::unique_ptr< ImageInfo > SourceImage() const
Retrieve the correlation between this instance image and the model image.
Definition training_set.hpp:572
void * Handle() const noexcept
Classic API MTSINSTANCE handle.
Definition training_set.hpp:136
Class that maintains the collection of Training Images inside a Minos Training Set.
Definition training_set.hpp:1025
bool Remove(const ModelInfo &model)
Remove a model (and all the instances extracted for that model!) from the training set.
Definition training_set.hpp:1139
std::vector< std::unique_ptr< ModelInfo > > ReadInfos() const
Retrieves all the items stored in the collection.
Definition training_set.hpp:1067
std::unique_ptr< ModelInfo > ReadInfo(int index) const
Retrieves the indexed model information block.
Definition training_set.hpp:1056
int Count() const
Retrieves the number of elements in the collection.
Definition training_set.hpp:1044
bool Contains(const String &name)
Check if the collection contains a model with the specified name.
Definition training_set.hpp:1093
int IndexOf(const ModelInfo &obj) const
Determine the index of an image information object inside this collection.
Definition training_set.hpp:1081
void SetGlobalAdvanceVector(Point2D< double > vec)
Set an advance vector for all available models.
Definition training_set.hpp:1175
void Add(const ImageInfo &image, const String &name, Point2D< double > location, Rect< int > featureWindow)
Add a new model (plus the first instance of that model) to the training set.
Definition training_set.hpp:1116
bool RemoveAt(int index)
Remove a model (and all the instances extracted for that model!) from the training set.
Definition training_set.hpp:1164
Model that has been added to a training set.
Definition training_set.hpp:711
const ModelInstanceInfoCollection & Instances() const
The instances belonging to this model.
Definition training_set.hpp:868
std::vector< SearchResult > CheckConsistency(double threshold, double density=1.0)
Test all images in the parent training set for instances of this model that might have been forgotten...
Definition training_set.hpp:902
Rect< int > GetExtractableArea(const ImageInfo &image) const
Determine the maximum area from which an instance of this model may be extracted from a given trainin...
Definition training_set.hpp:961
Point2D< double > AdvanceVector() const
Get the advance vector associated with this model.
Definition training_set.hpp:794
Point2D< double > Origin() const
Get the origin of the model in terms of coordinates inside the feature window.
Definition training_set.hpp:842
std::vector< SearchResult > CheckConsistency(const ImageInfo &trainingSetImage, double threshold, double density=1.0)
Test the image referenced by trainingSetImage for instances of this model that might have been forgot...
Definition training_set.hpp:883
void SetAdvanceVector(Point2D< double > advanceVector)
Set the advance vector associated with this model.
Definition training_set.hpp:806
std::unique_ptr< class Image > Image() const
Image representation of this object.
Definition training_set.hpp:754
String Name() const
Get the name of the model.
Definition training_set.hpp:767
void SetFeatureWindow(Rect< int > featureWindow)
Set the feature window for this model.
Definition training_set.hpp:830
int Index() const
Index of this object in the parent's collection.
Definition training_set.hpp:743
void SetOrigin(Point2D< double > origin)
Set the origin of the model in terms of coordinates inside the feature window.
Definition training_set.hpp:852
Rect< int > GetMaxFeatureWindow() const
Retrieve the maximum values that may be set as feature window for this model.
Definition training_set.hpp:921
void SetName(const String &name)
Set the name of the model.
Definition training_set.hpp:784
Rect< int > FeatureWindow() const
Get the feature window for this model.
Definition training_set.hpp:816
void * Handle() const noexcept
Classic API MTSMODEL handle.
Definition training_set.hpp:977
Class that maintains the collection of Training Images inside a Minos Training Set.
Definition training_set.hpp:406
A Minos Training Set from which a classifier can be generated.
Definition training_set.hpp:1188
static TypedRange< std::unique_ptr< TrainingSet >, std::uint8_t, RANGE >::type FromBuffer(const RANGE &buffer)
Recreate a serialized Minos training set from a byte array.
Definition training_set.hpp:1282
std::unique_ptr< TrainingSet > Transform(Matrix2D transformation)
Generate a new training set by transforming this training set with a 2x2 transformation matrix.
Definition training_set.hpp:1351
std::vector< SearchResult > CheckConsistency(double threshold, double density=1.0)
Test all images in the parent training set for instances of this model that might have been forgotten...
Definition training_set.hpp:1370
double CorrelationThreshold() const
Gets the correlation threshold. The correlation value under which Minos proposes generating a new mod...
Definition training_set.hpp:1558
int ClassCount() const
The number of identifiable classes inside this training set.
Definition training_set.hpp:1388
static std::unique_ptr< TrainingSet > FromBuffer(const void *buffer, size_t size)
Recreate a serialized Minos training set from a byte array.
Definition training_set.hpp:1265
void SetIsModified(bool isModified)
Set a flag that informs about unsaved modifications to the training set.
Definition training_set.hpp:1474
ModelInfoCollection & Models()
The models contained in this training set.
Definition training_set.hpp:1437
TrainingSet(const String &fileName)
Load a saved training set from a file.
Definition training_set.hpp:1235
static std::unique_ptr< TrainingSet > FromHandle(HandleGuard< TrainingSet > &&guard)
Creates training set from a classic API handle.
Definition training_set.hpp:1308
TrainingSet()
Create an empty training set.
Definition training_set.hpp:1225
String Comment() const
Get the comment assigned to the training set at generation time.
Definition training_set.hpp:1510
std::vector< std::uint8_t > ToBuffer() const
Serializes the training set into a buffer.
Definition training_set.hpp:1336
void SetExpectationRadius(double expectationRadius)
Set the expectation radius - the radius that is searched for the best occurrence of a sample,...
Definition training_set.hpp:1547
void Save(const String &fileName) const
Write the training set to a file.
Definition training_set.hpp:1324
Rect< int > Extent() const
Extent of the classes in the training set relative to the anchor point.
Definition training_set.hpp:1484
bool IsModified() const
Get a flag that informs about unsaved modifications to the training set.
Definition training_set.hpp:1460
void SetComment(String comment)
Set the comment assigned to the training set at generation time.
Definition training_set.hpp:1522
int InstancesTotal() const
Total number of instances currently trained in this training set.
Definition training_set.hpp:1411
static std::unique_ptr< TrainingSet > Load(const String &fileName)
Load a saved training set from a file.
Definition training_set.hpp:1253
Rect< int > LastFeatureWindow() const
Feature window of the last model that has been created for the training set.
Definition training_set.hpp:1497
void SetCorrelationThreshold(double correlationThreshold)
Set the correlation threshold - the correlation value below which Minos will suggest the generation o...
Definition training_set.hpp:1573
String FileName() const
Name of the file, from which this training set was loaded (empty string if this image list was neithe...
Definition training_set.hpp:1448
void * Handle() const noexcept
Classic API CLF handle.
Definition training_set.hpp:1295
ImageInfoCollection & Images()
The images contained in this training set.
Definition training_set.hpp:1424
InstanceInfoCollection & Instances()
The instances contained in this training set.
Definition training_set.hpp:1401
double ExpectationRadius() const
Get the expectation radius - the radius that is searched for the best occurrence of a sample,...
Definition training_set.hpp:1533
Multi-purpose 2D vector class.
Definition point_2d.hpp:20
T X() const noexcept
Gets the x-component of the point.
Definition point_2d.hpp:84
T Y() const noexcept
Gets the y-component of the point.
Definition point_2d.hpp:104
Rectangle object.
Definition rect.hpp:24
T Bottom() const noexcept
Gets bottom row of the rectangle (still inside the rectangle).
Definition rect.hpp:144
T Top() const noexcept
Gets first row of the rectangle.
Definition rect.hpp:104
T Right() const noexcept
Gets rightmost column of the rectangle (still inside the rectangle).
Definition rect.hpp:124
T Left() const noexcept
Gets first column of the rectangle.
Definition rect.hpp:84
T count(T... args)
cvbbool_t ShareObject(OBJ Object)
cvbbool_t ReleaseObject(OBJ &Object)
T move(T... args)
Namespace for the Minos package.
Definition classifier.hpp:29
bool operator==(const ClassifierModelInfo &lhs, const ClassifierModelInfo &rhs) noexcept
Comparison operator for ClassifierModelInfo objects.
Definition classifier.hpp:163
std::shared_ptr< TrainingSet > TrainingSetPtr
Convenience shared pointer for TrainingSet.
Definition training_set.hpp:1587
bool operator!=(const ClassifierModelInfo &lhs, const ClassifierModelInfo &rhs) noexcept
Comparison operator for ClassifierModelInfo objects.
Definition classifier.hpp:150
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
char Char
Character type for wide characters or unicode characters.
Definition string.hpp:63
std::string String
String for wide characters or unicode characters.
Definition string.hpp:49
Point2D< int > Round(const Point2D< T > &rhs) noexcept
Round to an integer point.
Definition point_2d.hpp:371
T quiet_NaN(T... args)
T lround(T... args)