CVB++ 14.0
classifier_factory.hpp
1#pragma once
2
3#include "../angle.hpp"
4#include "../value_range.hpp"
5#include "../point_2d.hpp"
6#include "../_detail/detail_pixel_list.hpp"
7#include "../image.hpp"
8
9#include "shapefinder2.hpp"
10#include "classifier.hpp"
11
12
13namespace Cvb
14{
15CVB_BEGIN_INLINE_NS
16
17
18
19namespace ShapeFinder2
20{
21
22
24
27{
28public:
29
31
34 ClassifierFactory() noexcept = default;
35 virtual ~ClassifierFactory() = default;
36
37
39
46 std::vector<int> GradientHistogram(const ImagePlane & plane, Rect<int> aoi, ShapeFinder2::GradientType gradient) const
47 {
48 if ((plane.DataType().BitsPerPixel() != 8) || (!plane.DataType().IsUnsignedInteger()))
49 std::rethrow_exception(CvbException::FromCvbResult(ErrorCodes::CVB_INVALIDDATATYPE, "invalid plane datatype"));
50
51 CExports::cvbval_t retval[256];
52 CExports::SFGradHistogram(plane.Parent().Handle(), plane.Plane(), aoi.Left(), aoi.Top(), aoi.Right(), aoi.Bottom(), static_cast<CExports::TSFGradientType>(gradient), &retval[0]);
53 return std::vector<int>(retval, retval + sizeof retval / sizeof retval[0]);
54 }
55
57
62 {
64 }
65
67
72 {
73 return rotationRange_;
74 }
75
77
82 {
83 if (value.Min() < RotationRangeMax().Min() || value.Max() > RotationRangeMax().Max())
84 throw std::out_of_range("rotation range must be in [-180.0, 180.0]");
85 rotationRange_ = value;
86 }
87
89
94 {
95 return ValueRange<double>(0.66, 1.50);
96 }
97
99
104 {
105 return scaleRange_;
106 }
107
109
114 {
115 if (value.Min() < ScaleRangeMax().Min() || value.Max() > ScaleRangeMax().Max())
116 throw std::out_of_range("scale range must be in [0.66, 1.50]");
117 scaleRange_ = value;
118 }
119
121
125 int FeatureCount() const noexcept // Function exists twice
126 {
127 return featureCount_;
128 }
129
131
135 void SetFeatureCount(int value)
136 {
137 if (value < FeatureCountMin)
138 throw std::out_of_range("feature count must be >= " + FeatureCountMin);
139 featureCount_ = value;
140 }
141
143
147 int ContrastThreshold() const noexcept
148 {
149 return contrastThreshold_;
150 }
151
153
157 void SetContrastThreshold(int value)
158 {
159 if (value < ContrastThresholdMin)
160 throw std::out_of_range("contrast threshold must be >= " + FeatureCountMin);
161 contrastThreshold_ = value;
162 }
163
165
169 int MaxCoarseLayerScale() const noexcept
170 {
171 return maxCoarseScale_;
172 }
173
175
180 {
181 if (value < -1)
182 throw std::out_of_range("maximum coarse layer scale must be >= -1");
183 maxCoarseScale_ = value;
184 }
185
187
192 {
193 return contrastMode_;
194 }
195
197
202 {
203 contrastMode_ = mode;
204 }
205
207
211 int ProfileSize() const noexcept
212 {
213 return profileSize_;
214 }
215
217
221 void SetProfileSize(int value)
222 {
223 if (value < 1)
224 throw std::out_of_range("profile size must be >= 1");
225 if ((value % 2) == 0)
226 throw std::invalid_argument("profile size must be %2 != 0");
227 profileSize_ = value;
228 }
229
231
235 int ProfileDelta() const noexcept
236 {
237 return profileDelta_;
238 }
239
241
245 void SetProfileDelta(int value)
246 {
247 if (value < 1)
248 throw std::out_of_range("profile delta must be >= 1");
249 profileDelta_ = value;
250 }
251
253
261 std::unique_ptr<Classifier> Learn(const ImagePlane & plane, Point2D<double> position, Rect<int> teachWindow, const std::vector<Point2D<int>>& dontCarePoints) const
262 {
263 return Learn(plane, position, Angle(), 0.0, teachWindow, dontCarePoints);
264 }
265
267
274 std::unique_ptr<Classifier> Learn(const ImagePlane & plane, Point2D<double> position, Rect<int> teachWindow) const
275 {
276 return Learn(plane, position, Angle(), 0.0, teachWindow);
277 }
278
280
289 std::unique_ptr<Classifier> Learn(const ImagePlane & plane, Point2D<double> position, Angle angleOffset, double scaleFactor, Rect<int> teachWindow) const
290 {
291 CExports::PIXELLIST dontCarePointsNative = nullptr;
292
293 if (plane.Parent().Handle() != nullptr && plane.DataType().HasOverlayBit())
294 {
295 CExports::CreatePixelListFromOverlay(plane.Parent().Handle(), plane.Plane(), 0, 0, plane.Parent().Width() - 1, plane.Parent().Height() - 1, dontCarePointsNative);
296 if (dontCarePointsNative)
297 {
298 CExports::TMatrix matrix;
299 matrix.A11 = Matrix2D::Identity().A11();
300 matrix.A12 = Matrix2D::Identity().A12();
301 matrix.A21 = Matrix2D::Identity().A21();
302 matrix.A22 = Matrix2D::Identity().A22();
303 CExports::TransformPixelListMatrix(dontCarePointsNative, matrix, -position.X(), -position.Y());
304 }
305 }
306
307 return Learn(plane, position, angleOffset, scaleFactor, teachWindow, dontCarePointsNative);
308 }
309
311
321 std::unique_ptr<Classifier> Learn(const ImagePlane & plane, Point2D<double> position, Angle angleOffset, double scaleFactor, Rect<int> teachWindow, const std::vector<Point2D<int>>& dontCarePoints) const
322 {
323 CExports::PIXELLIST dontCareList = static_cast<CExports::PIXELLIST>(Point2DToPixelList(dontCarePoints));
324 return Learn(plane, position, angleOffset, scaleFactor, teachWindow, dontCareList);
325 }
326
327private:
328
329 ClassifierFactory(ClassifierFactory & /*other*/) noexcept
330 {
331 }
332
333 ClassifierFactory & operator=(ClassifierFactory & other) = default;
334
335 static ValueRange<Angle> RotationRangeDefault() noexcept
336 {
338 }
339
340 static ValueRange<double> ScaleRangeDefault() noexcept
341 {
342 return ValueRange<double>(1.0, 1.0);
343 }
344
345 std::unique_ptr<Classifier> Learn(const ImagePlane & plane, Point2D<double> position, Angle angleOffset, double scaleFactor, Rect<int> teachWindow, CExports::PIXELLIST dontCareList ) const
346 {
347 CExports::TSymmetryParams symmetries;
348 symmetries.ContrastMode = (int)contrastMode_;
349 symmetries.A0 = RotationRange().Min().Deg();
350 symmetries.A1 = RotationRange().Max().Deg();
351 symmetries.R0 = ScaleRange().Min();
352 symmetries.R1 = ScaleRange().Max();
353
354 int maxCoarseScale = MaxCoarseLayerScale();
355 if (maxCoarseScale < 0)
356 maxCoarseScale = 16;
357
358 CExports::SF sf = nullptr;
359 if (ProfileSize() > 1)
360 {
361 sf = CExports::CreateSF2ExEx(plane.Parent().Handle(), plane.Plane(), (CExports::cvbdim_t)position.X(), (CExports::cvbdim_t)position.Y(), angleOffset.Rad(), scaleFactor
362 , teachWindow.Left(), teachWindow.Top(), teachWindow.Right(), teachWindow.Bottom(), ContrastThreshold(), FeatureCount()
363 , maxCoarseScale, symmetries, dontCareList, true, ProfileSize(), ProfileDelta());
364 }
365 else
366 {
367 sf = CExports::CreateSF2Ex(plane.Parent().Handle(), plane.Plane(), (CExports::cvbdim_t)position.X(), (CExports::cvbdim_t)position.Y(), angleOffset.Rad(), scaleFactor
368 , teachWindow.Left(), teachWindow.Top(), teachWindow.Right(), teachWindow.Bottom(), ContrastThreshold(), FeatureCount()
369 , maxCoarseScale, symmetries, dontCareList);
370 }
371
372 if (sf == nullptr)
373 Utilities::SystemInfo::ThrowLastError();
374 else
375 return Classifier::FromHandle(HandleGuard<Classifier>(sf));
376
377 return nullptr;
378 }
379
380
381 static Internal::PixelList* Point2DToPixelList(const std::vector<Point2D<int>>& points)
382 {
384 for (std::size_t i = 0; i < points.size(); i++)
385 {
386 tmp.push_back(static_cast<Point2D<double>>(points.at(i)));
387 }
388 auto pixelList = Internal::PixelList::FromPoints (tmp);
389 return pixelList.get();
390 }
391
392
393public:
394 static const int FeatureCountMin = 10;
395 static const int ContrastThresholdMin = 1;
396
397private:
398
399 static const int FeatureCountDefault = 100;
400 static const int ContrastThresholdDefault = 25;
401 static const int MaxCoarseLayerDefault = 8;
402
403 int featureCount_ = FeatureCountDefault;
404 int contrastThreshold_ = ContrastThresholdDefault;
405 int maxCoarseScale_ = MaxCoarseLayerDefault;
406 int profileSize_ = 1;
407 int profileDelta_ = 1;
408
409 Cvb::ValueRange<Cvb::Angle> rotationRange_ = RotationRangeDefault();
410 Cvb::ValueRange<double> scaleRange_ = ScaleRangeDefault();
412
413};
414
415}
416
417using ShapeFinder2::ClassifierFactory;
418
419CVB_END_INLINE_NS
420
421}
422
423
Object for convenient and type - safe handling of angles.
Definition: angle.hpp:19
static Angle FromDegrees(double deg, bool trim=false) noexcept
Create an angle in degrees.
Definition: angle.hpp:30
Image plane information container.
Definition: decl_image_plane.hpp:33
double A11() const noexcept
Gets top left matrix element.
Definition: matrix_2d.hpp:165
static Matrix2D Identity() noexcept
The identity element.
Definition: matrix_2d.hpp:24
double A22() const noexcept
Gets bottom right matrix element.
Definition: matrix_2d.hpp:225
double A12() const noexcept
Gets top right matrix element.
Definition: matrix_2d.hpp:185
double A21() const noexcept
Gets bottom left matrix element.
Definition: matrix_2d.hpp:205
T X() const noexcept
Gets the x-component of the point.
Definition: point_2d.hpp:86
T Y() const noexcept
Gets the y-component of the point.
Definition: point_2d.hpp:106
Rectangle object.
Definition: rect.hpp:26
ShapeFinder2 classifier factory object.
Definition: classifier_factory.hpp:27
void SetFeatureCount(int value)
Minimum number of features the result classifier should have.
Definition: classifier_factory.hpp:135
std::unique_ptr< Classifier > Learn(const ImagePlane &plane, Point2D< double > position, Rect< int > teachWindow) const
Create a ShapeFinder2 classifier from plane 0 of the input image.
Definition: classifier_factory.hpp:274
int ContrastThreshold() const noexcept
Minimum contrast a feature must have to enter into the classifier.
Definition: classifier_factory.hpp:147
std::vector< int > GradientHistogram(const ImagePlane &plane, Rect< int > aoi, ShapeFinder2::GradientType gradient) const
Calculate the gradient histogram.
Definition: classifier_factory.hpp:46
ValueRange< double > ScaleRange() const noexcept
Range of scales, that the classifier should be able to cover.
Definition: classifier_factory.hpp:103
void SetScaleRange(ValueRange< double > value)
Range of scales, that the classifier should be able to cover.
Definition: classifier_factory.hpp:113
void SetContrastThreshold(int value)
Minimum contrast a feature must have to enter into the classifier.
Definition: classifier_factory.hpp:157
ValueRange< Angle > RotationRangeMax() const noexcept
The maximum range of rotations (in degrees), that may be set on the learner.
Definition: classifier_factory.hpp:61
int ProfileDelta() const noexcept
Distance (in pixels) between adjacent profile points.
Definition: classifier_factory.hpp:235
std::unique_ptr< Classifier > Learn(const ImagePlane &plane, Point2D< double > position, Angle angleOffset, double scaleFactor, Rect< int > teachWindow) const
Create a ShapeFinder2 classifier from the input image.
Definition: classifier_factory.hpp:289
int MaxCoarseLayerScale() const noexcept
Maximum exponent of the scale factor between the coarse layer and the image.
Definition: classifier_factory.hpp:169
std::unique_ptr< Classifier > Learn(const ImagePlane &plane, Point2D< double > position, Rect< int > teachWindow, const std::vector< Point2D< int > > &dontCarePoints) const
Creates a ShapeFinder2 classifier from plane 0 of the input image.
Definition: classifier_factory.hpp:261
int FeatureCount() const noexcept
Minimum number of features the result classifier should have.
Definition: classifier_factory.hpp:125
ClassifierFactory() noexcept=default
The object that holds methods for generating ShapeFinder classifier factory.
ValueRange< double > ScaleRangeMax() const noexcept
The maximum range of scales, that may be set on the learner.
Definition: classifier_factory.hpp:93
void SetMaxCoarseLayerScale(int value)
Maximum exponent of the scale factor between the coarse layer and the image.
Definition: classifier_factory.hpp:179
ValueRange< Angle > RotationRange() const noexcept
Range of rotations, that the classifier should be able to cover.
Definition: classifier_factory.hpp:71
void SetProfileDelta(int value)
Distance (in pixels) between adjacent profile points.
Definition: classifier_factory.hpp:245
void SetRotationRange(ValueRange< Angle > value)
Range of rotations, that the classifier should be able to cover.
Definition: classifier_factory.hpp:81
void SetContrastMode(Cvb::ShapeFinder2::ContrastMode mode) noexcept
Contrast mode to be used for feature extraction.
Definition: classifier_factory.hpp:201
int ProfileSize() const noexcept
Profile size gives the number of profile points to be used for correlation around each feature.
Definition: classifier_factory.hpp:211
Cvb::ShapeFinder2::ContrastMode ContrastMode() const noexcept
Contrast mode to be used for feature extraction.
Definition: classifier_factory.hpp:191
void SetProfileSize(int value)
Profile size gives the number of profile points to be used for correlation around each feature.
Definition: classifier_factory.hpp:221
std::unique_ptr< Classifier > Learn(const ImagePlane &plane, Point2D< double > position, Angle angleOffset, double scaleFactor, Rect< int > teachWindow, const std::vector< Point2D< int > > &dontCarePoints) const
Create a ShapeFinder2 classifier from the input image.
Definition: classifier_factory.hpp:321
static std::unique_ptr< Classifier > FromHandle(HandleGuard< Classifier > &&guard)
Creates a classifier from a classic API handle.
Definition: classifier.hpp:49
Container for range definitions.
Definition: value_range.hpp:17
T Min() const noexcept
Gets the minimum value.
Definition: value_range.hpp:50
T Max() const noexcept
Gets the maximum value.
Definition: value_range.hpp:72
const int CVB_INVALIDDATATYPE
Invalid data type.
Definition: exception.hpp:78
GradientType
Type of Gradient used for feature extraction.
Definition: shapefinder2.hpp:59
ContrastMode
Normal contrast features.
Definition: shapefinder2.hpp:37
@ Normal
Normal contrast features.
Root namespace for the Image Manager interface.
Definition: c_barcode.h:24
Angle Max(Angle a, Angle b) noexcept
Returns the bigger of two angles.
Definition: angle.hpp:504
Angle Min(Angle a, Angle b) noexcept
Returns the smaller of two angles.
Definition: angle.hpp:521