CVB++ 15.0
detail_pixel_list.hpp
1#pragma once
2
3#include <vector>
4
5#include "../global.hpp"
6
7#include "../local_maximum.hpp"
8#include "../matrix_2d.hpp"
9
10namespace Cvb
11{
12
13 CVB_BEGIN_INLINE_NS
14
15 namespace Internal
16 {
17
18 class PixelList;
19 }
20
21 template <>
22 inline HandleGuard<Internal::PixelList>::HandleGuard(void *handle) noexcept
23 : HandleGuard<Internal::PixelList>(handle, [](void *handle) { CVB_CALL_CAPI(ReleaseObject(handle)); })
24 {
25 }
26
27 namespace Internal
28 {
29
30 class PixelList final
31 {
32
33 public:
34 static std::unique_ptr<PixelList> FromHandle(HandleGuard<PixelList> &&guard)
35 {
36 auto pixelList = std::unique_ptr<PixelList>(new PixelList(std::move(guard)));
37 return pixelList;
38 }
39
40 template <class RANGE>
41 static typename TypedRange<std::unique_ptr<PixelList>, Point2D<double>, RANGE>::type
42 FromPoints(const RANGE &points)
43 {
44 auto handle = CExports::CreatePixelList(2);
45 if (!handle)
46 throw std::runtime_error("failed to create pixel list");
47
48 auto pixelList = FromHandle(HandleGuard<PixelList>(handle));
49
50 for (const auto &point : points)
51 {
52 if (!CVB_CALL_CAPI(AddPixel(pixelList->Handle(), reinterpret_cast<const double *>(&point))))
53 Utilities::SystemInfo::ThrowLastError();
54 }
55 return pixelList;
56 }
57
58 void *Handle() const noexcept
59 {
60 return handle_.Handle();
61 }
62
63 int Dimension() const noexcept
64 {
65 return static_cast<int>(CExports::PixelListDimension(Handle()));
66 }
67
68 int Count() const noexcept
69 {
70 return static_cast<int>(CExports::PixelListCount(Handle()));
71 }
72
73 void Transform(Matrix2D matrix, Point2D<double> offset) noexcept
74 {
75 Transform(matrix, offset.X(), offset.Y());
76 }
77
78 void Transform(Matrix2D matrix, double offsetX, double offsetY) noexcept
79 {
80 CExports::TransformPixelListMatrix(Handle(), *reinterpret_cast<CExports::TMatrix *>(&matrix), offsetX, offsetY);
81 }
82
83 std::vector<LocalMaximum> ToLocalMaximum() const
84 {
85 auto dim = Dimension();
86 if (dim < 3)
87 throw std::runtime_error("not enough data to convert to local maxima");
88
89 auto count = Count();
90 std::vector<LocalMaximum> retval(static_cast<std::size_t>(count));
91 std::vector<double> tmpData(static_cast<std::size_t>(dim));
92 for (int i = 0; i < count; ++i)
93 {
94 CVB_CALL_CAPI(ListPixelEx(Handle(), static_cast<CExports::cvbval_t>(i), tmpData.data()));
95 retval[static_cast<std::size_t>(i)] = LocalMaximum(tmpData.data());
96 }
97 return retval;
98 }
99
100 std::vector<Point2D<double>> ToPoints() const
101 {
102 auto dim = Dimension();
103 auto count = Count();
104 std::vector<Point2D<double>> retval(static_cast<std::size_t>(count));
105 std::vector<double> tmpData(static_cast<std::size_t>(dim));
106 for (int i = 0; i < count; ++i)
107 {
108 CVB_CALL_CAPI(ListPixelEx(Handle(), static_cast<CExports::cvbval_t>(i), tmpData.data()));
109 retval[static_cast<std::size_t>(i)] = Point2D<double>(tmpData[0], tmpData[1]);
110 }
111 return retval;
112 }
113
114 std::vector<double> ToValues(int index) const
115 {
116 auto dim = Dimension();
117 auto count = Count();
118 std::vector<double> retval(static_cast<std::size_t>(dim));
119 if (index < count)
120 {
121 for (int i = 0; i < count; ++i)
122 {
123 if (index == i)
124 {
125 CVB_CALL_CAPI(ListPixelEx(Handle(), static_cast<CExports::cvbval_t>(i), retval.data()));
126 break;
127 }
128 }
129 }
130 return retval;
131 }
132
133 private:
134 explicit PixelList(HandleGuard<PixelList> &&guard) noexcept
135 : handle_(std::move(guard))
136 {
137 }
138
139 HandleGuard<PixelList> handle_;
140 };
141
142 } // namespace Internal
143
144 CVB_END_INLINE_NS
145
146} // namespace Cvb
T count(T... args)
cvbbool_t AddPixel(PIXELLIST PixelList, const double *Components)
cvbbool_t ListPixelEx(PIXELLIST PixelList, cvbval_t Index, double *Components)
cvbbool_t ReleaseObject(OBJ &Object)
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17