
Dehazer C++ library
v4.0.0
Table of contents
- Overview
- Versions
- Library files
- Key features and capabilities
- Supported pixel formats
- Library principles
- Dehazer class description
- Dehazer class declaration
- initVFilter method
- getVersion method
- setParam method
- getParam method
- getParams 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
Dehazer C++ library implements a video defog / dehaze algorithm based on local histogram equalization (low-resolution grid CLAHE). The library improves the local contrast of the video frame to reduce the effect of haze and to increase the visibility of low-contrast objects. The library is implemented in C++ (C++17 standard) and has no external dependencies beyond the VFilter interface. This library is suitable for various types of camera (daylight, SWIR, MWIR and LWIR) and it provides simple programming interface. Each instance of the Dehazer C++ class object performs frame-by-frame processing of a video data stream, processing each video frame independently. The library includes optimized SIMD paths for x86 (AVX2 and an SSE2 fallback), for ARM (NEON) and a scalar fallback for any other architecture; the path is selected at compile time from the build flags, so the SSE2 or scalar path is what a build without /arch:AVX2 (-mavx2) produces — note that the default Release flags of this project do target AVX2, which requires an AVX2-capable CPU. The library depends on open source VFilter library (provides interface as well as defines data structures for various video filters implementation, source code included, Apache 2.0 license). Demo application and example additionally depend on OpenCV library (version >=4.5.0, linked, Apache 2.0 license). Demo application also depends on open source SimpleFileDialog (provides dialog to open files, source code included, Apache 2.0 license).
Versions
Table 1 - Library versions.
| Version | Release date | What’s new |
|---|---|---|
| 1.0.0 | 11.12.2023 | First version based on histogram manipulation. |
| 2.0.0 | 21.02.2024 | - Library updated with VFilter interface. - Added CLAHE algorithm as second algorithm type. |
| 2.0.1 | 24.03.2024 | - VFilter class updated. - SimpleFileDialog class updated. - Documentation updated. |
| 2.0.2 | 21.05.2024 | - Submodules updated. - Documentation updated. |
| 2.0.3 | 19.07.2024 | - CMake updated. - Files structure updated. |
| 3.0.0 | 01.04.2026 | - OpenCV dependency removed from core library. - Own CLAHE implementation with AVX2/NEON/scalar paths. - Added CUSTOM_1 (CLAHE grid size) and CUSTOM_2 (thread count) parameters. - Performance optimizations. |
| 3.1.0 | 22.07.2026 | - Added sliding-window CLAHE as third algorithm type (TYPE=2): per-pixel local 16-bin histogram from a sliding NxN window, no tile subdivision, no interpolation between tiles. - Soft-binned histograms and continuous CDF evaluation keep uniform areas and smooth gradients free of banding artifacts. - Local brightness anchoring: uniform areas keep their tone while local detail contrast is amplified (up to ~8x). - Single-pass separable implementation on per-column sliding histograms (no full-frame integral surfaces, ~1 byte of temporary memory per pixel). - Added CUSTOM_3 parameter: sliding CLAHE window size (32/64/128, default 64). - Added low-resolution grid CLAHE as fourth algorithm type (TYPE=3): full 256-bin histograms on a downscaled 128x128 grid, original pixels remapped through bilinearly blended cell LUTs. |
| 4.0.0 | 31.07.2026 | - Performance optimization. - Algorithm changed for slide-clahe version. - Parameters usage simplified. |
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 --------------- Files with VFilter library source code.
src ----------------------- Folder with library source code.
CMakeLists.txt -------- CMake file of the library.
Dehazer.h ------------- Main library header file.
DehazerVersion.h ------ Header file with library version.
DehazerVersion.h.in --- Service CMake file to generate version header.
Dehazer.cpp ----------- C++ implementation file.
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 folder 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 test application (benchmark).
CMakeLists.txt -------- CMake file of test application (benchmark).
main.cpp -------------- Source C++ file of test application.
static -------------------- Images used by this document.
compiled ------------------ Prebuilt demo application packages.
Key features and capabilities
Table 2 - Key features and capabilities.
| Parameter and feature | Description |
|---|---|
| Programming language | C++ (standard C++17). No external dependencies for core library. |
| Supported OS | Compatible with any operating system that supports the C++ compiler (C++17 standard). |
| Algorithm type | Single algorithm: low-resolution grid CLAHE. The Y channel is downscaled to 128x128 with bilinear interpolation; for every downscaled element a 64-bin histogram of its 16x16 neighborhood is computed (pixel values are split proportionally between the two nearest bins, so no intensity precision is lost) and turned into a contrast-limited equalization LUT with 256 entries reconstructed by interpolation (the effective context is about 1/8 of the frame per dimension); every original pixel is remapped through the bilinear blend of its four nearest cell LUTs (the blend is evaluated at full precision and quantized with an 8x8 ordered dither, so no grid-aligned contouring appears on smooth areas). LUTs are smoothed over intensity (caps noise amplification on uniform backgrounds at ~13x per intensity level in the interior of the range, up to about twice that within two histogram bins of black and white where the odd end reflection shortens the smoothing window; no grain), LEVEL=0 returns the frame untouched, LEVEL=100 is almost full local equalization. |
| Memory | All working memory is allocated as a single block of 9 306 624 bytes (~8.9 MiB) by the class constructor and freed by the destructor. The size does not depend on the frame resolution and there are no per-frame allocations. Breakdown: per-cell LUTs stored as interleaved horizontal pairs 128x128x512 = 8 388 608 bytes; per-thread column histograms 32x128x64x2 = 524 288 bytes; internal mask 512x512 + 512 per-row states = 262 656 bytes; per-pixel mapping tables (6 tables, 14 bytes per pixel coordinate) 14x8192 = 114 688 bytes; downscaled image 128x128 = 16 384 bytes (the items sum to exactly the total: the layout needs no padding). Additionally each worker thread uses up to ~10 KB of stack during processFrame(). |
| Supported pixel formats | GRAY, YUV24, YUYV, UYVY, NV12, NV21, YV12, YU12. The library uses pixels intensity for video processing. If the pixel format of the image doesn’t include intensity channel it should be converted to proper format before applying dehazing. |
| Maximum and minimum video frame size | The intended size range is from 16x16 to 8192x8192 pixels. Frames wider or taller than 8192 pixels are rejected (processFrame returns FALSE); frames smaller than 16x16 are accepted, but the 128x128 cell grid degenerates at that size and the result is not meaningful. The size of the video frames to be processed has a significant impact on the computation speed. |
| Calculation speed | The processing time per video frame depends on the computing platform used. The processing time per video frame can be estimated with the benchmark application. |
Supported pixel formats
Frame library, which is included in Dehazer library contains Fourcc enum, which defines supported pixel formats (Frame.h file). Dehazer library supports intensity channel included pixel formats only (GRAY, YUV24, YUYV, UYVY, NV12, NV21, YV12, YU12). The library utilizes 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 library is available as a source code only. To utilize the library as source code, developers have to incorporate the library files into their project. The usage sequence for the library is following:
- Include the library files in the project.
- Create an instance of the Dehazer C++ class. If you need multiple parallel cameras processing you have to create multiple Dehazer C++ class instances. The working memory (9 306 624 bytes ≈ 8.9 MiB per instance, independent of the frame size) is allocated once by the constructor; there are no per-frame allocations.
- If necessary, modify the default library parameters (MODE, LEVEL, CUSTOM_2 = number of threads) using the setParam(…) method.
- Create Frame class object for input frame.
- Call the processFrame(…) method for frame processing.
- The algorithm applies changes on the input original frame (taking into account mask if necessary).
Dehazer class description
Dehazer class declaration
Dehazer.h file contains Dehazer class declaration.
namespace cr
{
namespace video
{
class Dehazer : public VFilter
{
public:
/// Class constructor. Allocates the working buffers.
Dehazer();
/// Class destructor. Frees the working buffers.
~Dehazer();
/// Get string of current library version.
static std::string getVersion();
/// Initialize video filter.
bool initVFilter(VFilterParams& params) override;
/// Set parameter.
bool setParam(VFilterParam id, float value) override;
/// Get parameter value.
float getParam(VFilterParam id) override;
/// Get all library parameters.
void getParams(VFilterParams& params) override;
/// Execute action command.
bool executeCommand(VFilterCommand id) override;
/// Process frame.
bool processFrame(Frame& frame) override;
/// Set mask for the filter.
bool setMask(cr::video::Frame mask) override;
/// Decode and execute command.
bool decodeAndExecuteCommand(uint8_t* data, int size) override;
};
}
}
getVersion method
The getVersion() method returns string of current version of Dehazer class. Method declaration:
static std::string getVersion();
Method can be used without Dehazer class instance. Example:
std::cout << "Dehazer version: " << Dehazer::getVersion();
Console output:
Dehazer version: 4.0.0
initVFilter method
The initVFilter(…) method initializes dehazer filter with applied parameters. The method will call setParam(…) method for parameters: mode and level. Method declaration:
bool initVFilter(VFilterParams& params) override;
| Parameter | Value |
|---|---|
| params | VFilterParams class object. Parameters supported by Dehazer: mode (default value 0) level (default value 0.0) If any parameter is out of valid range, the method will return FALSE. |
Returns: TRUE if the dehazer initialized or FALSE if not.
setParam method
The setParam(…) method sets Dehazer 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. The library supports parameters: MODE, LEVEL and CUSTOM_2. For other parameters the method will return FALSE. |
| value | Parameter value. Value depends on parameter ID. |
Returns: TRUE if the parameter was set or FALSE if not (if it is read-only parameter or parameter value out of range).
getParam method
The getParam(…) method returns Dehazer 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. The library supports parameters: MODE, LEVEL, PROCESSING_TIME_MCSEC and CUSTOM_2. For other parameters the method will return -1. |
Returns: parameter value or -1, if the parameter ID is not supported.
getParams method
The getParams(…) method is designed to obtain params structure and it is thread-safe. 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 library action command and it is thread-safe. 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 processes the given frame. If the mode is set to 0 (disabled), the method will skip the frame and return true without inspecting it. If LEVEL is 0 the frame is also returned untouched (the transform would be an identity) and the method returns true, but the pixel format and the frame size are validated first.
bool processFrame(cr::video::Frame& frame) override;
| Parameter | Description |
|---|---|
| frame | Video Frame for processing. Implemented algorithm takes frame as a source and process original video frame. Dehazer processes only GRAY, YUV24, YUYV, UYVY, NV12, NV21, YV12, YU12 formats. The library utilizes pixels intensity for video processing. If the pixel format of the image doesn’t include intensity channel it should be converted to proper format before dehazing. The intended frame size range is from 16x16 to 8192x8192 pixels: frames larger than 8192 pixels in any dimension are rejected (the method returns FALSE), while frames smaller than 16x16 are accepted but produce a meaningless result because the 128x128 cell grid degenerates. |
Returns: TRUE if frame was successfully processed or skipped, FALSE if method encountered an error.
setMask method
The setMask(…) method designed to set filtration mask. The user can disable dehazing in any area of the video frame. For this purpose the user can create an image of any size with GRAY, NV12, NV21, YV12 or YU12 pixel format (only the Y plane is read). Mask image pixel values equal to 0 prohibit video filtration in the corresponding area of video frames. Any mask pixel value different than 0 allows to apply filter in this area. 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 | Filtration mask in form of Frame object with GRAY, NV12, NV21, YV12 or YU12 pixel format (only the Y plane is read; other formats are rejected). Dehazer omits image segments, where filtration mask pixel values equal 0. Mask can have any resolution: the library stores it internally at a fixed 512x512 resolution (nearest-neighbor resampled) and maps it to the processed video resolution. |
Returns: TRUE if the mask is accepted or FALSE if not (not valid pixel format or empty).
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
decodeAndExecuteCommand(…) method decodes and executes command encoded on video filter side. 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. Should 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) or FALSE if not.
Data structures
VFilterCommand enum
Enum declaration:
enum class VFilterCommand
{
/// Restart image filter algorithm.
RESET = 1,
/// Enable filter.
ON,
/// Disable filter.
OFF
};
Table 4 - Action commands description.
| Command | Description |
|---|---|
| RESET | Not supported by Dehazer class. |
| ON | Enable video filter. |
| OFF | Disable video filter. |
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 5 - Params description.
| Parameter | Access | Description |
|---|---|---|
| MODE | read / write | Current filter mode: 0 - off, 1 - on. When the mode is set to 0, processFrame just forwards frame without processing and returns true. |
| LEVEL | read / write | Enhancement level as a percentage in range from 0% to 100%. Controls the contrast-limiting clip threshold with a cubic response: 0 - no enhancement at all (the frame is returned untouched, see processFrame), mid values - moderate local contrast enhancement with firmly limited noise amplification, 100 - almost full local histogram equalization. Values out of range are rejected (setParam returns FALSE). Default value: 0. |
| PROCESSING_TIME_MCSEC | read only | Processing time in microseconds. Read only parameter. Used to control performance of video filter. |
| TYPE | not supported | Not supported: the library implements a single algorithm (low-resolution grid CLAHE). setParam returns FALSE, getParam returns -1. |
| CUSTOM_1 | not supported | Custom parameter. Not supported by Dehazer. setParam returns FALSE, getParam returns -1. |
| CUSTOM_2 | read / write | Number of threads for parallel processing. Valid range: integer from 1 to 32 inclusive. Default value: 1 (sequential processing). Any value outside this range will be rejected (setParam returns FALSE). Multi-threading requires the library to be compiled with OpenMP support (_OPENMP defined); without OpenMP the parameter is accepted but processing remains single-threaded. At run time the value is additionally clamped to the number of available hardware threads. Recommendation for Linux (libgomp): when the thread count approaches the machine’s hardware thread count, run the process with OMP_WAIT_POLICY=passive — the default (active) policy makes idle threads spin at barriers and can collapse multi-threaded performance when every hardware thread is occupied; on hybrid P/E-core CPUs the best throughput is usually reached with the thread count close to the number of physical performance cores. |
| CUSTOM_3 | not supported | Custom parameter. Not supported by Dehazer. setParam returns FALSE, getParam returns -1. |
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:
class VFilterParams
{
public:
/// Current filter mode, usually 0 - off, 1 - on.
int mode{ 1 };
/// 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 6 - VFilterParams class fields description is related to VFilterParam enum description.
| Field | type | Description |
|---|---|---|
| mode | int | Current filter mode, 0 - off, 1 - on. When the mode is set to 0, processFrame just forwards frame without processing and returns true. |
| level | float | Enhancement level as a percentage in range from 0% to 100%. 0 - identity transform, 100 - almost full local histogram equalization. |
| processingTimeMcSec | int | Processing time in microseconds. Read only parameter. Used to control performance of video filter. |
| type | int | Not used: the library implements a single algorithm. getParams() always returns 0. |
| custom1 | float | Not supported by Dehazer. getParams() always returns -1. |
| custom2 | float | Number of threads for parallel processing. Valid range: integer from 1 to 32 inclusive. Default value: 1 (sequential processing). Multi-threading requires the library to be compiled with OpenMP support (_OPENMP defined). |
| custom3 | float | Not supported by Dehazer. getParams() always returns -1. |
Note: VFilterParams class fields listed in Table 6 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 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.0f;
// 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
Typical commands to build Dehazer library:
cd Dehazer
mkdir build
cd build
cmake ..
make
If you want to connect Dehazer library to your CMake project as source code, you can do the following. For example, if your repository has structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
Create folder 3rdparty in your repository folder and copy Dehazer repository folder there. The new structure of your repository will be as follows:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
Dehazer
Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should be containing:
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
################################################################################
if (${PARENT}_SUBMODULE_DEHAZER)
add_subdirectory(Dehazer)
endif()
File 3rdparty/CMakeLists.txt adds folder Dehazer to your project and excludes test applications and examples from compiling (by default test applications and example excluded from compiling if Dehazer included as sub-repository). The new structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
Dehazer
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 Dehazer library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} Dehazer)
Done!
Example
An example shows how to use the Dehazer library. The application opens a video file “test.mp4” and copies the video frame data into an object of the Frame class and performs dehazing.
#include <iostream>
#include <opencv2/opencv.hpp>
#include "Dehazer.h"
int main(void)
{
// Open video source.
cv::VideoCapture source;
if (!source.open("test.mp4"))
return -1;
// Init dehazer.
cr::video::Dehazer dehazer;
dehazer.setParam(cr::video::VFilterParam::MODE, 1);
dehazer.setParam(cr::video::VFilterParam::LEVEL, 50);
// Get frame size.
int width = (int)source.get(cv::CAP_PROP_FRAME_WIDTH);
int height = (int)source.get(cv::CAP_PROP_FRAME_HEIGHT);
// Init frames.
cv::Mat openCvBgrImg(height, width, CV_8UC3);
cr::video::Frame frame(width, height, cr::video::Fourcc::YUV24);
// Main loop.
while (true)
{
// Capture next video frame.
source >> openCvBgrImg;
if (openCvBgrImg.empty())
return 0;
// Convert BGR to YUV.
cv::Mat yuvImg(frame.height, frame.width, CV_8UC3, frame.data);
cvtColor(openCvBgrImg, yuvImg, cv::COLOR_BGR2YUV);
// Dehaze.
dehazer.processFrame(frame);
// Convert YUV to BGR.
cvtColor(yuvImg, openCvBgrImg, cv::COLOR_YUV2BGR);
// Show results.
imshow("Result", openCvBgrImg);
if (cv::waitKey(30) == 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 after startup. After entering the parameters, the application will create one synthetic frame and process it 100 times, then calculate and show statistics (minimum / average / maximum processing time per frame) and repeat until it is stopped. Benchmark console interface:
--------------------------------------------------
Dehazer v4.0.0 benchmark
Benchmark will process 100 frames and will show
processing time per frame
--------------------------------------------------
Set frame width: 1290
Set frame height: 720
Set number of threads for processing: 4
Processing time: 2.87 -> 3.733 -> 40.799 msec
Processing time: 2.862 -> 3.298 -> 4.518 msec
Processing time: 2.503 -> 3.621 -> 8.356 msec
Processing time: 2.556 -> 2.837 -> 4.675 msec
Processing time: 2.447 -> 2.87 -> 3.62 msec
Processing time: 2.527 -> 2.885 -> 5.494 msec
Demo application
Demo application overview
The demo application is intended to evaluate the performance of the Dehazer C++ library. The application allows you to evaluate the operation of the algorithm with different dehazing levels and thread counts. It is console application and serves as an example of using the Dehazer library. The application uses the OpenCV library for capturing video, recording video, displaying video, and forming a simple user interface.
Launch and user interface
The demo application does not require installation. The demo application compiled for Windows OS x64 (Windows 10 and newer) as well for Linux OS (few distros, to get demo application for specific Linux distro send us request). Table 7 shows list of files of demo application.
Table 7 - List of files of demo application (example for Windows OS).
| File | Description |
|---|---|
| DehazerDemo.exe | Demo application executable file for windows OS. |
| opencv_world4120.dll | OpenCV library file version 4.12.0 for Windows x64. |
| opencv_videoio_ffmpeg4120_64.dll | OpenCV library file version 4.12.0 for Windows x64. |
| VC_redist.x64 | Installer of necessary system libraries for Windows x64 (use if required). |
| src | Folder with application source code. |
To launch demo application run DehazerDemo.exe executable file on Windows x64 OS or run commands on Linux:
sudo chmod +x DehazerDemo
./DehazerDemo
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 application (running the executable file) the user should select the video file in the dialog box (if typed “y” to run file dialog). After that the user will see the user interface as shown below. Image at the top is the source image and image at the bottom shows results of algorithm.

Control
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.
Table 8 - Control buttons.
| Button | Description |
|---|---|
| ESC | Exit the application. If video recording is active, it will be stopped. |
| SPACE | Enable / disable dehazing algorithm. |
| 2 | Cycle thread count: 1 → 2 → 4 → 8 → 1 … Default - 1. |
| R | Start/stop video recording. When video recording is enabled, files dst_[date and time].avi (result video) and mix_[date and time].avi (combined source and result video) are created in the directory with the application executable file. To stop the recording, press the R key again. During video recording, the application shows a warning message. |
| Level | Dehazing algorithm enhancement value trackbar, can be set by dragging slider with a mouse. |
The user can set the filtration mask (mark a rectangular area where dehazing will be applied). In order to set a rectangular filtration area it is necessary to draw a line with the mouse with the left button pressed from the top-left corner of the required area to the bottom-right corner. The filtration area will be marked in blue color as shown in the image.