0
# Pixel Data Processing
1
2
Advanced pixel data manipulation including array extraction, compression, decompression, color space conversion, and various image processing operations for medical imaging workflows.
3
4
## Capabilities
5
6
### Pixel Array Access
7
8
Core functions for extracting pixel data from DICOM datasets as NumPy arrays with proper handling of various formats and orientations.
9
10
```python { .api }
11
def pixel_array(
12
src,
13
*,
14
ds_out=None,
15
specific_tags=None,
16
index=None,
17
raw=False,
18
decoding_plugin="",
19
**kwargs
20
):
21
"""
22
Extract pixel data as NumPy array from various sources.
23
24
Parameters:
25
- src: str, PathLike, file-like, or Dataset - Source of pixel data
26
- ds_out: Dataset or None - Output dataset for metadata (keyword-only)
27
- specific_tags: list of int or None - Specific tags to read (keyword-only)
28
- index: int or None - Frame index for multi-frame datasets (keyword-only)
29
- raw: bool - Return raw pixel data without processing (keyword-only)
30
- decoding_plugin: str - Specific decoder plugin to use (keyword-only)
31
- **kwargs: Additional keyword arguments for decoders
32
33
Returns:
34
ndarray - Pixel data array with appropriate shape and dtype
35
36
Raises:
37
AttributeError - If source has no pixel data
38
ImportError - If NumPy not available
39
"""
40
41
def iter_pixels(
42
src,
43
*,
44
ds_out=None,
45
specific_tags=None,
46
indices=None,
47
raw=False,
48
decoding_plugin="",
49
**kwargs
50
):
51
"""
52
Iterate over pixel data frames from various sources.
53
54
Parameters:
55
- src: str, PathLike, file-like, or Dataset - Source of pixel data
56
- ds_out: Dataset or None - Output dataset for metadata (keyword-only)
57
- specific_tags: list of int or None - Specific tags to read (keyword-only)
58
- indices: list of int or None - Specific frame indices to iterate over (keyword-only)
59
- raw: bool - Return raw pixel data without processing (keyword-only)
60
- decoding_plugin: str - Specific decoder plugin to use (keyword-only)
61
- **kwargs: Additional keyword arguments for decoders
62
63
Yields:
64
ndarray - Individual frame arrays
65
"""
66
67
def get_expected_length(dataset, unit='bytes'):
68
"""
69
Calculate expected pixel data length.
70
71
Parameters:
72
- dataset: Dataset - DICOM dataset
73
- unit: str - Unit for length ('bytes' or 'pixels')
74
75
Returns:
76
int - Expected length in specified units
77
"""
78
```
79
80
### Compression and Decompression
81
82
Functions for compressing and decompressing pixel data using various DICOM transfer syntaxes.
83
84
```python { .api }
85
def compress(dataset, transfer_syntax_uid, encoding_plugin=None, **kwargs):
86
"""
87
Compress pixel data using specified transfer syntax.
88
89
Parameters:
90
- dataset: Dataset - Dataset to compress
91
- transfer_syntax_uid: str - Target transfer syntax UID
92
- encoding_plugin: str - Specific encoder to use
93
- **kwargs: Additional encoder-specific options
94
95
Returns:
96
None - Modifies dataset in place
97
"""
98
99
def decompress(dataset, handler_name=None):
100
"""
101
Decompress pixel data to uncompressed format.
102
103
Parameters:
104
- dataset: Dataset - Dataset to decompress
105
- handler_name: str - Specific decoder to use
106
107
Returns:
108
None - Modifies dataset in place
109
"""
110
```
111
112
### Image Processing Operations
113
114
Advanced image processing functions for medical imaging applications including windowing, LUT applications, and color space conversions.
115
116
```python { .api }
117
def apply_windowing(arr, dataset, index=0):
118
"""
119
Apply window/level adjustments to pixel array.
120
121
Parameters:
122
- arr: ndarray - Input pixel array
123
- dataset: Dataset - Dataset containing windowing parameters
124
- index: int - Window/level pair index for multi-window datasets
125
126
Returns:
127
ndarray - Windowed pixel array
128
"""
129
130
def apply_modality_lut(arr, dataset):
131
"""
132
Apply modality LUT transformation.
133
134
Parameters:
135
- arr: ndarray - Input pixel array
136
- dataset: Dataset - Dataset containing modality LUT
137
138
Returns:
139
ndarray - Transformed pixel array
140
"""
141
142
def apply_voi_lut(arr, dataset, index=0):
143
"""
144
Apply VOI LUT transformation.
145
146
Parameters:
147
- arr: ndarray - Input pixel array
148
- dataset: Dataset - Dataset containing VOI LUT
149
- index: int - VOI LUT index
150
151
Returns:
152
ndarray - Transformed pixel array
153
"""
154
155
def apply_color_lut(arr, dataset, palette='RGB'):
156
"""
157
Apply color palette LUT.
158
159
Parameters:
160
- arr: ndarray - Input pixel array
161
- dataset: Dataset - Dataset containing color LUT
162
- palette: str - Target color palette ('RGB', 'BGR', etc.)
163
164
Returns:
165
ndarray - Color-mapped pixel array
166
"""
167
```
168
169
### Color Space Conversion
170
171
Functions for converting between different color spaces used in medical imaging.
172
173
```python { .api }
174
def convert_color_space(arr, current, desired, per_frame=False):
175
"""
176
Convert pixel array between color spaces.
177
178
Parameters:
179
- arr: ndarray - Input pixel array
180
- current: str - Current color space ('RGB', 'YBR_FULL', etc.)
181
- desired: str - Desired color space
182
- per_frame: bool - Apply conversion per frame
183
184
Returns:
185
ndarray - Converted pixel array
186
"""
187
188
def apply_icc_profile(arr, dataset):
189
"""
190
Apply ICC color profile transformation.
191
192
Parameters:
193
- arr: ndarray - Input pixel array
194
- dataset: Dataset - Dataset containing ICC profile
195
196
Returns:
197
ndarray - Color-corrected pixel array
198
"""
199
```
200
201
### Pixel Data Utilities
202
203
Utility functions for pixel data manipulation and format conversion.
204
205
```python { .api }
206
def pack_bits(arr):
207
"""
208
Pack pixel array using bit packing.
209
210
Parameters:
211
- arr: ndarray - Input pixel array
212
213
Returns:
214
bytes - Packed pixel data
215
"""
216
217
def unpack_bits(data, shape):
218
"""
219
Unpack bit-packed pixel data.
220
221
Parameters:
222
- data: bytes - Packed pixel data
223
- shape: tuple - Expected array shape
224
225
Returns:
226
ndarray - Unpacked pixel array
227
"""
228
229
def set_pixel_data(dataset, arr, photometric_interpretation=None):
230
"""
231
Set pixel data in dataset from NumPy array.
232
233
Parameters:
234
- dataset: Dataset - Target dataset
235
- arr: ndarray - Pixel array to set
236
- photometric_interpretation: str - Color interpretation
237
238
Returns:
239
None - Modifies dataset in place
240
"""
241
242
def reshape_pixel_array(dataset, arr):
243
"""
244
Reshape pixel array according to DICOM parameters.
245
246
Parameters:
247
- dataset: Dataset - Dataset with image parameters
248
- arr: ndarray - Input pixel array
249
250
Returns:
251
ndarray - Reshaped array matching DICOM dimensions
252
"""
253
```
254
255
## Usage Examples
256
257
### Basic Pixel Array Access
258
259
```python
260
from pydicom import dcmread
261
from pydicom.pixels.utils import pixel_array
262
import numpy as np
263
264
# Read DICOM file
265
ds = dcmread("image.dcm")
266
267
# Get pixel array
268
if hasattr(ds, 'pixel_array'):
269
pixels = ds.pixel_array
270
print(f"Shape: {pixels.shape}")
271
print(f"Data type: {pixels.dtype}")
272
print(f"Min/Max: {pixels.min()}/{pixels.max()}")
273
274
# Alternative using function
275
pixels2 = pixel_array(ds)
276
assert np.array_equal(pixels, pixels2)
277
```
278
279
### Multi-frame Processing
280
281
```python
282
from pydicom.pixels.utils import iter_pixels
283
284
# Process multi-frame dataset frame by frame
285
ds = dcmread("multiframe.dcm")
286
287
for i, frame in enumerate(iter_pixels(ds)):
288
print(f"Frame {i}: shape {frame.shape}")
289
290
# Process individual frame
291
mean_intensity = frame.mean()
292
print(f" Mean intensity: {mean_intensity:.2f}")
293
294
# Process specific frames only
295
for frame in iter_pixels(ds, indices=[0, 5, 10]):
296
# Process selected frames
297
pass
298
```
299
300
### Image Enhancement
301
302
```python
303
from pydicom.pixels.processing import apply_windowing, apply_modality_lut
304
305
# Read CT dataset
306
ds = dcmread("ct_image.dcm")
307
pixels = ds.pixel_array
308
309
# Apply modality LUT (Hounsfield units for CT)
310
hu_pixels = apply_modality_lut(pixels, ds)
311
312
# Apply window/level for soft tissue viewing
313
windowed = apply_windowing(hu_pixels, ds, index=0)
314
315
# Display-ready pixel values
316
print(f"Original range: {pixels.min()}-{pixels.max()}")
317
print(f"HU range: {hu_pixels.min()}-{hu_pixels.max()}")
318
print(f"Windowed range: {windowed.min()}-{windowed.max()}")
319
```
320
321
### Color Image Processing
322
323
```python
324
from pydicom.pixels.processing import convert_color_space, apply_color_lut
325
326
# Read color ultrasound image
327
ds = dcmread("color_us.dcm")
328
pixels = ds.pixel_array
329
330
# Convert from YBR_FULL to RGB
331
if ds.PhotometricInterpretation == "YBR_FULL":
332
rgb_pixels = convert_color_space(pixels, "YBR_FULL", "RGB")
333
ds.PhotometricInterpretation = "RGB"
334
335
print(f"Converted from YBR to RGB: {rgb_pixels.shape}")
336
337
# Apply color palette for pseudocolor images
338
if ds.PhotometricInterpretation == "PALETTE COLOR":
339
color_pixels = apply_color_lut(pixels, ds)
340
print(f"Applied color LUT: {color_pixels.shape}")
341
```
342
343
### Compression Workflows
344
345
```python
346
from pydicom.pixels.utils import compress, decompress
347
348
# Read uncompressed image
349
ds = dcmread("uncompressed.dcm")
350
original_size = len(ds.PixelData)
351
352
# Compress using JPEG 2000 Lossless
353
compress(ds, "1.2.840.10008.1.2.4.90")
354
compressed_size = len(ds.PixelData)
355
356
print(f"Compression ratio: {original_size/compressed_size:.2f}")
357
358
# Decompress back to uncompressed
359
decompress(ds)
360
decompressed_size = len(ds.PixelData)
361
362
print(f"Round-trip successful: {original_size == decompressed_size}")
363
```
364
365
### Custom Pixel Data Handling
366
367
```python
368
from pydicom.pixels.utils import set_pixel_data, reshape_pixel_array
369
import numpy as np
370
371
# Create synthetic image data
372
synthetic_image = np.random.randint(0, 4096, (512, 512), dtype=np.uint16)
373
374
# Create new dataset
375
ds = Dataset()
376
ds.Rows = 512
377
ds.Columns = 512
378
ds.BitsAllocated = 16
379
ds.BitsStored = 12
380
ds.HighBit = 11
381
ds.PixelRepresentation = 0
382
ds.SamplesPerPixel = 1
383
ds.PhotometricInterpretation = "MONOCHROME2"
384
385
# Set pixel data
386
set_pixel_data(ds, synthetic_image)
387
388
# Verify
389
verify_pixels = ds.pixel_array
390
print(f"Successfully set pixel data: {np.array_equal(synthetic_image, verify_pixels)}")
391
```