IDS peak AFL v2.1.0
Loading...
Searching...
No Matches
peak_afl_generic_auto_features.hpp
Go to the documentation of this file.
1
6
7#pragma once
8
9#include <memory>
10
11#include <peak_afl/peak_afl.hpp>
19
20#if defined(__has_include)
21# if __has_include(<peak_icv/types/peak_icv_image.hpp>)
22# include <peak_icv/types/peak_icv_image.hpp>
23# define HAS_PEAK_ICV_IMAGE 1
24# endif
25#endif
26
27#include <peak_ipl/types/peak_ipl_image.hpp>
28#include <peak/device/peak_device.hpp>
29#include <peak/node_map/peak_node_map.hpp>
30
36
37
38namespace peak
39{
40namespace pipeline
41{
42namespace modules
43{
44namespace detail
45{
46class GenericAutoFeatures : public IAutoFeature
47{
48 static constexpr int moduleVersion = 1;
49
50public:
51 friend class autofeature::BrightnessComponent;
52
53 explicit GenericAutoFeatures(const std::shared_ptr<peak::core::Device>& device, bool advanced = true)
54 : m_remoteDeviceNodeMap{ device ?
55 device->RemoteDevice()->NodeMaps().at(0) :
56 throw peak::afl::error::InvalidParameterException("The given device is not valid!", PEAK_AFL_STATUS_ERROR) }
57 , m_manager{ m_remoteDeviceNodeMap }
58 {
59 const auto isColorCamera = [this]() {
60 const auto pixelFormatNode = m_remoteDeviceNodeMap->TryFindNode<peak::core::nodes::EnumerationNode>("PixelFormat");
61 if (pixelFormatNode == nullptr || !pixelFormatNode->IsReadable())
62 {
63 return false;
64 }
65
66 for (const auto& entry : pixelFormatNode->AvailableEntries())
67 {
68 try
69 {
70 const auto pixelFormatInfo = peak::common::PixelFormatInfo(static_cast<peak::common::PixelFormat>(entry->Value()));
71 // If the camera supports bayer it is a color camera
72 if (pixelFormatInfo.HasChannel(peak::common::Channel::Bayer) || !pixelFormatInfo.IsSingleChannel())
73 {
74 return true;
75 }
76 }
77 catch (const std::exception&)
78 {
79 // ignore unknown pixelformats
80 }
81 }
82
83 return false;
84 };
85
86 for (const auto& controllerType :
88 {
89 if (controllerType == autofeature::ControllerType::WhiteBalance && !isColorCamera())
90 {
91 continue;
92 }
93
94 if (m_manager.IsControllerSupported(autofeature::detail::ToCType(controllerType)))
95 {
96 auto controller = CreateController(m_manager, controllerType, advanced);
97 m_controllers.emplace_back(std::move(controller));
98 }
99 }
100
101 m_manager.SetGainIPL(m_gain);
102
104 }
105
106 ~GenericAutoFeatures() override = default;
107
108 PEAK_COMMON_NO_DISCARD const char* GetType() const override
109 {
110 return "GenericAutoFeatures";
111 }
112
113 void SetEnabled(bool enabled) override
114 {
115 m_enabled = enabled;
116 }
117
118 void Serialize(peak::common::serialization::IArchive& archive) const override
119 {
120 archive.SetInt("Version", moduleVersion);
121 archive.SetBool("Enabled", m_enabled);
122
123 for (const auto& controller : m_controllers)
124 {
125 auto controllerArchive = archive.CreateArchive();
126 controller->Serialize(*controllerArchive);
127
128 archive.SetArchive(controller->GetName(), std::move(controllerArchive));
129 }
130 }
131
132 void Deserialize(const peak::common::serialization::IArchive& archive) override
133 {
134 const auto version{ archive.GetInt("Version") };
135 if (version < 1)
136 {
137 throw peak::afl::error::CorruptedDataException(
138 "Version " + std::to_string(version) + " is invalid. Must be at least 1", PEAK_AFL_STATUS_ERROR);
139 }
140
141 m_enabled = archive.GetBool("Enabled");
142 for (const auto& controller : m_controllers)
143 {
144 auto controllerArchive = archive.GetArchive(controller->GetName());
145 controller->Deserialize(*controllerArchive);
146 }
147 }
148
149 PEAK_COMMON_NO_DISCARD bool IsEnabled() const override
150 {
151 return m_enabled;
152 }
153
154 PEAK_COMMON_NO_DISCARD std::vector<autofeature::detail::IController*> GetControllers() const
155 {
156 std::vector<autofeature::detail::IController*> controllers;
157 std::transform(
158 m_controllers.begin(), m_controllers.end(), std::back_inserter(controllers), [](const auto& elem) { return elem.get(); });
159 return controllers;
160 }
161
162 PEAK_COMMON_NO_DISCARD autofeature::detail::IController* GetController(autofeature::ControllerType controllerType) const
163 {
164 const auto& controllers = GetControllers();
165 const auto result = std::find_if(
166 controllers.begin(), controllers.end(), [controllerType](const auto* elem) { return elem->GetType() == controllerType; });
167 if (result != controllers.end())
168 {
169 return *result;
170 }
171
172 return nullptr;
173 }
174
175 PEAK_COMMON_NO_DISCARD bool HasController(autofeature::ControllerType controllerType) const
176 {
177 const auto& controllers = GetControllers();
178 const auto result = std::find_if(
179 controllers.begin(), controllers.end(), [controllerType](const auto* elem) { return elem->GetType() == controllerType; });
180 return result != controllers.end();
181 }
182
183 void ResetToDefault() override
184 {
185 for (auto* controller : GetControllers())
186 {
187 controller->ResetToDefault();
188 }
189 }
190
191 void SetGainModule(std::shared_ptr<peak::pipeline::modules::IGain> gainModule) override
192 {
193 m_gainModule = gainModule;
194 }
195
196 void SetColorCorrectionMatrix(const std::array<float, 9>& ccm) override
197 {
198 m_manager.SetCCM(ccm);
199 }
200
201 PEAK_COMMON_NO_DISCARD peak::common::Any Process(const peak::common::Any& input) const override
202 {
203 if (!IsEnabled())
204 {
205 return input;
206 }
207
208 const auto isProcessing = m_manager.Status();
209 if (isProcessing)
210 {
211 return input;
212 }
213
214#if defined(HAS_PEAK_ICV_IMAGE) && defined(WITH_peak_ipl)
215 if (input.GetType() == typeid(peak::icv::Image))
216 {
217 m_manager.Process(input.AnyCast<peak::icv::Image>());
218 }
219 else
220#endif
221 if (input.GetType() == typeid(peak::ipl::Image))
222 {
223 m_manager.Process(input.AnyCast<peak::ipl::Image>());
224 }
225 else
226 {
227 throw peak::afl::error::InvalidCastException("Unsupported input type!", PEAK_AFL_STATUS_INVALID_PARAMETER);
228 }
229
230 return input;
231 }
232
233private:
234 PEAK_COMMON_NO_DISCARD std::unique_ptr<autofeature::detail::IController> CreateController(
235 peak::afl::Manager& manager, autofeature::ControllerType controllerType, bool advanced)
236 {
237 switch (controllerType)
238 {
240 if (advanced)
241 {
242 return std::make_unique<autofeature::AdvancedAutoFocus>(manager);
243 }
244 return std::make_unique<autofeature::BasicAutoFocus>(manager);
245
247 auto callback = [this]() {
248 if (!m_gainModule)
249 {
250 return;
251 }
252 m_gainModule->SetMaster(m_gain.MasterGainValue());
253 };
254
255 if (advanced)
256 {
257 return std::make_unique<autofeature::AdvancedAutoBrightness>(manager, callback);
258 }
259 return std::make_unique<autofeature::BasicAutoBrightness>(manager, callback);
260 }
261
263 auto callback = [this]() {
264 if (!m_gainModule)
265 {
266 return;
267 }
268
269 m_gainModule->SetRed(m_gain.RedGainValue());
270 m_gainModule->SetGreen(m_gain.GreenGainValue());
271 m_gainModule->SetBlue(m_gain.BlueGainValue());
272 };
273
274 if (advanced)
275 {
276 return std::make_unique<autofeature::AdvancedAutoWhiteBalance>(manager, callback);
277 }
278 return std::make_unique<autofeature::BasicAutoWhiteBalance>(manager, callback);
279 }
280 throw peak::afl::error::InternalErrorException("Unknown controller type", PEAK_AFL_STATUS_ERROR);
281 }
282
283 std::shared_ptr<peak::core::NodeMap> m_remoteDeviceNodeMap{};
284
285 std::vector<std::unique_ptr<autofeature::detail::IController>> m_controllers{};
286 peak::afl::Manager m_manager;
287
288 std::shared_ptr<modules::IGain> m_gainModule{};
289 peak::ipl::Gain m_gain{};
290
291 bool m_enabled{ true };
292};
293} // namespace detail
294} // namespace modules
295} // namespace pipeline
296} // namespace peak
const std::type_info & GetType() const
Gets the type of the stored value.
Definition peak_common_any.hpp:159
T & AnyCast()
Casts the stored value to the specified type.
Definition peak_common_any.hpp:174
virtual void SetBool(const std::string &key, bool value)=0
Stores a boolean value.
virtual std::shared_ptr< IArchive > GetArchive(const std::string &key) const =0
Retrieves a nested archive by key.
virtual void SetInt(const std::string &key, int64_t value)=0
Stores a 64-bit signed integer.
virtual int64_t GetInt(const std::string &key) const =0
Retrieves a 64-bit signed integer by key.
virtual bool GetBool(const std::string &key) const =0
Retrieves a boolean value by key.
virtual std::shared_ptr< IArchive > CreateArchive() const =0
Creates a new, empty archive instance.
virtual void SetArchive(const std::string &key, const std::shared_ptr< IArchive > &value)=0
Stores a nested archive object.
virtual void ResetToDefault()=0
Resets the module to its default state. The enabled state is not reset.
virtual bool IsEnabled() const =0
Checks whether the module is currently enabled.
virtual const char * GetType() const =0
Returns the type identifier of the module.
@ PEAK_AFL_STATUS_INVALID_PARAMETER
Invalid parameter provided.
Definition peak_afl.h:416
@ PEAK_AFL_STATUS_ERROR
General error occurred.
Definition peak_afl.h:396
ControllerType
Controller type enumeration.
Definition peak_afl_icontroller.hpp:36
@ WhiteBalance
Automatic white balance controller - manages color correction.
Definition peak_afl_icontroller.hpp:42
@ Brightness
Automatic brightness controller - manages exposure and gain.
Definition peak_afl_icontroller.hpp:40
@ Focus
Automatic focus controller - manages lens focus positioning.
Definition peak_afl_icontroller.hpp:38
PixelFormat
Enum listing all supported pixel formats and their internal IDs.
Definition peak_common_pixel_format.hpp:59
@ Bayer
Definition peak_common_channel.hpp:37
Interface definitions and implementations for individual module types used within a pipeline.
Definition peak_afl_generic_auto_brightness.hpp:35
Interfaces and implementations for defining and controlling data processing pipelines.
Definition peak_afl_generic_auto_brightness.hpp:33
Enum holding the possible pixel format names.