IDS peak ICV v1.3.0
Loading...
Searching...
No Matches
debayer_module.py
Go to the documentation of this file.
1import ctypes
2
3from ids_peak_common.datatypes.pixelformat import PixelFormat, Channel
4from ids_peak_common.serialization import IArchive
5from ids_peak_icv import lib_loader
6from ids_peak_icv.backend.datatypes import peak_icv_image_converter_handle, peak_icv_image_handle
7from ids_peak_icv.backend.utils import execute_and_map_return_codes
8from ids_peak_icv.datatypes.image import Image
9from ids_peak_icv.exceptions import NotSupportedException
10from ids_peak_icv.pipeline._internal.debayer_channel_layout import DebayerChannelLayout
11from ids_peak_icv.pipeline._internal.debayer_conversion_policy import DebayerConversionPolicy
13from ids_peak_icv.pipeline.processing_policy import ProcessingPolicy
14
15
17 """!
18 @brief
19 Debayer is an image pipeline module that converts Bayer RAW images into standard color formats.
20
21 It performs demosaicing on Bayer-pattern RAW images, converting them into full-color images
22 using configurable channel layouts such as RGB, BGR, RGBA, or BGRA. The bit depth of the output
23 is inferred from the input, depending on the selected processing policy.
24
25 Default configuration:
26 - Channel layout: DebayerChannelLayout.RGB
27 - Conversion policy: DebayerConversionPolicy.BAYER_ONLY
28 - Target bit depth: 8
29 - Processing policy: ProcessingPolicy.FAST
30
31 @ingroup ids_peak_icv_python_pipeline_modules
32 @since ids_peak_icv 1.0
33 """
34
35 DEFAULT_CHANNEL_LAYOUT: DebayerChannelLayout = DebayerChannelLayout.RGB
36 DEFAULT_CONVERSION_POLICY: DebayerConversionPolicy = DebayerConversionPolicy.BAYER_ONLY
37 DEFAULT_TARGET_BIT_DEPTH: int = 8
38 DEFAULT_POLICY: ProcessingPolicy = ProcessingPolicy.FAST
39
40 def __init__(self) -> None:
41 """!
42 @brief
43 Creates an instance of the debayer module.
44 @since ids_peak_icv 1.0
45 """
46 super().__init__()
47
48 image_converter_handle = peak_icv_image_converter_handle()
49 execute_and_map_return_codes(
50 lib_loader.dll().peak_icv_Preprocessing_ImageConverter_Create,
51 ctypes.pointer(image_converter_handle)
52 )
53
54 self._handle = image_converter_handle
55 self._channel_layout: DebayerChannelLayout = self.DEFAULT_CHANNEL_LAYOUT
56 self._conversion_policy: DebayerConversionPolicy = self.DEFAULT_CONVERSION_POLICY
58 self._policy: ProcessingPolicy = self.DEFAULT_POLICY
59
60 def __del__(self) -> None:
61 if hasattr(self, "_handle") and self._handle:
62 lib_loader.dll().peak_icv_Preprocessing_ImageConverter_Destroy(self._handle)
63
64 @property
65 def type(self) -> str:
66 """!
67 @brief
68 Returns the type of the module for serialization purposes.
69
70 @return Module type
71
72 @since ids_peak_icv 1.0
73 """
74 return "Debayer"
75
76 @property
77 def channel_layout(self) -> DebayerChannelLayout:
78 """!
79 @brief
80 Get the output channel layout used for debayered images.
81
82 @return The currently configured DebayerChannelLayout.
83
84 @since ids_peak_icv 1.0
85 """
86 return self._channel_layout
87
88 @channel_layout.setter
89 def channel_layout(self, layout: DebayerChannelLayout) -> None:
90 """!
91 @brief
92 Set the output channel layout for debayered images.
93
94 This controls the order and number of color channels in the converted image.
95
96 @param layout: Desired channel layout
97 @since ids_peak_icv 1.0
98 """
99 self._channel_layout = layout
100
101 @property
102 def conversion_policy(self) -> DebayerConversionPolicy:
103 """!
104 @brief
105 Get the current conversion policy.
106
107 @return The currently configured DebayerConversionPolicy.
108
109 @since ids_peak_icv 1.0
110 """
111 return self._conversion_policy
112
113 @conversion_policy.setter
114 def conversion_policy(self, policy: DebayerConversionPolicy) -> None:
115 """!
116 @brief
117 Set the debayer conversion policy.
118
119 This policy determines which types of input images will be converted.
120 All other image types are passed through unchanged.
121
122 @param policy: The desired conversion policy.
123
124 @since ids_peak_icv 1.0
125 """
126 self._conversion_policy = policy
127
128 @property
129 def target_bit_depth(self) -> int:
130 """!
131 @brief
132 Get the target bit depth for processed images.
133 @return Target bit depth as an integer.
134 @since ids_peak_icv 1.0
135 """
136 return self._target_bit_depth
137
138 @target_bit_depth.setter
139 def target_bit_depth(self, bit_depth: int) -> None:
140 """!
141 @brief
142 Set the target bit depth for processed images.
143
144 The effective output bit depth depends on the selected :class:`ProcessingPolicy`:
145
146 - **FAST**: The minimum of input bit depth and target bit depth.
147 - **BALANCED**: Equal to input bit depth.
148 - **ENHANCED**: The maximum of input bit depth and target bit depth.
149
150 @param bit_depth: The desired target bit depth (e.g., 8, 10, 12).
151
152 @since ids_peak_icv 1.0
153 """
154 self._target_bit_depth = bit_depth
155
156 @property
157 def processing_policy(self) -> ProcessingPolicy:
158 """!
159 @brief
160 Get the processing policy.
161 @return Current ProcessingPolicy value.
162 @since ids_peak_icv 1.0
163 """
164 return self._policy
165
166 @processing_policy.setter
167 def processing_policy(self, policy: ProcessingPolicy) -> None:
168 """!
169 @brief
170 Set the processing policy.
171
172 The processing policy defines how the target bit depth interacts
173 with the input image bit depth.
174
175 @param policy: The desired ProcessingPolicy.
176
177 @since ids_peak_icv 1.0
178 """
179 self._policy = policy
180
181 def process(self, input_image: Image) -> Image:
182 """!
183 @brief
184 Converts a Bayer or mono image to a color image,
185 or returns the input image unchanged.
186
187 A demosaicing algorithm is applied according to the configured
188 conversion policy. The input image is returned unchanged if the module
189 is disabled, the policy indicates bypass, or the image format is not
190 eligible for conversion. Otherwise, the Bayer RAW image is converted
191 to the configured output format.
192
193 @note This operation disregards any specified image regions and processes
194 the entire image.
195
196 @param input_image: The input image (Bayer, mono, or already color).
197
198 @return The processed color image or the unmodified input image.
199
200 @since ids_peak_icv 1.0
201 """
202 if not self._enabled_enabled:
203 return input_image
204
205 input_pixel_format = input_image.pixel_format
206 output_format = self._get_output_format(input_pixel_format)
207
208 if input_pixel_format == output_format:
209 return input_image
210
211 output_handle = peak_icv_image_handle()
212 execute_and_map_return_codes(
213 lib_loader.dll().peak_icv_Preprocessing_ImageConverter_Convert,
214 self._handle,
215 input_image._handle,
216 ctypes.c_int(output_format.value),
217 ctypes.pointer(output_handle)
218 )
219 return Image(_handle=output_handle)
220
221 def reset_to_default(self) -> None:
222 """!
223 @brief
224 Resets all settings to their defaults.
225
226 Default configuration:
227 - channel_layout = RGB
228 - conversion_policy = BAYER_ONLY
229 - target_bit_depth = 8
230 - processing_policy = FAST
231
232 @note The enabled state does not change when calling this function.
233
234 @since ids_peak_icv 1.0
235 """
239 self._policy = self.DEFAULT_POLICY
240
241 def release_buffers(self) -> None:
242 """!
243 @brief
244 Frees unused internal buffers.
245
246 This module uses pre-allocated internal buffers to accelerate conversions.
247 When the image size or pixel format changes, new buffers are allocated, which may cause
248 the internal buffer pool to grow over time. This function can be used to release
249 unused buffers and reduce memory usage.
250
251 @note Avoid calling this function too frequently (e.g., after every resize or format change),
252 as it introduces some overhead.
253
254 @since ids_peak_icv 1.0
255 """
256 execute_and_map_return_codes(
257 lib_loader.dll().peak_icv_Preprocessing_ImageConverter_ReleaseBuffers,
258 self._handle
259 )
260
261 # -------------------------------------------------------------------------
262
263 def serialize(self, archive: IArchive) -> None:
264 """!
265 @brief
266 Serializes the object's internal state into the provided archive.
267
268 This function populates the given archive with all parameters required to fully represent the current state of the object.
269 It ensures that the object can be reconstructed or transmitted accurately by saving all relevant data members
270 in a consistent and structured format.
271
272 @param archive: The target archive that will store the serialized parameters.
273
274 @since ids_peak_icv 1.0
275 """
276 super().serialize(archive)
277 archive.set("ChannelLayout", self._channel_layout.string_value)
278 archive.set("ConversionPolicy", self._conversion_policy.string_value)
279
280 def deserialize(self, archive: IArchive) -> None:
281 """!
282 @brief
283 Restores the object's state from the provided archive.
284
285 This function reads and applies all necessary parameters from the given archive to reconstruct the internal state of the object.
286 It ensures that the object is restored to a valid and consistent state.
287
288 @param archive: The source archive containing the serialized parameters.
289
290 @exception CorruptedException: If Archive is malformed, misses keys or the values are invalid
291 @exception NotSupportedException: If the 'Version' entry indicates an unsupported version.
292
293 @note This function requires that the archive contains all expected fields as produced by a corresponding serialize() call.
294
295 @since ids_peak_icv 1.0
296 """
297 super().deserialize(archive)
298
299 self._channel_layout = DebayerChannelLayout.create_from_string_value(archive.get("ChannelLayout", str))
300 self._conversion_policy = DebayerConversionPolicy.create_from_string_value(
301 archive.get("ConversionPolicy", str))
302
303 # -------------------------------------------------------------------------
304
305 def _get_output_bit_depth(self, input_bit_depth: int) -> int:
306 if self._policy == ProcessingPolicy.FAST:
307 return min(input_bit_depth, self._target_bit_depth)
308 elif self._policy == ProcessingPolicy.ENHANCED:
309 return max(input_bit_depth, self._target_bit_depth)
310 return input_bit_depth
311
312 def _get_output_format(self, input_pixel_format: PixelFormat) -> PixelFormat:
313 if self._conversion_policy == DebayerConversionPolicy.BYPASS:
314 return input_pixel_format
315
316 if not input_pixel_format.is_single_channel:
317 return input_pixel_format
318
319 is_bayer = input_pixel_format.has_channel(Channel.BAYER)
320 is_mono = input_pixel_format.has_channel(Channel.INTENSITY)
321
322 if not is_bayer and (not is_mono or self._conversion_policy is not DebayerConversionPolicy.BAYER_AND_MONO):
323 return input_pixel_format
324
325 input_bit_depth = input_pixel_format.storage_bits_per_channel
326 output_bit_depth = self._get_output_bit_depth(input_bit_depth)
327
328 if output_bit_depth <= 8:
329 return {
330 DebayerChannelLayout.RGB: PixelFormat.RGB_8,
331 DebayerChannelLayout.BGR: PixelFormat.BGR_8,
332 DebayerChannelLayout.RGBA: PixelFormat.RGBA_8,
333 DebayerChannelLayout.BGRA: PixelFormat.BGRA_8,
334 }[self._channel_layout]
335
336 if output_bit_depth <= 10:
337 return {
338 DebayerChannelLayout.RGB: PixelFormat.RGB_10,
339 DebayerChannelLayout.BGR: PixelFormat.BGR_10,
340 DebayerChannelLayout.RGBA: PixelFormat.RGBA_10,
341 DebayerChannelLayout.BGRA: PixelFormat.BGRA_10,
342 }[self._channel_layout]
343
344 if output_bit_depth <= 12:
345 return {
346 DebayerChannelLayout.RGB: PixelFormat.RGB_12,
347 DebayerChannelLayout.BGR: PixelFormat.BGR_12,
348 DebayerChannelLayout.RGBA: PixelFormat.RGBA_12,
349 DebayerChannelLayout.BGRA: PixelFormat.BGRA_12,
350 }[self._channel_layout]
351
353 f"The given input pixel format 0x{input_pixel_format.value:X} is unknown or not supported!"
354 )
Image Class for working with algorithms.
Definition image.py:40
Occurs when a requested operation is not implemented or supported (e.g., exporting to an unsupported ...
Definition exceptions.py:60
Debayer is an image pipeline module that converts Bayer RAW images into standard color formats.
None reset_to_default(self)
Resets all settings to their defaults.
None release_buffers(self)
Frees unused internal buffers.
None deserialize(self, IArchive archive)
Restores the object's state from the provided archive.
str type(self)
Returns the type of the module for serialization purposes.
DebayerConversionPolicy conversion_policy(self)
Get the current conversion policy.
PixelFormat _get_output_format(self, PixelFormat input_pixel_format)
DebayerChannelLayout channel_layout(self)
Get the output channel layout used for debayered images.
int target_bit_depth(self)
Get the target bit depth for processed images.
Image process(self, Image input_image)
Converts a Bayer or mono image to a color image, or returns the input image unchanged.
None __init__(self)
Creates an instance of the debayer module.
None serialize(self, IArchive archive)
Serializes the object's internal state into the provided archive.
Base class for all pipeline modules.
Definition module_base.py:8