denoiserjetpack_web_logo

DenoiserJetPack C++ library

v1.0.0

Table of contents

Overview

The DenoiserJetPack C++ library implements noise cancellation algorithm based on Nvidia VPI. This library is suitable for various types of camera (daylight, SWIR, MWIR and LWIR) and it provides simple programming interface. Each instance of the DenoiserJetPack C++ class object performs frame-by-frame processing of a video data stream, processing each video frame independently. DenoiserJetPack library at the moment supports only YUV24 pixel format. The library depends on VFilter library (provides interface for video filter, source code included, Apache 2.0 license) and Nvidia VPI API. Also test application and example depend on OpenCV library (version >= 4.5, linked, Apache 2.0 license). The library utilizes C++17 standard.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 25.02.2025 - First version.

Library files

The library is supplied as source code only. The user is provided with a set of files in the form of a CMake project (repository). The repository structure is shown below:

CMakeLists.txt ------------------- Main CMake file of the library.
3rdparty ------------------------- Folder with third-party libraries.
    CMakeLists.txt --------------- CMake file to include third-party libraries.
    VFilter ---------------------- Folder with VFilter library source code.
src ------------------------------ Folder with source code of the library.
    impl ------------------------- Folder with library implementation files.
        DenoiserJetPackImpl.cpp -- C++ implementation file.
        DenoiserJetPackImpl.h ---- Header file which includes DenoiserJetPackImpl class declaration.
    CMakeLists.txt --------------- CMake file of the library.
    DenoiserJetPack.cpp ---------- C++ implementation file.
    DenoiserJetPack.h ------------ Header file which includes DenoiserJetPack class declaration.
    DenoiserJetPackVersion.h ----- Header file which includes version of the library.
    DenoiserJetPackVersion.h.in -- CMake service file to generate version file.
test ----------------------------- Folder for test application.
    CMakeLists.txt --------------- CMake file for test application.
    main.cpp --------------------- Source code file of test application.
test ----------------------------- Folder for example application.
    CMakeLists.txt --------------- CMake file for example application.
    main.cpp --------------------- Source code file of example application.

DenoiserJetPack class description

DenoiserJetPack class declaration

The DenoiserJetPack class declared in DenoiserJetPack.h file. Class declaration:

namespace cr
{
namespace video
{
class DenoiserJetPack : public VFilter
{
public:

    /// Constructor.
    DenoiserJetPack();

    /// Destructor.
    ~DenoiserJetPack();

    /// Get the version of the DenoiserJetPack class.
    static std::string getVersion();

    /// Initialize DenoiserJetPack.
    bool initVFilter(VFilterParams& params) override;

    /// Set VFilter parameter.
    bool setParam(VFilterParam id, float value) override;

    /// Get the value of a specific VFilter parameter.
    float getParam(VFilterParam id) override;

    /// Get the structure containing all VFilter parameters.
    void getParams(VFilterParams& params) override;

    /// Execute a VFilter action command.
    bool executeCommand(VFilterCommand id) override;

    /// Process frame.
    bool processFrame(cr::video::Frame& frame) override;

    /// Set mask for filter. Not supported.
    bool setMask(cr::video::Frame mask) override;

    /// Decode and execute command.
    bool decodeAndExecuteCommand(uint8_t* data, int size) override;
};
}
}

getVersion method

The getVersion() static method returns string of current class version. Method declaration:

static std::string getVersion();

Method can be used without DenoiserJetPack class instance:

std::cout << "DenoiserJetPack version: " << cr::video::DenoiserJetPack::getVersion();

Console output:

DenoiserJetPack version: 1.0.0

initVFilter method

The initVFilter(…) method initializes denoiser. Method declaration:

bool initVFilter(VFilterParams& params) override;
Parameter Value
params VFilterParams class object.

Returns: TRUE if the video filter initialized or FALSE if not.

setParam method

The setParam (…) method sets new parameters value. The library provides thread-safe setParam(…) method call. This means that the setParam(…) method can be safely called from any thread. Method declaration:

bool setParam(VFilterParam id, float value) override;
Parameter Description
id Parameter ID according to VFilterParam enum.
value Parameter value. Value depends on parameter ID.

Returns: TRUE if the parameter was set or FALSE if not.

getParam method

The getParam(…) method returns parameter value. The library provides thread-safe getParam(…) method call. This means that the getParam(…) method can be safely called from any thread. Method declaration:

float getParam(VFilterParam id) override;
Parameter Description
id Parameter ID according to VFilterParam enum.

Returns: parameter value or -1 if the parameters doesn’t exist (not supported in particular implementation).

getParams method

The getParams(…) method is designed to obtain all denoiser params. The library provides thread-safe getParams(…) method call. This means that the getParams(…) method can be safely called from any thread. Method declaration:

void getParams(VFilterParams& params) override;
Parameter Description
params Reference to VFilterParams object to store params.

executeCommand method

The executeCommand(…) method executes video filter (denoiser) action command. The library provides thread-safe executeCommand(…) method call. This means that the executeCommand(…) method can be safely called from any thread. Method declaration:

bool executeCommand(VFilterCommand id) override;
Parameter Description
id Command ID according to VFilterCommand enum.

Returns: TRUE if the command executed or FALSE if not.

processFrame method

The processFrame(…) method applies noise cancellation on a frame. If the mode is set to 0 (disabled), the method will skip the frame and return true. Only YUV24 format is supported. Method declaration:

bool processFrame(cr::video::Frame& frame) override;
Parameter Description
frame Reference to Frame object. Only YUV24 format is supported.

Returns: TRUE if frame processed (noise cancellation) or FALSE if not. If filter disabled the method will return TRUE without video frame processing.

setMask method

The setMask(…) method designed to set video filter mask. Using mask is NOT supported in DenoiserJetPack class. Method declaration:

bool setMask(cr::video::Frame mask) override;
Parameter Description
mask Filter mask in form of Frame object with GRAY pixel format. Mask is NOT supported by DenoiserJetPack class.

Returns: TRUE.

encodeSetParamCommand method of VFilter class

The encodeSetParamCommand(…) static method encodes command to change any VFilter parameter value. To control any video filter remotely, the developer has to design his own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the VFilter class contains static methods for encoding the control command. The VFilter class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeSetParamCommand(…) designed to encode SET_PARAM command. Method declaration:

static void encodeSetParamCommand(uint8_t* data, int& size, VFilterParam id, float value);
Parameter Description
data Pointer to data buffer for encoded command. Must have size >= 11.
size Size of encoded data. Will be 11 bytes.
id Parameter ID according to VFilterParam enum.
value Parameter value.

encodeSetParamCommand(…) is static and used without VFilter class instance. This method used on client side (control system). Command encoding example:

// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Random parameter value.
float outValue = static_cast<float>(rand() % 20);
// Encode command.
VFilter::encodeSetParamCommand(data, size, VFilterParam::LEVEL, outValue);

encodeCommand method of VFilter class

The encodeCommand(…) static method encodes command for VFilter remote control. To control any video filter remotely, the developer has to design his own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the VFilter class contains static methods for encoding the control command. The VFilter class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeCommand(…) designed to encode COMMAND command (action command). Method declaration:

static void encodeCommand(uint8_t* data, int& size, VFilterCommand id);
Parameter Description
data Pointer to data buffer for encoded command. Must have size >= 7.
size Size of encoded data. Will be 7 bytes.
id Command ID according to VFilterCommand enum.

encodeCommand(…) is static and used without VFilter class instance. This method used on client side (control system). Command encoding example:

// Buffer for encoded data.
uint8_t data[7];
// Size of encoded data.
int size = 0;
// Encode command.
VFilter::encodeCommand(data, size, VFilterCommand::RESTART);

decodeCommand method of VFilter class

The decodeCommand(…) static method decodes command on image filter side. Method declaration:

static int decodeCommand(uint8_t* data, int size, VFilterParam& paramId, VFilterCommand& commandId, float& value);
Parameter Description
data Pointer to input command.
size Size of command. Must be 11 bytes for SET_PARAM and 7 bytes for COMMAND.
paramId VFilter parameter ID according to VFilterParam enum. After decoding SET_PARAM command the method will return parameter ID.
commandId VFilter command ID according to VFilterCommand enum. After decoding COMMAND the method will return command ID.
value VFilter parameter value (after decoding SET_PARAM command).

Returns: 0 - in case decoding COMMAND, 1 - in case decoding SET_PARAM command or -1 in case errors.

decodeAndExecuteCommand method

The decodeAndExecuteCommand(…) method decodes and executes command encoded by encodeSetParamCommand(…) and encodeCommand(…) methods on video filter side. The library provides thread-safe decodeAndExecuteCommand(…) method call. This means that the decodeAndExecuteCommand(…) method can be safely called from any thread. Method declaration:

bool decodeAndExecuteCommand(uint8_t* data, int size) override;
Parameter Description
data Pointer to input command.
size Size of command. Must be 11 bytes for SET_PARAM or 7 bytes for COMMAND.

Returns: TRUE if command decoded (SET_PARAM or COMMAND) and executed (action command or set param command).

Data structures

VFilterCommand enum

Enum declaration:

enum class VFilterCommand
{
    /// Reset image filter algorithm.
    RESET = 1,
    /// Enable filter.
    ON,
    /// Disable filter.
    OFF
};

Table 2 - Action commands description.

Command Description
RESET Resets denoiser.
ON Enable denoiser.
OFF Disable denoiser.

VFilterParam enum

Enum declaration:

enum class VFilterParam
{
	/// Current filter mode, usually 0 - off, 1 - on.
	MODE = 1,
	/// Enhancement level for particular filter, as a percentage in range from 
	/// 0% to 100%.
	LEVEL,
	/// Processing time in microseconds. Read only parameter.
	PROCESSING_TIME_MCSEC,
	/// Type of the filter. Depends on the implementation.
	TYPE,
	/// VFilter custom parameter. Custom parameters used when particular image 
	/// filter has specific unusual parameter.
	CUSTOM_1,
	/// VFilter custom parameter. Custom parameters used when particular image 
	/// filter has specific unusual parameter.
	CUSTOM_2,
	/// VFilter custom parameter. Custom parameters used when particular image 
	/// filter has specific unusual parameter.
	CUSTOM_3
};

Table 3 - Params description.

Parameter Access Description
MODE read / write Denoiser mode: 0 - disabled, 1 - enabled.
LEVEL read / write Denoiser level in percentage. Valid values from 0.0 to 100.0.
PROCESSING_TIME_MCSEC read only Processing time in microseconds. Read only parameter. Used to check performance of denoiser.
TYPE read / write Type of denoiser preset for VPI API. Values:
0 - Default
1 - Outdoor low light
2 - Outdoor mid light
3 - Outdoor high light
4 - Indoor low light
5 - Indoor mid light
6 - Indoor high light
CUSTOM_1 read / write Backend of VPI. Values : 0 - VCI, 1 - CUDA
CUSTOM_2 read / write Not supported by DenoiserJetPack class.
CUSTOM_3 read / write Not supported by DenoiserJetPack class.

VFilterParams class description

VFilterParams class declaration

The VFilterParams class is used to provide video filter parameters structure. Also VFilterParams provides possibility to write/read params from JSON files (JSON_READABLE macro) and provides methods to encode and decode params. VFilterParams interface class declared in VFilter.h file. Class declaration:

class VFilterParams
{
public:
    /// Current filter mode, usually 0 - off, 1 - on.
    int mode{ 0 };
    /// Enhancement level for particular filter, as a percentage in range from 
    /// 0% to 100%.
    float level{ 0 };
    /// Processing time in microseconds. Read only parameter.
    int processingTimeMcSec{ 0 };
    /// Type of the filter. Depends on the implementation.
    int type{ 0 };
    /// VFilter custom parameter. Custom parameters used when particular image 
    /// filter has specific unusual parameter.
    float custom1{ 0.0f };
    /// VFilter custom parameter. Custom parameters used when particular image 
    /// filter has specific unusual parameter.
    float custom2{ 0.0f };
    /// VFilter custom parameter. Custom parameters used when particular image 
    /// filter has specific unusual parameter.
    float custom3{ 0.0f };

    /// Macro from ConfigReader to make params readable/writable from JSON.
    JSON_READABLE(VFilterParams, mode, level, type, custom1, custom2, custom3)

    /// operator =
    VFilterParams& operator= (const VFilterParams& src);

    // Encode (serialize) params.
    bool encode(uint8_t* data, int bufferSize, int& size,
                                             VFilterParamsMask* mask = nullptr);
	// Decode (deserialize) params.
    bool decode(uint8_t* data, int dataSize);
};

Table 4 - VFilterParams class fields description is related to VFilterParam enum description.

Field type Description
mode int Denoiser mode: 0 - disabled, 1 - enabled.
level float Denoiser level in percentage. Valid values from 0.0 to 100.0.
processingTimeMcSec int Processing time in microseconds. Read only parameter. Used to check performance of denoiser.
type int Type of denoiser preset for VPI API. Values:
0 - Default
1 - Outdoor low light
2 - Outdoor mid light
3 - Outdoor high light
4 - Indoor low light
5 - Indoor mid light
6 - Indoor high light
custom1 float Backend of VPI. Values : 0 - VCI, 1 - CUDA
custom2 float Not supported by DenoiserJetPack class.
custom3 float Not supported by DenoiserJetPack class.

None: VFilterParams class fields listed in Table 4 have to reflect params set/get by methods setParam(…) and getParam(…).

Serialize VFilter params

VFilterParams class provides method encode(…) to serialize VFilter params. Serialization of VFilterParams is necessary in case when image filter parameters have to be sent via communication channels. Method provides options to exclude particular parameters from serialization. To do this method inserts binary mask (1 byte) where each bit represents particular parameter and decode(…) method recognizes it. Method declaration:

bool encode(uint8_t* data, int bufferSize, int& size, VFilterParamsMask* mask = nullptr);
Parameter Value
data Pointer to data buffer. Buffer size must be >= 48 bytes.
bufferSize Data buffer size. Buffer size must be >= 48 bytes.
size Size of encoded data.
mask Parameters mask - pointer to VFilterParamsMask structure. VFilterParamsMask (declared in VFilter.h file) determines flags for each field (parameter) declared in VFilterParams class. If the user wants to exclude any parameters from serialization, he can put a pointer to the mask. If the user wants to exclude a particular parameter from serialization, he should set the corresponding flag in the VFilterParamsMask structure.

Returns: TRUE if params encoded (serialized) or FALSE if not.

VFilterParamsMask structure declaration:

struct VFilterParamsMask
{
    bool mode{ true };
    bool level{ true };
    bool processingTimeMcSec{ true };
    bool type{ true };
    bool custom1{ true };
    bool custom2{ true };
    bool custom3{ true };
};

Example without parameters mask:

// Prepare parameters.
cr::video::VFilterParams params;
params.level = 80.0f;

// Encode (serialize) params.
int bufferSize = 128;
uint8_t buffer[128];
int size = 0;
params.encode(buffer, bufferSize, size);

Example with parameters mask:

// Prepare parameters.
cr::video::VFilterParams params;
params.level = 80.0;

// Prepare mask.
cr::video::VFilterParams mask;
// Exclude level.
mask.level = false;

// Encode (serialize) params.
int bufferSize = 128;
uint8_t buffer[128];
int size = 0;
params1.encode(buffer, bufferSize, size, &mask);

Deserialize VFilter params

VFilterParams class provides method decode(…) to deserialize params. Deserialization of VFilterParams is necessary in case when it is needed to receive params via communication channels. Method automatically recognizes which parameters were serialized by encode(…) method. Method declaration:

bool decode(uint8_t* data, int dataSize);
Parameter Value
data Pointer to data buffer with serialized params.
dataSize Size of command data.

Returns: TRUE if params decoded (deserialized) or FALSE if not.

Example:

// Prepare parameters.
cr::video::VFilterParams params1;
params1.level = 80;

// Encode (serialize) params.
int bufferSize = 128;
uint8_t buffer[128];
int size = 0;
params1.encode(buffer, bufferSize, size);

// Decode (deserialize) params.
cr::video::VFilterParams params2;
params2.decode(buffer, size);

Read params from JSON file and write to JSON file

VFilter depends on open source ConfigReader library which provides method to read params from JSON file and to write params to JSON file. Example of writing and reading params to JSON file:

// Write params to file.
cr::utils::ConfigReader inConfig;
cr::video::VFilterParams in;
inConfig.set(in, "vFilterParams");
inConfig.writeToFile("VFilterParams.json");

// Read params from file.
cr::utils::ConfigReader outConfig;
if(!outConfig.readFromFile("VFilterParams.json"))
{
    cout << "Can't open config file" << endl;
    return false;
}

VFilterParams.json will look like:

{
    "vFilterParams":
    {
        "level": 50,
        "mode": 2,
        "type": 1,
        "custom1": 0.7,
        "custom2": 12.0,
        "custom3": 0.61
    }
}

Build and connect to your project

Before built user has to install OpenCV library. Example for Linux Ubuntu:

sudo apt install libopencv-dev

Typical commands to build DenoiserJetPack:

cd DenoiserJetPack
mkdir build
cd build
cmake ..
make

If you want connect DenoiserJetPack to your CMake project as source code you can make follow. For example, if your repository has structure:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp

Create folder 3rdparty in your repository and copy DenoiserJetPack repository folder there. New structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    DenoiserJetPack

Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should contain:

cmake_minimum_required(VERSION 3.13)

################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)

################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)

################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
add_subdirectory(DenoiserJetPack)

File 3rdparty/CMakeLists.txt adds folder DenoiserJetPack to your project and excludes test application from compiling (by default test applications and example are excluded from compiling if DenoiserJetPack is included as sub-repository).The new structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    CMakeLists.txt
    DenoiserJetpack

Next you need include folder 3rdparty in main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:

add_subdirectory(3rdparty)

Next you have to include DenoiserJetPack library in your src/CMakeLists.txt file:

target_link_libraries(${PROJECT_NAME} DenoiserJetpack)

Done!

Example

This section demonstrates how to use the DenoiserJetpack with a straightforward example.

#include <iostream>
#include <cstdint>
#include <opencv2/opencv.hpp>
#include "DenoiserJetPack.h"

using namespace cv;
using namespace std;
using namespace cr::video;

int main(void)
{
    cout << "DenoiserJetPack v" << DenoiserJetPack::getVersion() << endl;

    // Prepare filter params.
    VFilterParams params;
    params.mode = 1;    // Enable filter.
    params.level = 80;  // %80 filter strength.
    params.type = 1;    // Outdoor low light
    params.custom1 = 0; // VIC backend.

    // Create and init denoiser.
    DenoiserJetPack denoiser;
    if (!denoiser.initVFilter(params))
        return -1;

    // Open video file.
    VideoCapture capture("test.mp4");
    if (!capture.isOpened())
        return -1;

    int width = capture.get(CAP_PROP_FRAME_WIDTH);
    int height = capture.get(CAP_PROP_FRAME_HEIGHT);

    cr::video::Frame frame(width, height, cr::video::Fourcc::YUV24);

    // Main loop.
    Mat bgrMat;
    while(true)
    {
        // Capture frame.
        capture >> bgrMat;
        if (bgrMat.empty())
            break;

        cv::Mat yuvMat(height, width, CV_8UC3, frame.data);

        // Convert to YUV.
        cvtColor(bgrMat, yuvMat, COLOR_BGR2YUV);

        // Denoise.
        denoiser.processFrame(frame);

        // Convert back to BGR to display.
        cvtColor(yuvMat, bgrMat, COLOR_YUV2BGR);

        // Display.
        imshow("Denoised Frame", bgrMat);
        if (waitKey(1) == 27)
            break;
    }
    
    return 1;
}

Test application

The DenoiserJetPack C++ library includes a test application located in the /test folder. This application is designed to help users evaluate the DenoiserJetPack’s capabilities. It provides options to adjust parameters such as LEVEL, BACKEND and TYPE, and it displays the processing time in milliseconds. Test application reads test.mp4 video file from its direction.

Once the application is successfully launched, it will display a noisy image and denoised image in a window. The window will appear as follows:

denoiserjetpack_test_interface


Table of contents