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