Capturing Images Using libcamera in Microchip Platforms
Introduction
libcamera is an open-source software library handling image signal processors and embedded cameras that is supported on Linux-based distributions. Refer libcamera architecture to know more about the architecture
Here is a block diagram from the official libcamera page
--------------------------< libcamera Public API >---------------------------
^ ^
| |
v v
+-------------+ +---------------------------------------------------+
| Camera | | Camera Device |
| Manager | | +-----------------------------------------------+ |
+-------------+ | | Device-Agnostic | |
^ | | | |
| | | +--------------------------+ |
| | | | ~~~~~~~~~~~~~~~~~~~~~~~ |
| | | | { +-----------------+ } |
| | | | } | //// Image //// | { |
| | | | <-> | / Processing // | } |
| | | | } | / Algorithms // | { |
| | | | { +-----------------+ } |
| | | | ~~~~~~~~~~~~~~~~~~~~~~~ |
| | | | ========================== |
| | | | +-----------------+ |
| | | | | // Pipeline /// | |
| | | | <-> | /// Handler /// | |
| | | | | /////////////// | |
| | +--------------------+ +-----------------+ |
| | Device-Specific |
| +---------------------------------------------------+
| ^ ^
| | |
v v v
+--------------------------------------------------------------------+
| Helpers and Support Classes |
| +-------------+ +-------------+ +-------------+ +-------------+ |
| | MC & V4L2 | | Buffers | | Sandboxing | | Plugins | |
| | Support | | Allocator | | IPC | | Manager | |
| +-------------+ +-------------+ +-------------+ +-------------+ |
| +-------------+ +-------------+ |
| | Pipeline | | ... | |
| | Runner | | | |
| +-------------+ +-------------+ |
+--------------------------------------------------------------------+
/// Device-Specific Components
~~~ Sandboxing
Traditionally, the camera interfaces in linux4sam platforms are configured using media-ctl and v4l2-ctl commands. Each entity in the pipeline has to be configured separately. libcamera provides a higher-level, flexible interface to manage this complexity.
It abstracts away the hardware differences and provides a consistent interface, making it easier for application developers to support multiple devices. It provides control over camera pipelines, including white balance, gain, and sensor tuning, which is crucial for high-quality image capture.
Microchip Specific Pipeline Handler
In libcamera, a pipeline handler is a core component responsible for interfacing with camera hardware. It manages the media devices, configures the camera pipeline, and handles image capture operations. Each hardware platform typically requires a specific pipeline handler to accommodate its unique architecture and capabilities.The pipeline handler is a component of libcamera that is device-specific. It manages the complex pipelines exposed by the kernel drivers through the Media Controller and V4L2 APIs. You can find the supported devices in the libcamera source in the following path src/libcamera/pipeline. See the GitHub page for the microchip ISC pipeline handler implementation.
Capturing Images Using mchpcam-still
mchpcam-still is a comprehensive userspace demo application that can configure the microchip ISC and capture images. The application supports various image processing options and algorithms that are explained in the following section with a few examples.
Features in mchpcam-still
Display the help menu with -h option
root@sama7g5ek-sd:~# mchpcam-still -h
Usage: mchpcam-still [options]
Discovery:
--list-cameras List all available cameras and exit
--list-controls List controls supported by the camera and exit
--list-properties List camera properties and exit
--version Print version string and exit
Camera selection:
-c, --camera=ID Camera ID or index (default: first available)
Output:
-o, --output=FILE Output file. Supports tokens:
%d = counter (0001, 0002, ...)
%t = Unix epoch seconds
%T = MMDDHHmmSS timestamp
--image-format=FORMAT jpeg | png (default: from extension)
--jpeg-quality=1-100 JPEG quality (default: 100)
--png-compression=0-9 PNG compression level (default: 6)
--latest=LINK Create/update symlink to latest capture
--metadata Print all frame metadata after capture
--metadata-format=FMT json | txt (default: txt)
Stream:
-f, --format=FMT RGB565 | YUYV | BGR888 | RGB888
(default: RGB565)
--raw Capture 10-bit Bayer (SRGGB10/RGGB) as 16-bit PGM.
Forces unity WB gains (512) so the ISC WB
block is a mathematical no-op (datasheet
§43.6.20: histogram taps vp_data before WB;
AE converges normally). AWB is disabled.
Output: <file>.pgm maxval=1023 Bayer GRBG.
Use for CCM calibration with microchip_isc.py.
--width=N Capture width (default: 1920)
--height=N Capture height (default: 1080)
Capture modes:
--timeout=SECONDS Per-capture timeout. Default: auto (maxFrames/fps * 1.5 + 2 s)
--capture=N Capture N frames (burst or timelapse)
--timelapse=MS Timelapse: repeat every MS milliseconds
Keeps IPA warm between shots.
Use with --capture=N or Ctrl+C to stop.
-k, --keypress Wait for Enter keypress before each capture
-s, --signal Wait for SIGUSR1 before each capture
(enables scripted/remote-triggered capture)
Image controls:
--brightness=F [-1.0, +1.0], neutral 0.0 (default)
--contrast=F [ 0.0, 32.0], neutral 1.0 (default)
--gamma=F Display gamma exponent (default: 2.2)
--saturation=F [ 0.0, 2.0], neutral 1.0 (default)
--hue=F Hue rotation degrees [-180, +180], 0 (default)
--sharpness=F No-op: ISC has no hardware sharpening
Exposure:
--ev=F EV compensation [-2.0, +2.0] stops (default: 0)
--metering=MODE centre | spot | matrix (default: centre)
--shutter=US Manual exposure time in microseconds
--analoggain=F Manual analogue gain, 1.0=unity (disables AGC)
--digitalgain=F Manual digital gain 1.0–16.0
--framerate=F Lock output framerate (e.g. 30.0, 15.0)
--exposure-time-mode=MODE auto | manual — lock/free shutter independently
--gain-mode=MODE auto | manual — lock/free gain independently
e.g. fix gain=1x, let AE choose exposure:
--gain-mode=manual --analoggain=1.0
--no-agc Disable both AE and AG (--exposure-time-mode=manual
--gain-mode=manual combined)
White balance:
--awb=MODE AWB mode preset:
auto — IPA auto (default)
incandescent — ~2800K tungsten
tungsten — ~3200K (alias)
fluorescent — ~4000K cool white
indoor — ~3800K warm LED
daylight — ~5500K D65
cloudy — ~6500K overcast
shade — ~7500K open shade
--no-awb Disable IPA Auto White Balance
--awbgains=R,B IPA manual WB gains (disables AWB)
--red-gain=N ISC hardware WB R gain 0-8191 (512=1×)
--blue-gain=N ISC hardware WB B gain 0-8191
--green-red-gain=N ISC hardware WB GR gain 0-8191
--green-blue-gain=N ISC hardware WB GB gain 0-8191
--red-offset=N ISC hardware WB R offset -4095..4095
--blue-offset=N ISC hardware WB B offset
--green-red-offset=N ISC hardware WB GR offset
--green-blue-offset=N ISC hardware WB GB offset
Note: hardware register options bypass the IPA. Use --no-awb.
Colour correction:
--no-ccm Disable IPA Colour Correction Matrix
--ccm=a,b,c,d,e,f,g,h,i Manual CCM: 9 floats, row-major RGB→RGB
e.g. identity: 1,0,0,0,1,0,0,0,1
Transform:
--hflip Horizontal mirror (IMX219 hardware HW flip)
--vflip Vertical flip (IMX219 hardware VFlip)
--rotation=0|180 Image rotation (0 or 180 degrees)
Algorithm enable/disable:
--enable-all Enable AWB + AGC + CCM
--disable-all Disable AWB + AGC + CCM
Warmup:
--warmup=N Minimum frames before saving (default: 12)
--noir Use imx219_noir.yaml tuning file
(sensor without IR-cut filter)
--tuning-file=PATH Override tuning YAML path
-h, --help Print this helpCapture an image using mchpcam-still application.
root@sama7g5ek-sd:~# mchpcam-still [0:00:28.429634000] [220] INFO Camera camera_manager.cpp:340 libcamera v0.0.0+6141-linux4microchip-2026.04-rc1-dirty (2026-04-28T17:49:06UTC) [0:00:28.643008800] [221] WARN CameraSensor camera_sensor_legacy.cpp:355 'imx219 1-0010': Recommended V4L2 control 0x009a0922 not supported [0:00:28.643543000] [221] WARN CameraSensor camera_sensor_legacy.cpp:427 'imx219 1-0010': The sensor kernel driver needs to be fixed [0:00:28.643769800] [221] WARN CameraSensor camera_sensor_legacy.cpp:429 'imx219 1-0010': See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information [0:00:28.650875200] [221] WARN CameraSensor camera_sensor_legacy.cpp:595 'imx219 1-0010': Failed to retrieve the camera location [0:00:28.651171800] [221] WARN CameraSensor camera_sensor_legacy.cpp:617 'imx219 1-0010': Rotation control not available, default to 0 degrees [0:00:28.659503000] [221] INFO IPAProxy ipa_proxy.cpp:180 Using tuning file /usr/share/libcamera/ipa/microchip-isc/imx219.yaml [0:00:28.678642600] [221] INFO ISC_IPA microchip_isc_ipa.cpp:212 microchip-isc: ISC IPA initialized with 6 algorithms [0:00:28.692955600] [221] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc/flexcom@e2818000/i2c@600/camera@10' for pipeline handler microchip-isc [0:00:28.693282600] [221] INFO MicrochipISC microchip-isc.cpp:872 Registered camera '/base/soc/flexcom@e2818000/i2c@600/camera@10' [0:00:28.693475600] [221] INFO MicrochipISC microchip-isc.cpp:876 Camera registration complete with HARDWARE HISTOGRAM support [0:00:28.695072200] [220] INFO Camera camera.cpp:1215 configuring streams: (0) 1920x1080-RGB565/sRGB [0:00:28.698979200] [221] INFO MicrochipISC microchip-isc.cpp:1039 Camera configuration complete: /base/soc/flexcom@e2818000/i2c@600/camera@10 Camera configured: RGB565 1920x1080 AWB: auto (IPA) AGC: auto CCM: on Warmup frames: 12 Warming up IPA (12 frames minimum)... [0:00:29.139518000] [221] INFO V4L2 v4l2_videodevice.cpp:1913 /dev/video1[11:cap]: Zero sequence expected for first frame (got 6) Captured after 33 frame(s) AWB locked : yes AE locked : yes Colour temp: 5700 K Saved JPEG: output.jpg
Capture a high-quality image with a specific resolution:
root@sama7g5ek-sd:~# mchpcam-still --width=1920 --height=1080 --jpeg-quality=100 -o high_quality.jpg
Capture with a specific white balance mode:
root@sama7g5ek-sd:~# mchpcam-still --awb=daylight -o daylight_scene.jpg
Capture with custom white balance settings:
root@sama7g5ek-sd:~# mchpcam-still --awb=manual --red-gain=2000 --blue-gain=3500 -o custom_wb.jpg
Capture at 640x480 resolution with YUV format:
root@sama7g5ek-sd:~# mchpcam-still --width=640 --height=480 --format=YUYV -o small.jpg