BadPixelProcessor C++ lib. Detection and filtering bad pixels for MWIR, LWIR and SWIR thermal cameras

€400.00

BadPixelProcessor C++ library implements bad pixel detection algorithm. The library automatically detects bad pixels and remove them to provide clear image.

LICENSE: We sell source code of this library as is, without future updates and technical support according to perpetual non-exclusive royalty-free license. You pay once and can use this library in your software and hardware products without limits. Please read the license agreement before purchasing: LICENSE.

BadPixelProcessor C++ library implements bad pixel detection algorithm. The library automatically detects bad pixels and remove them to provide clear image.

LICENSE: We sell source code of this library as is, without future updates and technical support according to perpetual non-exclusive royalty-free license. You pay once and can use this library in your software and hardware products without limits. Please read the license agreement before purchasing: LICENSE.

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. 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.

Downloads

Documentation: GO TO DOCUMENTATION

Simple interface

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);
};

Simple example

#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;
}