RAW Image Capture (DNG)
Relevant source files
The following files were used as context for generating this wiki page:The picamera2 library provides the capability to capture raw, unprocessed image data directly from the camera sensor and save it as an Adobe Digital Negative (DNG) file. This allows for maximum flexibility in post-processing, as the DNG file contains the sensor's raw Bayer data, which can be processed using various raw image editors. This functionality leverages the external pidng library to handle the DNG file creation.
This document outlines how to configure the camera for raw capture, save images in DNG format, and perform simultaneous captures of both raw (DNG) and processed (e.g., JPEG) images.
Configuration for RAW Capture
To capture raw data, a raw stream must be enabled in the camera configuration. This is typically done by passing a raw dictionary to one of the configuration creation methods, such as create_still_configuration.
Sources: picamera2/picamera2.py:732-749
Configuration Methods
The raw stream is configured as part of a CameraConfiguration object. The most common method is create_still_configuration.
# examples/capture_dng.py:12
capture_config = picam2.create_still_configuration(raw={})
The raw parameter is a dictionary that can specify the size and format for the raw stream. If an empty dictionary {} is provided, picamera2 will use sensible defaults, typically matching the main stream's size and the sensor's native format.
Sources: examples/capture_dng.py:12, picamera2/picamera2.py:732-749
You can also specify the format and size for raw video capture:
# examples/capture_video_raw.py:12
size = (2592, 1944)
picam2 = Picamera2()
video_config = picam2.create_video_configuration(raw={"format": 'SGBRG10', 'size': size})
Sources: examples/capture_video_raw.py:11-13
Configuration Flow
The following diagram illustrates the typical flow for setting up a raw capture configuration.
This diagram shows the basic steps to prepare the camera for capturing a raw stream.
Sources: examples/capture_dng.py:9-16
RAW Stream Configuration Parameters
The raw dictionary in the configuration methods can accept the following keys:
| Key | Type | Description |
|---|---|---|
format | str | The raw sensor format (e.g., 'SGBRG10', 'SRGGB12_IPISP'). If None, a default is chosen based on the sensor. |
size | tuple | The resolution (width, height) of the raw stream. If None, it defaults to the size of the main stream. |
Sources: picamera2/picamera2.py:612-623, picamera2/picamera2.py:1016-1021
Capturing and Saving DNG Files
Once the camera is configured with a raw stream, you can capture a request and save the raw buffer as a DNG file.
Core Saving Mechanism
The primary method for saving a DNG file is CompletedRequest.save_dng(). This method is part of the CompletedRequest object, which is returned after a successful capture.
# examples/capture_dng_and_jpeg.py:18
request = picam2.switch_mode_and_capture_request(capture_config)
# ...
request.save_dng("full.dng")
The save_dng method handles the entire process of extracting the raw buffer, gathering metadata, and invoking the pidng library to create the DNG file.
Sources: examples/capture_dng_and_jpeg.py:18-20, picamera2/request.py:302-309
save_dng Call Sequence
The save_dng method on a CompletedRequest object initiates a sequence of calls that result in a DNG file.
This diagram shows that CompletedRequest.save_dng delegates the main work to Helpers.save_dng, which in turn uses the PICAM2DNG class from the pidng library to perform the conversion.
Sources: picamera2/request.py:302-309, picamera2/request.py:536-554
Saving to a File or Memory
The save_dng method can write to a file path or an in-memory io.BytesIO object.
| Parameter | Type | Description |
|---|---|---|
file_output | str or io.BytesIO | The destination file path or buffer. |
name | str | The name of the raw stream to use. Defaults to "raw". |
Sources: picamera2/request.py:302-309, piccamera2/request.py:548-553
Simultaneous RAW and Processed Capture
A common use case is to capture a raw DNG file and a processed JPEG file from the same frame. This is achieved by configuring both a raw stream and a main stream.
Workflow
- Configure: Create a still configuration with both
mainandrawstreams enabled. - Capture: Use a capture method that provides access to multiple stream buffers, such as
switch_mode_and_capture_request()orswitch_mode_and_capture_buffers(). - Save:
- Save the
mainstream as a JPEG usingrequest.save("main", "filename.jpg"). - Save the
rawstream as a DNG usingrequest.save_dng("filename.dng").
- Save the
The following diagram shows this workflow.
Sources: examples/capture_dng_and_jpeg.py
Example: Using switch_mode_and_capture_request
This method is convenient as it returns a single CompletedRequest object from which both streams can be saved.
# examples/capture_dng_and_jpeg.py:12-20
capture_config = picam2.create_still_configuration(raw=picam2.sensor_modes[2])
picam2.start()
time.sleep(2)
request = picam2.switch_mode_and_capture_request(capture_config)
request.save("main", "full.jpg")
request.save_dng("full.dng")
Sources: examples/capture_dng_and_jpeg.py:12-20
Example: Using switch_mode_and_capture_buffers and Helpers
This approach gives you direct access to the memory buffers and uses the picam2.helpers for saving.
# examples/capture_dng_and_jpeg_helpers.py:15-18
buffers, metadata = picam2.switch_mode_and_capture_buffers(capture_config, ["main", "raw"])
picam2.helpers.save(picam2.helpers.make_image(buffers[0], capture_config["main"]), metadata, "full.jpg")
picam2.helpers.save_dng(buffers[1], metadata, capture_config["raw"], "full.dng")
Sources: examples/capture_dng_and_jpeg_helpers.py:15-18
Manual DNG Conversion from RAW Video
It's also possible to record a raw video stream and then manually convert individual frames to DNG format. This is a lower-level approach that does not use the CompletedRequest.save_dng method. It relies on the pidng.core.RAW2DNG class.
The process involves:
- Recording a raw video to a file.
- Reading a frame from the file into a
numpyarray. - Manually setting DNG tags (image width, height, CFA pattern, etc.).
- Using
RAW2DNG().convert()to create the DNG file.
# examples/capture_video_raw.py:38-55
# Create DNG file from frame, based on https://github.com/schoolpost/PiDNG/blob/master/examples/raw2dng.py
# Tested loading of DNG in darktable
r = RAW2DNG()
t = DNGTags()
bpp = 10
t.set(Tag.ImageWidth, size[0])
t.set(Tag.ImageLength, size[1])
# ... other tags
t.set(Tag.CFAPattern, CFAPattern.GBRG)
t.set(Tag.DNGVersion, DNGVersion.V1_4)
r.options(t, path="", compress=False)
r.convert(arr, filename="test")
This demonstrates the flexibility of the underlying pidng library for more custom workflows.
Sources: examples/capture_video_raw.py:38-55
Summary
The picamera2 library offers a robust and straightforward mechanism for capturing raw sensor data and saving it in the DNG format. By enabling a raw stream in the camera configuration, users can easily obtain raw buffers alongside processed images. The CompletedRequest.save_dng() method provides a high-level, convenient way to generate DNG files, while lower-level access through the pidng library is also possible for custom applications. This feature is essential for users who require the highest image quality and full control over the post-processing workflow.
Sources: picamera2/request.py:302-309, picamera2/picamera2.py:732-749