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