
GasLeakDetector C++ library
v2.1.0
Table of contents
- Overview
- Versions
- Library files
- Key features and capabilities
- Supported pixel formats
- Library principles
- GasLeakDetector class description
- GasLeakDetector class declaration
- getVersion method
- initVFilter method
- setParam method
- getParam method
- executeCommand method
- processFrame method
- setMask method
- encodeSetParamCommand method of VFilter class
- encodeCommand method of VFilter class
- decodeCommand method of VFilter class
- decodeAndExecuteCommand method
- Data structures
- VFilterParams class description
- Build and connect to your project
- Example
- Benchmark
- Demo application
Overview
GasLeakDetector C++ library amplifies subtle motion and temporal variations in digital video content. The library implements a video filtering function and can be used not only for Gas Leak Detection but for motion magnification in general. The library is implemented in C++ (C++17 standard). This library is suitable for various types of cameras (daylight, SWIR, MWIR and LWIR). Each instance of the GasLeakDetector C++ class object performs frame-by-frame processing of a video data stream. By default each video frame is processed in one thread (one CPU core used). The number of processing threads can be set by the user via the CUSTOM_1 parameter (see VFilterParam enum) to speed up processing on multi-core platforms. Processing results are bitwise identical for any number of threads. The image processing kernels are vectorized with SIMD instructions, with back-ends for AVX2, SSE2 and ARM NEON plus a portable scalar fallback, so no external computing library is required. The library is only intended for stationary (or slowly moving) cameras or for PTZ cameras when observing a certain sector. The library depends on the open-source VFilter library (provides interface as well as defines data structures for various video filter implementations, source code included, Apache 2.0 license). Additionally, the demo application and example depend on the open-source SimpleFileDialog (provides dialog to open files, source code included, Apache 2.0 license) and OpenCV (provides user interface, version >= 4.5, linked, Apache 2.0 license).
Versions
Table 1 - Library versions.
| Version | Release date | What’s new |
|---|---|---|
| 1.0.0 | 24.02.2025 | - First version. |
| 1.1.0 | 19.03.2025 | - OpenCV dependencies have been removed. |
| 1.1.1 | 13.08.2025 | - Fixed bug with building on Windows. |
| 1.1.2 | 20.08.2025 | - Fixed bug with header includes. |
| 1.2.0 | 06.04.2026 | - Processing speed improved x2.5. - Critical bugs fixed. - Coding standards applied. |
| 2.0.0 | 18.07.2026 | - Processing speed improved x2 in single-threaded mode (dead computation eliminated, memory reallocation removed). - Multi-threaded processing added: the number of threads is set by the CUSTOM_1 parameter (default 1). Results are bitwise identical for any number of threads. - Fixed a bug with changing the frame size during processing without RESET command. - Demo application: keys 1-4 set the number of processing threads. |
| 2.1.0 | 02.08.2026 | - Processing speed improved x2.5 more in single-threaded mode (x5 in total compared to v1.2.0, up to x16 with 4 threads): image processing kernels vectorized with SIMD instructions (AVX2, SSE2 and ARM NEON back-ends with a scalar fallback), and the finest pyramid level is now built from the frame bytes and written back to them in one streaming pass, which removes the full-resolution intermediate images. - Memory footprint reduced: the full-resolution float image and the full-size intermediate matrices of the finest level are no longer allocated (about 24 bytes per pixel less). - Fixed a bug: a mask set by the user was silently lost when the frame resolution changed. - Processing results are unchanged: no output pixel deviates by more than one least significant bit from v1.2.0. |
Library files
The library is supplied as source code only. The user is given 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.
ImgProc ---------------------- Folder with image processing library source code.
ImagePyramid.hpp --------- Image pyramid interface (build and reconstruct).
ImagePyramid.cpp --------- Image pyramid kernels.
SimdFloat.hpp ------------ SIMD primitives (AVX2, SSE2, NEON, scalar).
Resize.hpp / .cpp -------- Image scaling (used to scale the mask).
BorderInterpolate.hpp ---- Image border handling.
MathProc --------------------- Folder with math library source code.
src ------------------------------ Folder with library source code.
CMakeLists.txt --------------- CMake file of the library.
GasLeakDetector.h ------------ Main library header file.
GasLeakDetectorVersion.h.in -- File for CMake to generate version header.
GasLeakDetector.cpp ---------- C++ class source file.
impl ------------------------- Folder with implementation files.
GasLeakDetectorImpl.cpp -- C++ implementation file.
GasLeakDetectorImpl.h ---- Header file of the implementation.
demo ----------------------------- Folder for demo application files.
CMakeLists.txt --------------- CMake file for demo application.
3rdparty --------------------- Folder with third-party libraries for demo application.
CMakeLists.txt ----------- CMake file to include third-party libraries.
SimpleFileDialog --------- Folder with SimpleFileDialog library source code.
main.cpp --------------------- Source C++ file of demo application.
example -------------------------- Folder for simple example.
CMakeLists.txt --------------- CMake file of example.
main.cpp --------------------- Source C++ file of example.
benchmark ------------------------ Folder with benchmark application.
CMakeLists.txt --------------- CMake file of benchmark application.
main.cpp --------------------- Source C++ file of benchmark application.
test ----------------------------- Folder with unit tests (require OpenCV and GTest).
bench ---------------------------- Folder with micro-benchmark sources (require Google Benchmark).
docs ----------------------------- Folder with additional documentation.
Key features and capabilities
Table 2 - Key features and capabilities.
| Parameter and feature | Description |
|---|---|
| Programming language | C++ (standard C++17). |
| Supported OS | Compatible with any operating system that supports the C++ compiler (C++17 standard). |
| Movement type | The library is able to magnify any kind of movement, but it is best suited for tiny moving objects that are hard to spot with the unaided eye, e.g. drones, gas leaks. |
| Supported pixel formats | GRAY, YUV24, YUYV, UYVY, NV12, NV21, YV12, YU12. The library uses pixel intensity (luma) for video processing. If the pixel format of the image does not include an intensity channel, it should be converted to a supported format before applying magnification. |
| Calculation speed | The processing time per video frame depends on the computing platform used. For orientation, on one core of a desktop x86-64 CPU (Intel Core i7-13700H) a 1920x1080 frame takes about 2.2 ms and a 640x480 frame about 0.27 ms; with 4 threads the same frames take about 1.0 ms and 0.14 ms. The processing time per video frame on a particular platform can be estimated with the demo application or the benchmark application. |
| Multithreading | By default the library processes each video frame in one thread (one CPU core). The number of processing threads can be set via the CUSTOM_1 parameter (range 1..128, thread-safe, can be changed at any time during processing). Processing results are bitwise identical for any number of threads. Multithreading requires the library to be built with OpenMP support (found automatically by CMake); without OpenMP the library works in single-threaded mode. |
| Vector instructions | The image processing kernels are vectorized with explicit SIMD primitives and the back-end is selected at compile time: AVX2 (x86-64), SSE2 (x86 / x86-64), ARM NEON (ARMv7 and ARMv8) or a portable scalar fallback for any other target. No run-time dependency is added and no source change is needed to switch: the back-end follows the compiler’s target architecture flags. Defining IMGPROC_SIMD_DISABLE forces the scalar fallback. |
| Type of algorithm | A modified Eulerian Video Magnification algorithm was implemented. Amplification factor can be dynamically changed by user to serve different requirements. |
| Working conditions | Algorithm implemented in the library is designed to work on fixed cameras (or moving slowly) with any background conditions. |
Supported pixel formats
The Frame library, which is included in the GasLeakDetector library, contains the Fourcc enum that defines supported pixel formats (Frame.h file). The GasLeakDetector library supports only formats with an intensity channel (GRAY, YUV24, YUYV, UYVY, NV12, NV21, YV12, YU12). The library uses the intensity channel for video processing. Fourcc enum declaration:
enum class Fourcc
{
/// RGB 24bit pixel format.
RGB24 = MAKE_FOURCC_CODE('R', 'G', 'B', '3'),
/// BGR 24bit pixel format.
BGR24 = MAKE_FOURCC_CODE('B', 'G', 'R', '3'),
/// YUYV 16bits per pixel format.
YUYV = MAKE_FOURCC_CODE('Y', 'U', 'Y', 'V'),
/// UYVY 16bits per pixel format.
UYVY = MAKE_FOURCC_CODE('U', 'Y', 'V', 'Y'),
/// Grayscale 8bit.
GRAY = MAKE_FOURCC_CODE('G', 'R', 'A', 'Y'),
/// YUV 24bit per pixel format.
YUV24 = MAKE_FOURCC_CODE('Y', 'U', 'V', '3'),
/// NV12 pixel format.
NV12 = MAKE_FOURCC_CODE('N', 'V', '1', '2'),
/// NV21 pixel format.
NV21 = MAKE_FOURCC_CODE('N', 'V', '2', '1'),
/// YU12 (YUV420) - Planar pixel format.
YU12 = MAKE_FOURCC_CODE('Y', 'U', '1', '2'),
/// YV12 (YVU420) - Planar pixel format.
YV12 = MAKE_FOURCC_CODE('Y', 'V', '1', '2'),
/// JPEG compressed format.
JPEG = MAKE_FOURCC_CODE('J', 'P', 'E', 'G'),
/// H264 compressed format.
H264 = MAKE_FOURCC_CODE('H', '2', '6', '4'),
/// HEVC compressed format.
HEVC = MAKE_FOURCC_CODE('H', 'E', 'V', 'C')
};
Table 3 - Bytes layout of supported RAW pixel formats. Example of 4x4 pixels image.
Library principles
The filter algorithm implements Eulerian video magnification using Laplacian pyramid decomposition with temporal bandpass filtering and signal amplification. The algorithm involves the following sequential steps:
- Build a Laplacian pyramid from the intensity (luma) channel of the source video frame.
- Compute temporal bandpass-filtered differences at each pyramid level.
- Amplify the filtered signal according to the configured level.
- Reconstruct the magnified signal and blend it with the original intensity channel.
Steps 1 and 4 read and write the intensity channel of the video frame directly, converting the samples on the fly, and process the image as a stream of rows through a small buffer. The library therefore never allocates a full-resolution copy of the frame, which is what makes the processing time dominated by the pyramid arithmetic rather than by memory traffic.
The library is available as source code only. To utilize the library as source code, developers must incorporate the library files into their project. The usage sequence for the library is as follows:
- Include the library files in the project.
- Create an instance of the GasLeakDetector C++ class. If you need to process multiple cameras in parallel, you must create a separate GasLeakDetector instance for each.
- If necessary, modify the default library parameters using the setParam(…) method.
- Create a Frame class object for the input frame.
- Call the processFrame(…) method to magnify the video data stream.
GasLeakDetector class description
GasLeakDetector class declaration
GasLeakDetector.h file contains GasLeakDetector class declaration:
namespace cr
{
namespace video
{
/**
* @brief Gas leak detector class. Implements Eulerian video motion
* magnification to detect subtle intensity changes.
*/
class GasLeakDetector : public VFilter
{
public:
/** @brief Constructor. Creates GasLeakDetector object. */
GasLeakDetector();
/** @brief Destructor. Destroys GasLeakDetector object. */
~GasLeakDetector();
/** @brief Get string of current library version. */
static std::string getVersion();
/** @brief Initialize detector with given parameters. */
bool initVFilter(VFilterParams& params) override;
/** @brief Set detector parameter. */
bool setParam(VFilterParam id, float value) override;
/** @brief Get detector parameter value. */
float getParam(VFilterParam id) override;
/** @brief Get all detector parameters. */
void getParams(VFilterParams& params) override;
/** @brief Execute action command. */
bool executeCommand(VFilterCommand id) override;
/** @brief Process frame. */
bool processFrame(cr::video::Frame& frame) override;
/** @brief Set detector mask. */
bool setMask(cr::video::Frame mask) override;
/** @brief Decode and execute command from serialized data. */
bool decodeAndExecuteCommand(uint8_t* data, int size) override;
};
}
}
getVersion method
The getVersion() method returns string of current version of GasLeakDetector class. Method declaration:
static std::string getVersion();
Method can be used without GasLeakDetector class instance. Example:
cout << "GasLeakDetector v: " << GasLeakDetector::getVersion();
Console output:
GasLeakDetector v: 2.1.0
initVFilter method
The initVFilter(…) method initializes the GasLeakDetector class with a VFilterParams object that includes all video filter parameters. Method declaration:
bool initVFilter(VFilterParams& params) override;
| Parameter | Value |
|---|---|
| params | VFilterParams class object. The library uses only mode, level and custom1 (number of processing threads; values < 1 are ignored and the current value is kept) parameters. |
Returns: TRUE if the video filter initialized or FALSE if not.
setParam method
The setParam(…) method is designed to set a new GasLeakDetector object parameter value. setParam(…) is a thread-safe method. 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 the value is out of range. Parameter IDs not supported by the library are accepted and ignored (the method returns TRUE).
getParam method
The getParam(…) method is designed to obtain a library parameter value. getParam(…) is a thread-safe method. 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 parameter is not supported.
executeCommand method
The executeCommand(…) method is designed to execute a library command. executeCommand(…) is a thread-safe method. 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 was executed or FALSE if not.
processFrame method
The processFrame(…) method is designed to perform the magnification algorithm. The library provides a thread-safe processFrame(…) method call. This means that the processFrame(…) method can be safely called from any thread. Method declaration:
bool processFrame(cr::video::Frame& frame) override;
| Parameter | Description |
|---|---|
| frame | Video Frame object for processing. The filter processes only GRAY, YUV24, YUYV, UYVY, NV12, NV21, YV12, YU12 formats. The library uses pixel intensity (luma) for video processing. If the pixel format of the image does not include an intensity channel, it should be converted to a supported format before applying the filter. |
Returns: TRUE if the video frame was processed or FALSE if not. If the filter is disabled, the method returns TRUE.
setMask method
The setMask(…) method is designed to set the filter mask. The user can disable magnification in any areas of the video frame. For this purpose the user can create an image of any size and configuration with GRAY (preferable), NV12, NV21, YV12 or YU12 pixel format. Mask image pixel values equal to 0 prohibit magnification in the corresponding place of video frames. Any other mask pixel value other than 0 allows magnification at the corresponding location of video frames. The mask is used for magnification algorithms to compute a binary motion mask. The method can be called either before video frame processing or during video frame processing. Method declaration:
bool setMask(cr::video::Frame mask) override;
| Parameter | Description |
|---|---|
| mask | Image of magnification mask (Frame object). Must have GRAY (preferable), NV12, NV21, YV12 or YU12 pixel format. The size and configuration of the mask image can be any. If the size of the mask image differs from the size of processed frames, the mask will be scaled by the library for processing. The mask stays in effect until it is replaced by another call: if the resolution of the processed frames changes, the library scales the mask again for the new frame size. |
Returns: TRUE if the mask was accepted or FALSE if not (invalid pixel format or empty).
encodeSetParamCommand method of VFilter class
The encodeSetParamCommand(…) static method encodes a command to change any VFilter parameter value remotely. 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(…) is designed to encode a 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. Size will be 11 bytes. |
| id | Parameter ID according to VFilterParam enum. |
| value | Parameter value. |
encodeSetParamCommand(…) is static and can be 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 an action 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(…) is designed to encode a 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. Size will be 7 bytes. |
| id | Command ID according to VFilterCommand enum. |
encodeCommand(…) is static and can be 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::RESET);
decodeCommand method of VFilter class
The decodeCommand(…) static method decodes command on video filter side (on edge device). 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 (action 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 (action command), 1 - in case decoding SET_PARAM command or -1 in case errors.
decodeAndExecuteCommand method
The decodeAndExecuteCommand(…) method decodes and executes a command encoded by the encodeSetParamCommand(…) and encodeCommand(…) methods on the video filter side. The library provides a 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 video filter algorithm.
RESET = 1,
/// Enable filter.
ON,
/// Disable filter.
OFF
};
Table 4 - Action commands description.
| Command | Description |
|---|---|
| RESET | Reset filter. |
| ON | Enable filter. |
| OFF | Disable filter. |
VFilterParam enum
Enum declaration:
enum class VFilterParam
{
/// Filter mode: 0 - off, 1 - on. Depends on implementation.
MODE = 1,
/// Enhancement level for particular filter, as a percentage from
/// 0% to 100%. May have another meaning depends on implementation.
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 5 - Params description.
| Parameter | Access | Description |
|---|---|---|
| MODE | read / write | Mode. Default: 0 - Off, 1 - On. If the filter is not activated, frame processing is not performed and the frame is only forwarded. |
| LEVEL | read / write | Amplification factor adjusts the intensity of motion enhancement in videos, with higher values emphasizing motion changes and lower values maintaining the original motion characteristics. Supported values are from 0 to 100%. |
| PROCESSING_TIME_MCSEC | read only | Processing time in microseconds. Read only parameter. Used to check performance of GasLeakDetector and shows processing time for last frame. |
| TYPE | read / write | Not supported by GasLeakDetector library. |
| CUSTOM_1 | read / write | Number of threads for frame processing. Supported values from 1 to 128. Default: 1 (single-threaded processing). Setting the number of threads is thread-safe and can be done at any time during processing. Processing results are bitwise identical for any number of threads. Has effect only if the library is built with OpenMP support (found automatically by CMake). |
| CUSTOM_2 | read / write | Not supported by GasLeakDetector library. |
| CUSTOM_3 | read / write | Not supported by GasLeakDetector library. |
VFilterParams class description
VFilterParams class declaration
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:
namespace cr
{
namespace video
{
/// VFilter parameters class.
class VFilterParams
{
public:
/// Filter mode: 0 - off, 1 - on. Depends on implementation.
int mode{ 1 };
/// Enhancement level for particular filter, as a percentage from
/// 0% to 100%. May have another meaning depends on implementation.
float level{ 0.0f };
/// 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 6 - VFilterParams class fields description is related to VFilterParam enum description.
| Field | type | Description |
|---|---|---|
| mode | int | Mode. Default: 0 - Off, 1 - On. If the library is not activated, frame processing is not performed, it will be only forwarded. |
| level | float | Amplification factor adjusts the intensity of motion enhancement in videos, with higher values emphasizing motion changes and lower values maintaining the original motion characteristics. Supported values are from 0 to 100%. |
| processingTimeMcSec | int | Processing time in microseconds. Read only parameter. Used to check performance of GasLeakDetector and shows processing time for last frame. |
| type | int | Not supported by GasLeakDetector library. |
| custom1 | float | Number of threads for frame processing. Supported values from 1 to 128. Default: 1 (single-threaded processing). Processing results are bitwise identical for any number of threads. |
| custom2 | float | Not supported by GasLeakDetector library. |
| custom3 | float | Not supported by GasLeakDetector library. |
Note: VFilterParams class fields listed in Table 6 must reflect params set/get by the methods setParam(…) and getParam(…).
Serialize VFilter params
VFilterParams class provides method encode(…) to serialize VFilter params. Serialization of VFilterParams is necessary in case when video 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 >= 32 bytes. |
| bufferSize | Data buffer size. Buffer size must be >= 32 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 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 (buffer size < 32).
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::VFilterParamsMask mask;
// Exclude level.
mask.level = false;
// Encode (serialize) params.
int bufferSize = 128;
uint8_t buffer[128];
int size = 0;
params.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:
// Prepare random params.
cr::video::VFilterParams params1;
params1.mode = 1;
params1.level = 10.1f;
params1.processingTimeMcSec = 10;
params1.type = 2;
params1.custom1 = 22.3;
params1.custom2 = 23.4;
params1.custom3 = 24.5;
// Save to JSON.
cr::utils::ConfigReader configReader1;
if (!configReader1.set(params1, "Params"))
std::cout << "Can't set params" << std::endl;
if (!configReader1.writeToFile("VFilterParams.json"))
std::cout << "Can't write to file" << std::endl;
// Read params from file.
cr::utils::ConfigReader configReader2;
if (!configReader2.readFromFile("VFilterParams.json"))
std::cout << "Can't read from file" << std::endl;
cr::video::VFilterParams params2;
if (!configReader2.get(params2, "Params"))
std::cout << "Can't get params" << std::endl;
VFilterParams.json will look like:
{
"Params": {
"custom1": 22.3,
"custom2": 23.4,
"custom3": 24.5,
"level": 10.1,
"mode": 1,
"type": 2
}
}
Build and connect to your project
Before building, the user has to install the OpenCV library (for the demo application and example). Example for Linux Ubuntu:
sudo apt install libopencv-dev
Typical commands to build GasLeakDetector library:
cd GasLeakDetector
mkdir build
cd build
cmake ..
make
If you want to connect GasLeakDetector to your CMake project as source code, you can do the following. For example, if your repository has this structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
Create folder 3rdparty in your repository and copy GasLeakDetector repository folder there. New structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
GasLeakDetector
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(GasLeakDetector)
File 3rdparty/CMakeLists.txt adds folder GasLeakDetector (by default test applications and example excluded from compiling if GasLeakDetector included as sub-repository). The new structure of your repository will be:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
GasLeakDetector
Next, you need to include the 3rdparty folder in the main CMakeLists.txt file of your repository. Add the following string at the end of your main CMakeLists.txt:
add_subdirectory(3rdparty)
Next, you have to include GasLeakDetector library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} GasLeakDetector)
Done!
Example
A simple application that shows how to use the GasLeakDetector library. The application opens a video file “test.mp4”.
#include <opencv2/opencv.hpp>
#include "GasLeakDetector.h"
int main(void)
{
// Open video file "test.mp4".
cv::VideoCapture videoSource;
if (!videoSource.open("test.mp4"))
return -1;
// Create frames.
cv::Mat bgrImg;
int width = (int)videoSource.get(cv::CAP_PROP_FRAME_WIDTH);
int height = (int)videoSource.get(cv::CAP_PROP_FRAME_HEIGHT);
cr::video::Frame frameYuv(width, height, cr::video::Fourcc::YUV24);
// Create gas leak detector and set initial params.
cr::video::GasLeakDetector filter;
filter.setParam(cr::video::VFilterParam::MODE, 1); // Enable.
filter.setParam(cr::video::VFilterParam::LEVEL, 50); // 50% level.
filter.setParam(cr::video::VFilterParam::CUSTOM_1, 2); // 2 threads.
// Main loop.
while (true)
{
// Capture next video frame. Default BGR pixel format.
videoSource >> bgrImg;
if (bgrImg.empty())
{
// Set initial video position to replay.
videoSource.set(cv::CAP_PROP_POS_FRAMES, 0);
continue;
}
// Convert BGR to YUV for filter.
cv::Mat yuvImg(height, width, CV_8UC3, frameYuv.data);
cv::cvtColor(bgrImg, yuvImg, cv::COLOR_BGR2YUV);
// Magnify movement with default params.
filter.processFrame(frameYuv);
// Convert result YUV to BGR to display.
cv::cvtColor(yuvImg, bgrImg, cv::COLOR_YUV2BGR);
// Show video.
cv::imshow("VIDEO", bgrImg);
if (cv::waitKey(1) == 27)
return 0;
}
return 1;
}
Benchmark
Benchmark allows you to evaluate the speed of the algorithm on different platforms. This is a console application that allows you to enter initial parameters (frame width and height) after startup. After entering the parameters, the application continuously generates synthetic video frames and processes them, printing statistics (minimum / average / maximum processing time per frame) after every 100 processed frames until the application is closed. Benchmark console interface:
=================================================
GasLeakDetector v2.1.0 benchmark
Average processing time per frame
=================================================
Set frame width: 1920
Set frame height: 1080
Time 1.893 -> 2.248 -> 3.146 msec
Time 1.861 -> 2.238 -> 5.647 msec
Time 1.903 -> 2.331 -> 3.652 msec
Time 1.865 -> 2.245 -> 3.15 msec
The benchmark application uses the default number of processing threads (one thread). The processing speed for a different number of threads can be evaluated with the demo application (keys 1-4).
Demo application
The demo application is intended to evaluate the performance of the GasLeakDetector C++ library. The application allows you to evaluate the magnification algorithm with a chosen video file. It is a console application and can be used as an example of GasLeakDetector library usage. The application uses the OpenCV (version 4.5 and higher) library for capturing video, recording video, displaying video, and forming a simple user interface. The demo application does not require installation. The demo application is compiled for Windows OS x64 (Windows 10 and newer) as well as for Linux OS (several distros; to get the demo application for a specific Linux distro, send us a request). Table 7 shows the list of files of the demo application.
Table 7 - List of files of demo application (example for Windows OS).
| File | Description |
|---|---|
| GasLeakDetectorDemo.exe | Demo application executable file for windows OS. |
| opencv_world480.dll | OpenCV library file version 4.8.0 for Windows x64. |
| opencv_videoio_msmf480_64.dll | OpenCV library file version 4.8.0 for Windows x64. |
| opencv_videoio_ffmpeg480_64.dll | OpenCV library file version 4.8.0 for Windows x64. |
| VC_redist.x64 | Installer of necessary system libraries for Windows x64. |
| src | Folder with application source code. |
| test.mp4 | Test video file. |
To launch demo application run GasLeakDetectorDemo.exe executable file on Windows x64 OS or run commands on Linux:
sudo chmod +x GasLeakDetectorDemo
./GasLeakDetectorDemo
If a message about missing system libraries appears (on Windows OS) when launching the application, you must install the VC_redist.x64.exe program, which will install the system libraries required for operation. After starting, the user must choose a video source:
=================================================
GasLeakDetector v2.1.0 demo application
=================================================
Open file dialog? (y/n) y
The user should choose between a file dialog and an initialization string (for OpenCV). If the user does not choose the file dialog option, the application will ask to enter a video source initialization string: the user can manually set a file name, camera number (0, 1, 2, etc.) or an RTSP initialization string (example: rtsp://192.168.0.1:7031/live). After that, the user will see the user interface as shown below (if the video source is open and a region of interest is set).

To control the application, it is necessary that the main video display window was active (in focus), and also it is necessary that the English keyboard layout was activated without CapsLock mode. The program is controlled by the keyboard and mouse (magnification ROI control).
Table 8 - Control buttons.
| Button | Description |
|---|---|
| ESC | Exit the application. If video recording is active, it will be stopped. |
| SPACE | Reset filter. |
| R | Start/stop video recording. When video recording is enabled, a file dst_[date and time].avi (result video) is created in the directory with the application executable file. The recording contains the full-resolution processed video without the on-screen hints and ROI markings shown in the display window (the displayed video may additionally be downscaled to 720p). To stop the recording, press the R key again. During video recording, the application shows a warning message. |
| E | Enable/disable filter. |
| 1 | Set 1 processing thread (default). |
| 2 | Set 2 processing threads. |
| 3 | Set 3 processing threads. |
| 4 | Set 4 processing threads. |
Magnification level can be changed by slider. The user can set the magnification mask (mark a rectangular area where image will be magnified). In order to set a rectangular magnification area it is necessary to draw a line with the mouse with the left button pressed from the left-top corner of the required magnification area to the right-bottom corner. The magnification area will be marked in blue color as shown in the image.
The application shows on the video the current number of processing threads and the hint about control keys (1, 2, 3 or 4 to set the number of threads). The processing time shown on the video allows to evaluate the performance for the chosen number of threads.