mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 10:40:47 +03:00
feat(isp): support ISP DPC, add tests and use it in multi pipeline example
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "driver/isp_ccm.h"
|
||||
#include "driver/isp_color.h"
|
||||
#include "driver/isp_demosaic.h"
|
||||
#include "driver/isp_dpc.h"
|
||||
#include "driver/isp_gamma.h"
|
||||
#include "driver/isp_hist.h"
|
||||
#include "driver/isp_lsc.h"
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/isp_types.h"
|
||||
#include "driver/isp_dpc_dynamic.h"
|
||||
#include "driver/isp_dpc_static.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------
|
||||
DPC (Dead Pixel Correction)
|
||||
---------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief ISP DPC common configuration
|
||||
*
|
||||
* This configuration controls common DPC behavior only. Configure static LUT
|
||||
* coordinates with esp_isp_dpc_static_configure() and dynamic algorithm
|
||||
* parameters with esp_isp_dpc_dynamic_configure().
|
||||
*/
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t update_once_configured : 1; ///< If set, apply configuration to hardware immediately; otherwise defer to frame boundary
|
||||
} flags; ///< Driver behavior flags
|
||||
} esp_isp_dpc_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configure common ISP DPC settings
|
||||
*
|
||||
* @note Call this while DPC is disabled, after configuring any required static
|
||||
* and dynamic correction paths, and before esp_isp_dpc_enable(). This API
|
||||
* configures the common clock and shadow-register update behavior; it does
|
||||
* not configure or enable static or dynamic correction.
|
||||
*
|
||||
* @param[in] isp_proc Processor handle
|
||||
* @param[in] config DPC common configuration
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_STATE DPC is enabled
|
||||
* - ESP_ERR_INVALID_ARG Invalid argument
|
||||
*/
|
||||
esp_err_t esp_isp_dpc_configure(isp_proc_handle_t isp_proc, const esp_isp_dpc_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Enable ISP DPC function
|
||||
*
|
||||
* @note Call `esp_isp_dpc_static_configure` and/or `esp_isp_dpc_dynamic_configure`,
|
||||
* then `esp_isp_dpc_configure`, first. Static and dynamic correction can be
|
||||
* configured together.
|
||||
* Static calibration is a separate flow started by
|
||||
* `esp_isp_dpc_static_calibration_start_once`; that API enables DPC internally.
|
||||
*
|
||||
* @param[in] isp_proc Processor handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_dpc_enable(isp_proc_handle_t isp_proc);
|
||||
|
||||
/**
|
||||
* @brief Disable ISP DPC function
|
||||
*
|
||||
* @param[in] isp_proc Processor handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid.
|
||||
* - ESP_ERR_INVALID_STATE Driver state is invalid.
|
||||
*/
|
||||
esp_err_t esp_isp_dpc_disable(isp_proc_handle_t isp_proc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/isp_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ISP DPC dynamic correction method
|
||||
*
|
||||
* Method 1 uses absolute thresholds around the minimum and maximum of the
|
||||
* eight neighboring pixels. Method 2 uses ratios and a second adaptive test
|
||||
* against the neighboring-pixel estimate.
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_ISP_DPC_DYNAMIC_METHOD_1 = 0, ///< Detects a pixel outside [min8 - low_threshold, max8 + high_threshold]
|
||||
ESP_ISP_DPC_DYNAMIC_METHOD_2 = 1, ///< Applies ratio screening followed by an estimate-based adaptive threshold test
|
||||
} esp_isp_dpc_dynamic_method_t;
|
||||
|
||||
/**
|
||||
* @brief ISP DPC dynamic correction configurations
|
||||
*
|
||||
* @note Both methods examine the eight same-color neighboring pixels and replace a
|
||||
* detected dead pixel with their median value. Method 1 directly compares the center
|
||||
* pixel with the neighboring minimum and maximum using absolute thresholds. Method 2
|
||||
* first keeps pixels within a max8-based ratio range. For pixels outside that range,
|
||||
* it compares the center pixel with the neighboring-pixel estimate using adaptive
|
||||
* bright and dark thresholds.
|
||||
*/
|
||||
typedef struct {
|
||||
esp_isp_dpc_dynamic_method_t method; ///< Dynamic correction method
|
||||
union {
|
||||
struct {
|
||||
uint8_t high_threshold; ///< A pixel above max8 + high_threshold is a bright dead-pixel candidate (0-255)
|
||||
uint8_t low_threshold; ///< A pixel below min8 - low_threshold is a dark dead-pixel candidate (0-255)
|
||||
} method_1;
|
||||
struct {
|
||||
isp_dpc_ratio_t first_stage_upper_ratio; /*!< Upper bound of the first-stage normal-pixel range.
|
||||
* Value = integer + decimal / ISP_DPC_RATIO_MAX. Range 0 ~ 1.
|
||||
* Fractional values use integer 0 and decimal 0 ~ (ISP_DPC_RATIO_MAX - 1);
|
||||
* 1.0 uses integer 1 and decimal 0. Must be greater than first_stage_lower_ratio.
|
||||
*/
|
||||
isp_dpc_ratio_t first_stage_lower_ratio; /*!< Lower bound of the first-stage normal-pixel range.
|
||||
* Value = integer + decimal / ISP_DPC_RATIO_MAX. Range 0 ~ 1.
|
||||
* Fractional values use integer 0 and decimal 0 ~ (ISP_DPC_RATIO_MAX - 1);
|
||||
* 1.0 uses integer 1 and decimal 0.
|
||||
*/
|
||||
isp_dpc_deviation_factor_t bright_deviation_factor; /*!< Second-stage bright-pixel sensitivity.
|
||||
* Value = integer + decimal / ISP_DPC_DEVIATION_FACTOR_MAX. Range 0 ~ 1.
|
||||
* Fractional values use integer 0 and decimal 0 ~ (ISP_DPC_DEVIATION_FACTOR_MAX - 1);
|
||||
* 1.0 uses integer 1 and decimal 0. A smaller value corrects bright pixels more aggressively.
|
||||
*/
|
||||
isp_dpc_deviation_factor_t dark_deviation_factor; /*!< Second-stage dark-pixel sensitivity.
|
||||
* Value = integer + decimal / ISP_DPC_DEVIATION_FACTOR_MAX. Range 0 ~ 1.
|
||||
* Fractional values use integer 0 and decimal 0 ~ (ISP_DPC_DEVIATION_FACTOR_MAX - 1);
|
||||
* 1.0 uses integer 1 and decimal 0. A smaller value corrects dark pixels more aggressively.
|
||||
*/
|
||||
} method_2;
|
||||
};
|
||||
} esp_isp_dpc_dynamic_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configure dynamic DPC correction
|
||||
*
|
||||
* @note Call this while DPC is disabled. This function enables dynamic correction but
|
||||
* does not enable the DPC module; call esp_isp_dpc_configure() and then
|
||||
* esp_isp_dpc_enable() afterwards. Static and dynamic correction can be
|
||||
* configured together.
|
||||
*
|
||||
* @param[in] isp_proc Processor handle
|
||||
* @param[in] config Dynamic correction configuration
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG Invalid argument or dynamic parameters
|
||||
* - ESP_ERR_INVALID_STATE DPC is enabled
|
||||
* - ESP_ERR_NOT_SUPPORTED Not supported
|
||||
*/
|
||||
esp_err_t esp_isp_dpc_dynamic_configure(isp_proc_handle_t isp_proc, const esp_isp_dpc_dynamic_config_t *config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/isp_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_ISP_DPC_MAX_DEAD_PIXELS 512 ///< Maximum number of dead pixels supported by the static DPC LUT
|
||||
|
||||
/**
|
||||
* @brief DPC pixel coordinate
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t x; ///< Horizontal coordinate
|
||||
uint16_t y; ///< Vertical coordinate
|
||||
} esp_isp_dpc_pixel_coord_t;
|
||||
|
||||
/**
|
||||
* @brief ISP DPC static correction configurations
|
||||
*/
|
||||
typedef struct {
|
||||
const esp_isp_dpc_pixel_coord_t *dead_pixel_coords; ///< Unique coordinates in ascending y/x order. Coordinates must be inside the input frame. The driver reads this array only during esp_isp_dpc_static_configure().
|
||||
uint32_t dead_pixel_count; ///< Number of dead pixels in the array (0 to ESP_ISP_DPC_MAX_DEAD_PIXELS)
|
||||
} esp_isp_dpc_static_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configure static DPC correction
|
||||
*
|
||||
* @note Call this while DPC is disabled. This function writes the coordinates to the
|
||||
* hardware LUT and enables static correction. It does not enable the DPC module;
|
||||
* call esp_isp_dpc_configure() and then esp_isp_dpc_enable() afterwards. The
|
||||
* driver reads dead_pixel_coords only during this call and does not retain the
|
||||
* array after it returns.
|
||||
*
|
||||
* @param[in] isp_proc Processor handle
|
||||
* @param[in] config Static correction configuration
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_STATE DPC is enabled
|
||||
* - ESP_ERR_INVALID_ARG Invalid argument or coordinates
|
||||
* - ESP_ERR_NOT_SUPPORTED Not supported
|
||||
*/
|
||||
esp_err_t esp_isp_dpc_static_configure(isp_proc_handle_t isp_proc, const esp_isp_dpc_static_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief ISP DPC static calibration configuration
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t threshold; ///< Dead-pixel threshold. For a white image, lower pixels are considered dead pixels; for a black image, higher pixels are considered dead pixels
|
||||
bool enable_output; ///< Whether to output the calibration frame. When false, DPC records detected coordinates without outputting image data.
|
||||
} esp_isp_dpc_calibration_config_t;
|
||||
|
||||
/**
|
||||
* @brief DPC calibration image type
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_ISP_DPC_CALIBRATION_IMAGE_WHITE, ///< Uniform white frame, used to detect dark dead pixels
|
||||
ESP_ISP_DPC_CALIBRATION_IMAGE_BLACK, ///< Uniform black frame, used to detect bright dead pixels
|
||||
} esp_isp_dpc_calibration_image_t;
|
||||
|
||||
/**
|
||||
* @brief ISP DPC calibration coordinate reference
|
||||
*/
|
||||
typedef struct {
|
||||
esp_isp_dpc_pixel_coord_t dead_pixel_coords[ESP_ISP_DPC_MAX_DEAD_PIXELS]; ///< Dead pixel coordinates
|
||||
uint32_t dead_pixel_count; ///< Number of valid coordinates in dead_pixel_coords
|
||||
} esp_isp_dpc_calibration_ref_t;
|
||||
|
||||
/**
|
||||
* @brief Start DPC static calibration onetime
|
||||
*
|
||||
* @note After calling this function, input a uniform frame matching image_type,
|
||||
* then call esp_isp_dpc_calibration_read_result to wait for completion and
|
||||
* read the results.
|
||||
* Static correction is enabled and dynamic correction is disabled while
|
||||
* calibration check mode is enabled.
|
||||
* DPC must not be enabled before calling this function.
|
||||
*
|
||||
* @param[in] isp_proc Processor handle
|
||||
* @param[in] image_type Calibration image type
|
||||
* @param[in] config Calibration configuration
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_STATE Not allowed to be called under current state
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
||||
* - ESP_ERR_NOT_SUPPORTED Not supported
|
||||
*/
|
||||
esp_err_t esp_isp_dpc_static_calibration_start_once(isp_proc_handle_t isp_proc,
|
||||
esp_isp_dpc_calibration_image_t image_type,
|
||||
const esp_isp_dpc_calibration_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Read DPC static calibration results
|
||||
*
|
||||
* @note This function waits for calibration completion, then disables check mode and
|
||||
* DPC before reading the LUT. The result storage is supplied by the caller.
|
||||
*
|
||||
* @param[in] isp_proc Processor handle
|
||||
* @param[in] timeout_ms Maximum wait time in milliseconds; zero polls once
|
||||
* @param[out] result Calibration coordinate reference
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
||||
* - ESP_ERR_INVALID_STATE Calibration is not running
|
||||
* - ESP_ERR_TIMEOUT Calibration did not complete within the timeout
|
||||
*/
|
||||
esp_err_t esp_isp_dpc_calibration_read_result(isp_proc_handle_t isp_proc, uint32_t timeout_ms,
|
||||
esp_isp_dpc_calibration_ref_t *result);
|
||||
|
||||
/**
|
||||
* @brief Merge static calibration coordinate references
|
||||
*
|
||||
* @note This is a software-only utility. It does not access an ISP processor or any
|
||||
* hardware resource. It combines the coordinates from ref_count references, sorts
|
||||
* them by y/x, removes duplicates, and keeps at most ESP_ISP_DPC_MAX_DEAD_PIXELS
|
||||
* coordinates. The output reference must not also appear in refs.
|
||||
*
|
||||
* @param[in] refs Array of pointers to the coordinate references to merge
|
||||
* @param[in] ref_count Number of entries in refs, must be greater than zero
|
||||
* @param[out] merged_ref Merged coordinate reference
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG If the combination of arguments is invalid
|
||||
*/
|
||||
esp_err_t esp_isp_dpc_calibration_merge_result(const esp_isp_dpc_calibration_ref_t *const refs[],
|
||||
size_t ref_count,
|
||||
esp_isp_dpc_calibration_ref_t *merged_ref);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -97,6 +97,7 @@ typedef struct isp_processor_t {
|
||||
ISP_ATOMIC_TYPE(isp_fsm_t) lsc_fsm;
|
||||
ISP_ATOMIC_TYPE(isp_fsm_t) sharpen_fsm;
|
||||
ISP_ATOMIC_TYPE(isp_fsm_t) wbg_fsm;
|
||||
ISP_ATOMIC_TYPE(isp_fsm_t) dpc_fsm;
|
||||
esp_isp_evt_cbs_t cbs;
|
||||
void *user_data;
|
||||
|
||||
@@ -114,6 +115,7 @@ typedef struct isp_processor_t {
|
||||
|
||||
struct {
|
||||
uint32_t wbg_update_once_configured: 1;
|
||||
uint32_t dpc_update_once_configured: 1;
|
||||
} sub_module_flags;
|
||||
|
||||
} isp_processor_t;
|
||||
|
||||
Reference in New Issue
Block a user