IDS peak AFL v2.0.2
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
40
41
42namespace peak
43{
44namespace pipeline
45{
46namespace modules
47{
48namespace detail
49{
50class GenericAutoFeatures : public IAutoFeature
51{
52 static constexpr int moduleVersion = 1;
53
54public:
55 friend class autofeature::BrightnessComponent;
56
57 explicit GenericAutoFeatures(const std::shared_ptr<peak::core::Device>& device, bool advanced = true)
58 : m_remoteDeviceNodeMap{ device ?
59 device->RemoteDevice()->NodeMaps().at(0) :
60 throw peak::afl::error::InvalidParameterException("The given device is not valid!", PEAK_AFL_STATUS_ERROR) }
61 , m_manager{ m_remoteDeviceNodeMap }
62 {
63 const auto isColorCamera = [this]() {
64 const auto pixelFormatNode = m_remoteDeviceNodeMap->TryFindNode<peak::core::nodes::EnumerationNode>("PixelFormat");
65 if (pixelFormatNode == nullptr || !pixelFormatNode->IsReadable())
66 {
67 return false;
68 }
69
70 for (const auto& entry : pixelFormatNode->AvailableEntries())
71 {
72 try
73 {
74 const auto pixelFormatInfo = peak::common::PixelFormatInfo(static_cast<peak::common::PixelFormat>(entry->Value()));
75 // If the camera supports bayer it is a color camera
76 if (pixelFormatInfo.HasChannel(peak::common::Channel::Bayer) || !pixelFormatInfo.IsSingleChannel())
77 {
78 return true;
79 }
80 }
81 catch (const std::exception&)
82 {
83 // ignore unknown pixelformats
84 }
85 }
86
87 return false;
88 };
89
90 for (const auto& controllerType :
92 {
93 if (controllerType == autofeature::ControllerType::WhiteBalance && !isColorCamera())
94 {
95 continue;
96 }
97
98 if (m_manager.IsControllerSupported(autofeature::detail::ToCType(controllerType)))
99 {
100 auto controller = CreateController(m_manager, controllerType, advanced);
101 m_controllers.emplace_back(std::move(controller));
102 }
103 }
104
105 m_manager.SetGainIPL(m_gain);
106
108 }
109
110 ~GenericAutoFeatures() override = default;
111
112 PEAK_COMMON_NO_DISCARD const char* GetType() const override
113 {
114 return "GenericAutoFeatures";
115 }
116
117 void SetEnabled(bool enabled) override
118 {
119 m_enabled = enabled;
120 }
121
122 void Serialize(peak::common::serialization::IArchive& archive) const override
123 {
124 archive.SetInt("Version", moduleVersion);
125 archive.SetBool("Enabled", m_enabled);
126
127 for (const auto& controller : m_controllers)
128 {
129 auto controllerArchive = archive.CreateArchive();
130 controller->Serialize(*controllerArchive);
131
132 archive.SetArchive(controller->GetName(), std::move(controllerArchive));
133 }
134 }
135
136 void Deserialize(const peak::common::serialization::IArchive& archive) override
137 {
138 const auto version{ archive.GetInt("Version") };
139 if (version < 1)
140 {
141 throw peak::afl::error::CorruptedDataException(
142 "Version " + std::to_string(version) + " is invalid. Must be at least 1", PEAK_AFL_STATUS_ERROR);
143 }
144
145 m_enabled = archive.GetBool("Enabled");
146 for (const auto& controller : m_controllers)
147 {
148 auto controllerArchive = archive.GetArchive(controller->GetName());
149 controller->Deserialize(*controllerArchive);
150 }
151 }
152
153 PEAK_COMMON_NO_DISCARD bool IsEnabled() const override
154 {
155 return m_enabled;
156 }
157
158 PEAK_COMMON_NO_DISCARD std::vector<autofeature::detail::IController*> GetControllers() const
159 {
160 std::vector<autofeature::detail::IController*> controllers;
161 std::transform(
162 m_controllers.begin(), m_controllers.end(), std::back_inserter(controllers), [](const auto& elem) { return elem.get(); });
163 return controllers;
164 }
165
166 PEAK_COMMON_NO_DISCARD autofeature::detail::IController* GetController(autofeature::ControllerType controllerType) const
167 {
168 const auto& controllers = GetControllers();
169 const auto result = std::find_if(
170 controllers.begin(), controllers.end(), [controllerType](const auto* elem) { return elem->GetType() == controllerType; });
171 if (result != controllers.end())
172 {
173 return *result;
174 }
175
176 return nullptr;
177 }
178
179 PEAK_COMMON_NO_DISCARD bool HasController(autofeature::ControllerType controllerType) const
180 {
181 const auto& controllers = GetControllers();
182 const auto result = std::find_if(
183 controllers.begin(), controllers.end(), [controllerType](const auto* elem) { return elem->GetType() == controllerType; });
184 return result != controllers.end();
185 }
186
187 void ResetToDefault() override
188 {
189 for (auto* controller : GetControllers())
190 {
191 controller->ResetToDefault();
192 }
193 }
194
195 void SetGainModule(std::shared_ptr<peak::pipeline::modules::IGain> gainModule) override
196 {
197 m_gainModule = gainModule;
198 }
199
200 void SetColorCorrectionMatrix(const std::array<float, 9>& ccm) override
201 {
202 m_manager.SetCCM(ccm);
203 }
204
205 PEAK_COMMON_NO_DISCARD peak::common::Any Process(const peak::common::Any& input) const override
206 {
207 if (!IsEnabled())
208 {
209 return input;
210 }
211
212 const auto isProcessing = m_manager.Status();
213 if (isProcessing)
214 {
215 return input;
216 }
217
218#if defined(HAS_PEAK_ICV_IMAGE) && defined(WITH_peak_ipl)
219 if (input.GetType() == typeid(peak::icv::Image))
220 {
221 m_manager.Process(input.AnyCast<peak::icv::Image>());
222 }
223 else
224#endif
225 if (input.GetType() == typeid(peak::ipl::Image))
226 {
227 m_manager.Process(input.AnyCast<peak::ipl::Image>());
228 }
229 else
230 {
231 throw peak::afl::error::InvalidCastException("Unsupported input type!", PEAK_AFL_STATUS_INVALID_PARAMETER);
232 }
233
234 return input;
235 }
236
237private:
238 PEAK_COMMON_NO_DISCARD std::unique_ptr<autofeature::detail::IController> CreateController(
239 peak::afl::Manager& manager, autofeature::ControllerType controllerType, bool advanced)
240 {
241 switch (controllerType)
242 {
244 if (advanced)
245 {
246 return std::make_unique<autofeature::AdvancedAutoFocus>(manager);
247 }
248 return std::make_unique<autofeature::BasicAutoFocus>(manager);
249
251 auto callback = [this]() {
252 if (!m_gainModule)
253 {
254 return;
255 }
256 m_gainModule->SetMaster(m_gain.MasterGainValue());
257 };
258
259 if (advanced)
260 {
261 return std::make_unique<autofeature::AdvancedAutoBrightness>(manager, callback);
262 }
263 return std::make_unique<autofeature::BasicAutoBrightness>(manager, callback);
264 }
265
267 auto callback = [this]() {
268 if (!m_gainModule)
269 {
270 return;
271 }
272
273 m_gainModule->SetRed(m_gain.RedGainValue());
274 m_gainModule->SetGreen(m_gain.GreenGainValue());
275 m_gainModule->SetBlue(m_gain.BlueGainValue());
276 };
277
278 if (advanced)
279 {
280 return std::make_unique<autofeature::AdvancedAutoWhiteBalance>(manager, callback);
281 }
282 return std::make_unique<autofeature::BasicAutoWhiteBalance>(manager, callback);
283 }
284 throw peak::afl::error::InternalErrorException("Unknown controller type", PEAK_AFL_STATUS_ERROR);
285 }
286
287 std::shared_ptr<peak::core::NodeMap> m_remoteDeviceNodeMap{};
288
289 std::vector<std::unique_ptr<autofeature::detail::IController>> m_controllers{};
290 peak::afl::Manager m_manager;
291
292 std::shared_ptr<modules::IGain> m_gainModule{};
293 peak::ipl::Gain m_gain{};
294
295 bool m_enabled{ true };
296};
297} // namespace detail
298} // namespace modules
299} // namespace pipeline
300} // 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
PixelFormat
Enum listing all supported pixel formats and their internal IDs.
Definition peak_common_pixel_format.hpp:64
@ Bayer
Definition peak_common_channel.hpp:42
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
Enum holding the possible pixel format names.