![]()
BadPixelProcessor C++ library
v1.1.0
Table of contents
- Overview
- Versions
- Library files
- BadPixelProcessor class description
- BadPixelProcessor class declaration
- getVersion method
- initVFilter method
- setParam method
- getParam method
- executeCommand method
- processFrame method
- setMask method
- setBadPixelsConfigFilePath 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
Overview
The BadPixelProcessor library is designed to detect and correct bad pixels on video from thermal cameras (LWIR, MWIR, and SWIR). The working principle: the library takes RAW images. When the first video frame comes to the library, it reads the config file with the list of bad pixel coordinates and initializes the internal buffer. If the config file contains bad pixel coordinates, the library replaces such pixels with mean values of neighbor pixels. Also, the library automatically detects bad pixels on video after a user command and stores coordinates in the config file. To detect bad pixels, the user must provide flat surfaces that cover the field of view of the camera. In addition, the library performs an image flip operation if necessary. The library accepts video frames only with YUV24 pixel format (see Frame class description). The library uses only the Y (brightness) component of YUV24 pixels. Any pixel can be considered as a bad pixel only if: 1. The value (brightness) is less than the low threshold (default 20) or greater than the high threshold (default 235) (see VFilterParam enum parameters CUSTOM_1 and CUSTOM_2). 2. The value of the pixel did not change by more than the threshold during the past 60 frames. 3. The difference between the pixel candidate and its neighbor is more than the threshold (see VFilterParam enum parameter LEVEL). The library is implemented in C++ (C++17 standard) and does not have third-party dependencies to be installed in the system. Each instance of the BadPixelProcessor C++ class object performs frame-by-frame processing of a video data stream, processing each video frame independently. The bad pixel detection and correction algorithm works only on one CPU core. The library depends on the open-source VFilter library (provides an interface and defines data structures for various video filter implementations, source code included, Apache 2.0 license). Additionally, the example application depends on OpenCV (provides user interface, version >= 4.5, linked, Apache 2.0 license). The library is compatible with Linux and Windows.
Versions
Table 1 - Library versions.
| Version | Release date | What’s new |
|---|---|---|
| 1.0.0 | 29.11.2025 | - First version. |
| 1.1.0 | 11.12.2025 | - Added flip image option. - Updated approach to applying the threshold. |
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.
src -------------------------------- Folder with library source code.
CMakeLists.txt ----------------- CMake file of the library.
BadPixelProcessor.h ------------ Main library header file.
BadPixelProcessor.cpp ---------- C++ implementation file.
BadPixelProcessorVersion.h.in -- File for CMake to generate version header.
BadPixelProcessorVersion.h ----- Library version header file.
example ---------------------------- Folder for example application.
CMakeLists.txt ----------------- CMake file of example.
main.cpp ----------------------- Source C++ file of example.
BadPixelProcessor class description
BadPixelProcessor class declaration
The BadPixelProcessor.h file contains BadPixelProcessor class declaration:
namespace cr
{
namespace video
{
class BadPixelProcessor : public VFilter
{
public:
/// Get string of current library version.
static std::string getVersion();
/// Initialize filter.
bool initVFilter(VFilterParams& params) override;
/// Set filter parameter.
bool setParam(VFilterParam id, float value) override;
/// Get filter parameter value.
float getParam(VFilterParam id) override;
/// Get all filter parameters.
void getParams(VFilterParams& params) override;
/// Execute action command.
bool executeCommand(VFilterCommand id) override;
/// Process frame.
bool processFrame(cr::video::Frame& frame) override;
/// Set filter mask. Not supported in current version.
bool setMask(cr::video::Frame mask) override;
/// Decode and execute command.
bool decodeAndExecuteCommand(uint8_t* data, int size) override;
/// Set path to config file with bad pixels coordinates.
void setBadPixelsConfigFilePath(std::string path);
};
}
}
getVersion method
The getVersion() method returns a string of the current version of the BadPixelProcessor class. Method declaration:
static std::string getVersion();
Method can be used without BadPixelProcessor class instance. Example:
cout << "BadPixelProcessor v: " << BadPixelProcessor::getVersion();
Console output:
BadPixelProcessor v: 1.1.0
initVFilter method
The initVFilter(…) method initializes the BadPixelProcessor 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, custom1 and custom2 parameters. |
Returns: TRUE if the video filter was initialized or FALSE if not.
setParam method
The setParam(…) method is designed to set a new BadPixelProcessor 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. The library accepts only parameters LEVEL, CUSTOM_1, CUSTOM_2, and CUSTOM_3. |
| value | Parameter value. Value depends on parameter ID. |
Returns: TRUE if the parameter was set or FALSE if not.
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. The commands are used to enable/disable video processing and to start bad pixel detection. 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 bad pixel correction algorithm. After the first frame, the library reads the config file (if a path to the config file was set by the user). The config file includes video frame width, height, and a list of bad pixel coordinates. The library loads the list of bad pixel coordinates. If the width and height written in the config file are different from the actual video frame size, the library will reset the list of bad pixel coordinates. According to the bad pixel coordinates, the library corrects them (if processing is enabled) by replacing them with the mean value of neighbor pixels. When bad pixel detection mode is enabled (RESET command, see VFilterCommand enum), the library collects 60 video frames and detects bad pixels, resetting the previous list of coordinates. The new coordinates and video frame size (width and height) will be saved in the config file (if set by the user in advance). Method declaration:
bool processFrame(cr::video::Frame& frame) override;
| Parameter | Description |
|---|---|
| frame | Video Frame object for processing. Filter processes only YUV24 format. |
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 a filter mask. Not supported in the BadPixelProcessor class. Method declaration:
bool setMask(cr::video::Frame mask) override;
| Parameter | Description |
|---|---|
| mask | Image of magnification mask (Frame object). |
Returns: always returns FALSE.
setBadPixelsConfigFilePath method
The setBadPixelsConfigFilePath(…) method sets the path to the configuration file. The library reads bad pixel coordinates from the config file and writes coordinates to the file after bad pixel detection. If the user does not set the path to the config file, the library will not read or save any config file. If the user does not set the path to the config file, the library will not be able to keep bad pixel coordinates, and the user must run bad pixel detection after every start. Method declaration:
void setBadPixelsConfigFilePath(std::string path);
| Parameter | Description |
|---|---|
| path | Path to config file. Example: “/home/pi/Downloads/BadPixelCoordinates.json”. |
The config file includes video frame size (width and height) and bad pixel coordinates (X and Y coordinates) on video. At the moment of first video frame processing, the library reads the config file and compares the frame width and height in the config file with the input width and height. If the width or height is different, the library will reset all bad pixel coordinates. The structure of the config file (includes coordinates for 3 bad pixels):
{
"Params": {
"badPixelsX": [
1,
446,
527,
],
"badPixelsY": [
14,
14,
29
],
"height": 1024,
"width": 1280
}
}
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 their 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 the 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 a VFilter class instance. This method is used on the 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 their 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 the 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 a VFilter class instance. This method is used on the 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 a command on the video filter side (on the 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 of decoding COMMAND (action command), 1 - in case of decoding SET_PARAM command, or -1 in case of errors.
decodeAndExecuteCommand method
The decodeAndExecuteCommand(…) method decodes and executes a command encoded by 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 2 - Action commands description.
| Command | Description |
|---|---|
| RESET | The RESET command is used to start detection of bad pixels. After the RESET command, the library will copy the next 60 video frames to the internal buffer. After 60 frames from the RESET command, the library will detect bad pixels and will write bad pixel coordinates into the config file (if the path to the config file was set in advance by the user). |
| ON | Enable bad pixel correction. |
| OFF | Disable bad pixel correction. |
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 3 - Params description.
| Parameter | Access | Description |
|---|---|---|
| MODE | read / write | Mode. Default: 0 - disable bad pixel correction, 1 - Enable bad pixel correction. |
| LEVEL | read / write | The pixel value difference between a bad pixel candidate and its neighbors. The pixel will be classified as a bad pixel if during 60 frames (from the RESET command, see VFilterCommand enum) the brightness value did not change by more than the LEVEL value. Default 40. Any pixel brightness value within [0:255] range. |
| PROCESSING_TIME_MCSEC | read only | Processing time in microseconds. Read only parameter. Used to check performance of BadPixelProcessor and shows processing time for last frame. |
| TYPE | read / write | Not supported by BadPixelProcessor library. |
| CUSTOM_1 | read / write | Low threshold value for bad pixel candidates. The pixel will be classified as a bad pixel candidate if the brightness value is less than the CUSTOM_1 parameter. Default 20. Any pixel brightness value within [0:255] range. |
| CUSTOM_2 | read / write | High threshold value for bad pixel candidates. The pixel will be classified as a bad pixel candidate if the brightness value is greater than the CUSTOM_2 parameter. Default 235. Any pixel brightness value within [0:255] range. |
| CUSTOM_3 | read / write | Image flip mode: 0 - none, 1 - horizontal, 2 - vertical, 3 - both. |
VFilterParams class description
VFilterParams class declaration
The VFilterParams class is used to provide a video filter parameters structure. Also, VFilterParams provides the possibility to write/read params from JSON files (JSON_READABLE macro) and provides methods to encode and decode params. The VFilterParams interface class is declared in the 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 5 - VFilterParams class fields description is related to VFilterParam enum description.
| Field | type | Description |
|---|---|---|
| mode | int | Mode. Default: 0 - disable bad pixel correction, 1 - Enable bad pixel correction. |
| level | float | The pixel value difference between a bad pixel candidate and its neighbors. The pixel will be classified as a bad pixel if during 60 frames (from the RESET command, see VFilterCommand enum) the brightness value did not change by more than the LEVEL value. Default 40. Any pixel brightness value within [0:255] range. |
| processingTimeMcSec | int | Processing time in microseconds. Read only parameter. Used to check performance of BadPixelProcessor and shows processing time for last frame. |
| type | int | Not supported by BadPixelProcessor library. |
| custom1 | float | Low threshold value for bad pixel candidates. The pixel will be classified as a bad pixel candidate if the brightness value is less than the CUSTOM_1 parameter. Default 20. Any pixel brightness value within [0:255] range. |
| custom2 | float | High threshold value for bad pixel candidates. The pixel will be classified as a bad pixel candidate if the brightness value is greater than the CUSTOM_2 parameter. Default 235. Any pixel brightness value within [0:255] range. |
| custom3 | float | Image flip mode: 0 - none, 1 - horizontal, 2 - vertical, 3 - both. |
Note: VFilterParams class fields listed in Table 5 have to reflect params set/get by methods setParam(…) and getParam(…).
Serialize VFilter params
The VFilterParams class provides the encode(…) method to serialize VFilter params. Serialization of VFilterParams is necessary when video filter parameters have to be sent via communication channels. The method provides options to exclude particular parameters from serialization. To do this, the method inserts a binary mask (1 byte) where each bit represents a particular parameter, and the 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 the VFilter.h file) determines flags for each field (parameter) declared in VFilterParams class. If the user wants to exclude any parameters from serialization, they can put a pointer to the mask. If the user wants to exclude a particular parameter from serialization, they 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::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
The VFilterParams class provides the decode(…) method to deserialize params. Deserialization of VFilterParams is necessary when it is needed to receive params via communication channels. The method automatically recognizes which parameters were serialized by the 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 the open-source ConfigReader library, which provides methods to read params from a JSON file and to write params to a JSON file. Example of writing and reading params to a 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 (used for example only). Example for Linux Ubuntu:
sudo apt install libopencv-dev
Typical commands to build BadPixelProcessor library:
cd BadPixelProcessor
mkdir build
cd build
cmake ..
make
If you want to connect BadPixelProcessor 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 and copy BadPixelProcessor repository folder there. New structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
BadPixelProcessor
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(BadPixelProcessor)
File 3rdparty/CMakeLists.txt adds folder BadPixelProcessor (by default, test applications and the example are excluded from compiling if BadPixelProcessor is included as a sub-repository). The new structure of your repository will be:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
BadPixelProcessor
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 BadPixelProcessor library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} BadPixelProcessor)
Done!
Example
A simple application shows how to use the BadPixelProcessor library. The application generates video frames and puts some bad pixels. The user can change the position of bad pixels and can run bad pixel detection again.
#include <opencv2/opencv.hpp>
#include "BadPixelProcessor.h"
int main(void)
{
// Prepare bad pixel processor filter parameters.
cr::video::VFilterParams filterParams;
filterParams.mode = 1; // Enable filter.
filterParams.level = 20.0f; // Set neighborhood difference threshold.
filterParams.custom1 = 20.0f; // Set low pixel threshold.
filterParams.custom2 = 235.0f; // Set high pixel threshold.
// Create bad pixel processor filter.
cr::video::BadPixelProcessor filter;
if (!filter.initVFilter(filterParams))
{
std::cout << "Error initializing BadPixelProcessor filter\n";
return -1;
}
// Set path to config file.
filter.setBadPixelsConfigFilePath("badPixelsConfig.json");
// Frame size.
const int width = 1280;
const int height = 1024;
// Create frame.
cr::video::Frame srcFrameYuv(width, height, cr::video::Fourcc::YUV24);
// Main loop.
uint8_t pixelValue = 0;
int frameCounter = 0;
int pixelsOffset = 20;
while (true)
{
// Fill frame by value.
memset(srcFrameYuv.data, 128, srcFrameYuv.size);
for (int i = 0; i < srcFrameYuv.size; i = i + 3)
srcFrameYuv.data[i] = pixelValue;
++pixelValue;
// Add two bad pixels: one black and one white.
srcFrameYuv.data[pixelsOffset * width * 3 + 50 * 3] = 0;
srcFrameYuv.data[pixelsOffset * 2 * width * 3 + 60 * 3] = 255;
srcFrameYuv.data[pixelsOffset * 3 * width * 3 + 70 * 3] = 0;
srcFrameYuv.data[pixelsOffset * 4 * width * 3 + 80 * 3] = 255;
srcFrameYuv.data[pixelsOffset * 5 * width * 3 + 90 * 3] = 0;
// Process frame.
filter.processFrame(srcFrameYuv);
// Get all filter parameters.
filter.getParams(filterParams);
// Convert to BGR.
cv::Mat imgYuv(height, width, CV_8UC3, srcFrameYuv.data);
cv::Mat imgBgr;
cv::cvtColor(imgYuv, imgBgr, cv::COLOR_YUV2BGR);
// Display frame.
cv::imshow("BadPixelProcessor Example", imgBgr);
switch (cv::waitKey(30))
{
case 27: // ESC key.
return 0;
case 32: // SPACE key.
// Start detection of bad pixels.
filter.executeCommand(cr::video::VFilterCommand::RESET);
break;
case 13: // ENTER key - enable / disable filter.
if (filterParams.mode == 1)
filter.setParam(cr::video::VFilterParam::MODE, 0);
else
filter.setParam(cr::video::VFilterParam::MODE, 1);
break;
case 102: // F key - Image flip mode change.
case 70: // f key
{
int currentFlipMode = (int)filter.getParam(cr::video::VFilterParam::CUSTOM_3);
currentFlipMode = (currentFlipMode + 1) % 4;
filter.setParam(cr::video::VFilterParam::CUSTOM_3, (float)currentFlipMode);
}
break;
case 114: // R key - increase pixels offset
case 82: // r key
{
pixelsOffset += 2;
break;
}
}
}
return 1;
}