Jump to content

Examples - Sample Applications

From RidgeRun Developer Wiki

Follow us on: YouTube Twitter LinkedIn Email Share this page

Share This Page


Preferred Partner Logo 3 Partner Program Banner




Sample Applications

PVA ISP provides four C++ example applications. Built-from-source binaries are shown below as ./builddir/out/bin/...; use the corresponding installed path in an evaluation package. All examples require an even image resolution and a YAML parameter file. RAW input is stored in 16-bit samples, with the meaningful sample depth and Bayer pattern described by the configuration. Match both to the actual sensor data before evaluating image quality.

Application What it demonstrates Output
isp_minimal One RAW file through separate or joined ISP stages, with optional convolution, BLC, and DLUT tone mapping. One NV12 file, default <image>.nv12.
isp_minimal_cuda CUDA-mapped input/output boundary buffers rotated between PVA executions. One NV12 file containing the final iteration.
isp_multicamera 2–16 simulated cameras, each with an independent joined DLUT pipeline and execution session. One NV12 file per simulated camera.
isp_app File input or V4L2 capture, histogram and Auto Exposure branches, optional CSV exports and PVA statistics. File mode writes <image>.out; capture mode processes frames without writing an NV12 file.

Shared parameter file

All four examples load examples/configs/params.yaml. The example parameter file is included below. Its decompand.x_pts are compressed input codes and decompand.y_pts are linear 16-bit output codes. The gamma_tone_mapping.lut entries are ignored while build_lut: true. Camera calibration values should be adjusted for the actual sensor.

Example: examples/configs/params.yaml

# yaml-language-server: $schema=./params.schema.yaml
# Copyright (C) 2026 RidgeRun, LLC (http://www.ridgerun.com)
# All Rights Reserved.
#
# The contents of this software are proprietary and confidential to RidgeRun,
# LLC.  No part of this program may be photocopied, reproduced or translated
# into another programming language without prior written consent of
# RidgeRun, LLC.  The user is free to modify the source code after obtaining
# a software license from RidgeRun.  All source code changes must be provided
# back to RidgeRun without any encumbrance.

# Reference parameter file for the ISP examples.
# This sample matches `params.schema.yaml` and the runtime loader used by:
# - isp_minimal
# - isp_minimal_cuda
# - isp_multicamera
# - isp_app

decompand:
  input_shift: 4
  x_pts: [0, 1098, 1885, 2501, 3062, 3602, 3914, 3975, 4095]
  y_pts: [0, 1107, 3325, 7766, 16652, 34430, 52207, 56648, 65535]

convolution:
  kernel: [1, 2, 1, 2, 4, 2, 1, 2, 1]
  shift: 4

color_correction:
  matrix: [1, 0, 0, 0, 1, 0, 0, 0, 1]
  shift: 0

black_level:
  channel00: 16
  channel01: 16
  channel10: 16
  channel11: 16

digital_gain:
  channel_gains: [1.5, 1.5, 1.5, 1.5]

white_balance:
  u_ref: [0.982, 0.789, 0.668, 0.558, 0.426]
  v_ref: [0.308, 0.382, 0.445, 0.428, 0.678]
  use_calibration: false
  manual_wb: false
  manual_wb_gains: [1.0, 1.0, 1.0]

demosaic:
  bayer_pattern: 0

histogram:
  bit_depth: 16
  use_mask: false

auto_exposure:
  kp_exposure: 40.0
  ki_exposure: 1.0
  kd_exposure: 8.0
  kp_gain: 5000000.0
  ki_gain: 10.0
  kd_gain: 500.0
  reference_mean: 120.0
  dynamic_range: 255.0
  min_exposure: 5000
  max_exposure: 20000
  min_gain: 2000000
  max_gain: 100000000
  camera_index: 0
  enable_v4l2: false

gamma_tone_mapping:
  build_lut: true
  gamma: 2.2
  lut: [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
    32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
    64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
    80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
    96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
    128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143,
    144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
    160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
    176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
    192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
    208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
    224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
    240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
  ]

global_tone_mapping:
  brightness: 0.18
  gtm_scale_min: 0.0001
  gtm_scale_max: 0.01
  gtm_temporal_alpha: 1.0

debug:
  export_scene_key: false
  export_debug_csv: false
  debug_export_frame_index: 0

isp_minimal

isp_minimal loads one RAW image, executes the selected graph repeatedly, and writes only the final NV12 result. --num-frames defaults to 100 processing iterations. It does not read a sequence of different source frames.

Usage

./builddir/out/bin/isp_minimal --image <raw-file> --resolution <width>x<height> \
  --parameters <yaml> [--output <nv12-file>] [--dump-graph <dot-file>] \
  [--num-frames <iterations>] [--no-convolution] [--disable-blc] \
  [--join-kernels] [--gtm-dlut] [--stats]
  • --no-convolution skips the spatial filter but keeps Color Correction.
  • --disable-blc uses White Balance Gains in place of Black Level Correction.
  • --join-kernels selects Input Stage, Pre RGB, combined Convolution + Color Correction when convolution is enabled, and Post RGB. Without convolution it retains standalone Color Correction.
  • --gtm-dlut selects standalone DLUT Global Tone Mapping or, with --join-kernels, Post RGB DLUT.
  • --stats prints per-stage PVA execution statistics. --dump-graph writes Graphviz DOT after preparation.

The standard graph is Decompand → Black Level / WB Gains → White Balance → Demosaic → [Convolution] → Color Correction → Global Tone Mapping → Gamma → NV12 Conversion. The joined graph is Input Stage → Pre RGB → [Convolution + Color Correction / Color Correction] → Post RGB. The selected tone-mapping path changes the relevant final stage. A scene-key side connection feeds tone mapping in either graph.

File example

./builddir/out/bin/isp_minimal \
  --image input.raw \
  --resolution 1920x1080 \
  --parameters examples/configs/params.yaml \
  --output /tmp/input.nv12 \
  --num-frames 1

Use the IMX274 reference RAW file or another compatible RAW input. Use its actual resolution, Bayer pattern, and alignment when running the example. The command as written expects a 1920×1080×2-byte RAW16 file, with the Bayer pattern and low-bit alignment specified by the YAML. For another image, change the resolution and sensor parameters accordingly. NV12 has one full-resolution Y plane plus a half-height interleaved UV plane; view it using the input width and height, rather than the storage height H + H/2.

The following image shows an example output. It is illustrative; it is not a validation target for arbitrary input RAW data.

Expected NV12 output

A successful run prepares the selected stages, prints initialization and average execution times, and writes the requested NV12 file. Logger details and timing values vary by graph, hardware, and run. Check the log for the selected stages, completed processing, and the output path.

isp_minimal_cuda

isp_minimal_cuda is built when the CUDA Toolkit is available. Its fixed joined graph is Input Stage → Pre RGB → Color Correction → Post RGB DLUT. It creates a pool of CUDA-mapped Bayer input and NV12 output buffer pairs and uses Pipeline::updateExternalFrame() between iterations to rotate those external boundary allocations. It writes only the final NV12 result.

./builddir/out/bin/isp_minimal_cuda --image <raw-file> \
  --resolution <width>x<height> --parameters <yaml> \
  [--output <nv12-file>] [--dump-graph <dot-file>] \
  [--num-frames <iterations>] [--num-buffers <count>] [--stats]

--num-frames defaults to 100; --num-buffers defaults to 2. The input and output frame specifications stay fixed while the underlying CUDA pointers change. The external allocations must remain valid for each process() call. See Custom Application Development for the boundary-frame API.

isp_multicamera

isp_multicamera simulates cameras by copying the same loaded RAW16 frame into 2–14 independent pipelines. It does not capture from multiple physical cameras. Each pipeline runs Input Stage → Pre RGB → Post RGB DLUT; Convolution and Color Correction are omitted. Cameras run in sequential batches of two, with the pair submitted concurrently on separate execution sessions and streams.

./builddir/out/bin/isp_multicamera --image <raw-file> \
  --resolution <width>x<height> --parameters <yaml> \
  [--output-prefix <prefix>] [--dump-graph <dot-file>] \
  [--num-frames <iterations>] [--num-cameras <2-16>] [--stats]

--num-cameras defaults to 2; --num-frames defaults to 100 per camera. The output prefix defaults to the input path, producing <prefix>_camera0.nv12, <prefix>_camera1.nv12, and so on. The graph export describes one representative camera because their topologies are identical. The average execution time reports a complete all-camera round, excluding initialization and file I/O.

isp_app

isp_app is the full example. Its separate graph includes Decompand, Black Level Correction, White Balance, Demosaic, Convolution, Color Correction, Global Tone Mapping, Gamma Tone Mapping, and NV12 Conversion. A Histogram → Auto Exposure branch consumes corrected Bayer data. --join-kernels replaces the image path with Input Stage, Pre RGB, Convolution + Color Correction, and Post RGB while retaining Histogram and Auto Exposure. isp_app does not have a --gtm-dlut option.

Usage

./builddir/out/bin/isp_app (--image <raw-file> | --device /dev/videoN) \
  --resolution <width>x<height> --parameters <yaml> \
  [--num-frames <count>] [--format <0|1|2>] [--mask <mask-file>] \
  [--dump-graph <dot-file>] [--gtm-luminances-csv <path>] \
  [--gtm-scene-key-csv <path>] [--join-kernels] [--stats]

The capture format numbers are 0 = BG12 (BGGR), 1 = RG10 (RGGB), and 2 = BYR2 (BGGR). The format matters for V4L2 input and must match demosaic.bayer_pattern in the YAML. --mask supplies a float histogram mask. The GTM CSV path options override the default locations under debug/. Debug export settings are in the YAML debug section. CSV exporters require separate stages: isp_app --join-kernels rejects debug.export_debug_csv: true or debug.export_scene_key: true. --stats and graph export still work with joined kernels.

File input example

./builddir/out/bin/isp_app \
  --image input.raw \
  --resolution 1920x1080 \
  --parameters examples/configs/params.yaml \
  --num-frames 1

A one-frame RAW16 file can be reused for the requested frame count, or the file may contain exactly that many concatenated frames. File mode writes input.raw.out (one NV12 frame per processed input) and computes Auto Exposure controls without writing them to a camera. The YAML sample's debug_export_frame_index must be below --num-frames when CSV export is enabled.

V4L2 input example

./builddir/out/bin/isp_app \
  --device /dev/video0 \
  --resolution 1920x1080 \
  --format 0 \
  --parameters examples/configs/params.yaml \
  --num-frames 100

The sample YAML selects Bayer pattern 0 (BGGR), matching capture format 0. Capture mode writes computed exposure and gain through V4L2 controls and requires a suitable /dev/videoN device. It processes the requested captured frames and does not write an NV12 output file. Applications that need to save or stream captured NV12 data should consume the pipeline output in their own loop.

Source Code Guide

The example application sources are examples/isp_minimal.cpp, examples/isp_minimal_cuda.cpp, examples/isp_multicamera.cpp, and examples/isp_full_application.cpp (isp_app). Shared helpers are in examples/isp_example_common.cpp; YAML loading is in examples/isp_params/isp_params.cpp. The full applications use the public Pipeline API described in Custom Application Development.

How isp_minimal runs

  1. parseArgs() validates input, resolution, parameter path, and graph switches. loadIspParams() parses the YAML parameter file.
  2. buildStandardPipeline() or buildJoinedPipeline() creates stages with addStage(), links the main image path and the required gains and scene_key pads, and sets stage properties.
  3. bindBoundaryFrames() binds Bayer input and NV12 output through setInput() and setOutput(), using the configured Bayer pattern and an NV12 storage height of H + H/2.
  4. prepare(options.stats) initializes, negotiates, allocates, and configures the pipeline. The optional Graphviz graph is then written.
  5. The application loads the RAW16 file, copies it into the input frame's host mapping, calls process() for the requested iterations, reports average time, and writes the final NV12 buffer.

The YAML parser uses names such as params.decompand.inputShift, params.decompand.xPts, and params.decompand.yPts internally. The public stage property for input alignment is named shift_bits. Use examples/isp_minimal.cpp as the C++ reference for the complete stage configuration and graph.


Cookies help us deliver our services. By using our services, you agree to our use of cookies.