mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'feat/isp_dpc_support_v6.0' into 'release/v6.0'
feat(isp): support isp dpc dead pixel correction (v6.0) See merge request espressif/esp-idf!51470
This commit is contained in:
@@ -12,6 +12,7 @@ This example demonstrates how to use the ISP (image signal processor) to work wi
|
||||
- ISP AF (auto-focus) feature
|
||||
- ISP BF (bayer denoise) feature
|
||||
- ISP BLC (black level correction) feature
|
||||
- ISP DPC (dead pixel correction) feature
|
||||
- ISP Sharpen feature
|
||||
- ISP Demosaic feature
|
||||
- ISP GAMMA feature
|
||||
|
||||
@@ -2,7 +2,8 @@ set(srcs "isp_dsi_main.c"
|
||||
"example_buffer.c"
|
||||
"example_af.c"
|
||||
"example_awb.c"
|
||||
"example_pipelines.c")
|
||||
"example_pipelines.c"
|
||||
"example_dpc.c")
|
||||
|
||||
if(CONFIG_EXAMPLE_ISP_CROP_ENABLE)
|
||||
list(APPEND srcs "example_crop.c")
|
||||
|
||||
@@ -53,6 +53,24 @@ menu "Example Configuration"
|
||||
Enable ISP crop functionality. When enabled, you can configure
|
||||
the crop area for the ISP pipeline.
|
||||
|
||||
config EXAMPLE_ISP_ENABLE_DPC
|
||||
depends on (ESP32P4_REV_MIN_FULL >= 300)
|
||||
bool "Enable ISP dead pixel correction"
|
||||
default y
|
||||
help
|
||||
Enable the ISP Dead Pixel Correction (DPC) example. This feature
|
||||
requires ESP32-P4 revision v3.0 or later.
|
||||
|
||||
config EXAMPLE_ISP_DPC_STATIC_CALIBRATION
|
||||
depends on EXAMPLE_ISP_ENABLE_DPC
|
||||
bool "Enable ISP DPC static calibration"
|
||||
default n
|
||||
help
|
||||
Enable static DPC calibration using camera input. At startup, the
|
||||
example prompts the user to provide uniform white and black images,
|
||||
then press Enter after each image is ready.
|
||||
Dynamic DPC remains enabled regardless of this option.
|
||||
|
||||
menu "ISP Crop Configuration"
|
||||
visible if EXAMPLE_ISP_CROP_ENABLE
|
||||
|
||||
|
||||
130
examples/peripherals/isp/multi_pipelines/main/example_dpc.c
Normal file
130
examples/peripherals/isp/multi_pipelines/main/example_dpc.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "driver/isp_dpc.h"
|
||||
#include "example_dpc.h"
|
||||
|
||||
static const char *TAG = "isp_dpc";
|
||||
|
||||
#define EXAMPLE_DPC_WHITE_THRESHOLD 0xf0
|
||||
#define EXAMPLE_DPC_BLACK_THRESHOLD 0x0a
|
||||
#define EXAMPLE_DPC_CALIBRATION_TIMEOUT_MS 5000
|
||||
|
||||
static esp_isp_dpc_calibration_ref_t s_white_calibration_ref;
|
||||
static esp_isp_dpc_calibration_ref_t s_black_calibration_ref;
|
||||
|
||||
/* Wait for the user to prepare the requested calibration image. */
|
||||
static void s_example_dpc_wait_for_calibration_image(const char *image_name)
|
||||
{
|
||||
ESP_LOGI(TAG, "Present a uniform %s image to the camera, then press Enter", image_name);
|
||||
int c;
|
||||
do {
|
||||
c = getchar();
|
||||
if (c == EOF) {
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
} while (c != '\n');
|
||||
}
|
||||
|
||||
/* Capture white and black calibration frames, then merge their bad-pixel lists. */
|
||||
esp_err_t example_isp_dpc_calibrate_static(isp_proc_handle_t isp_proc, esp_isp_dpc_calibration_ref_t *calibration_ref)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(isp_proc && calibration_ref, ESP_ERR_INVALID_ARG, TAG, "invalid arguments");
|
||||
|
||||
esp_isp_dpc_calibration_config_t calibration_config = {
|
||||
.enable_output = true,
|
||||
};
|
||||
|
||||
s_example_dpc_wait_for_calibration_image("white");
|
||||
calibration_config.threshold = EXAMPLE_DPC_WHITE_THRESHOLD;
|
||||
ESP_RETURN_ON_ERROR(esp_isp_dpc_static_calibration_start_once(isp_proc, ESP_ISP_DPC_CALIBRATION_IMAGE_WHITE, &calibration_config),
|
||||
TAG, "failed to start white-frame DPC calibration");
|
||||
ESP_RETURN_ON_ERROR(esp_isp_dpc_calibration_read_result(isp_proc, EXAMPLE_DPC_CALIBRATION_TIMEOUT_MS, &s_white_calibration_ref),
|
||||
TAG, "failed to read white-frame DPC calibration result");
|
||||
|
||||
s_example_dpc_wait_for_calibration_image("black");
|
||||
calibration_config.threshold = EXAMPLE_DPC_BLACK_THRESHOLD;
|
||||
ESP_RETURN_ON_ERROR(esp_isp_dpc_static_calibration_start_once(isp_proc, ESP_ISP_DPC_CALIBRATION_IMAGE_BLACK, &calibration_config),
|
||||
TAG, "failed to start black-frame DPC calibration");
|
||||
ESP_RETURN_ON_ERROR(esp_isp_dpc_calibration_read_result(isp_proc, EXAMPLE_DPC_CALIBRATION_TIMEOUT_MS, &s_black_calibration_ref),
|
||||
TAG, "failed to read black-frame DPC calibration result");
|
||||
|
||||
const esp_isp_dpc_calibration_ref_t *refs[] = {
|
||||
&s_white_calibration_ref,
|
||||
&s_black_calibration_ref,
|
||||
};
|
||||
ESP_RETURN_ON_ERROR(esp_isp_dpc_calibration_merge_result(refs, sizeof(refs) / sizeof(refs[0]), calibration_ref),
|
||||
TAG, "failed to merge DPC calibration results");
|
||||
|
||||
ESP_LOGI(TAG, "DPC static calibration done, %" PRIu32 " dead pixels found", calibration_ref->dead_pixel_count);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Configure static correction when available, followed by dynamic correction. */
|
||||
esp_err_t example_isp_dpc_init(isp_proc_handle_t isp_proc, const esp_isp_dpc_calibration_ref_t *calibration_ref)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "Invalid arguments: isp_proc is NULL");
|
||||
|
||||
if (calibration_ref) {
|
||||
esp_isp_dpc_static_config_t static_config = {
|
||||
.dead_pixel_coords = calibration_ref->dead_pixel_coords,
|
||||
.dead_pixel_count = calibration_ref->dead_pixel_count,
|
||||
};
|
||||
esp_err_t ret = esp_isp_dpc_static_configure(isp_proc, &static_config);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to configure static DPC: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
ESP_LOGI(TAG, "DPC static correction configured");
|
||||
}
|
||||
|
||||
esp_isp_dpc_dynamic_config_t dpc_config = {
|
||||
.method = ESP_ISP_DPC_DYNAMIC_METHOD_1,
|
||||
.method_1 = {
|
||||
.high_threshold = 48,
|
||||
.low_threshold = 48,
|
||||
},
|
||||
};
|
||||
esp_err_t ret = esp_isp_dpc_dynamic_configure(isp_proc, &dpc_config);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to configure DPC: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_isp_dpc_config_t common_config = {
|
||||
.flags.update_once_configured = true,
|
||||
};
|
||||
ret = esp_isp_dpc_configure(isp_proc, &common_config);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to configure common DPC settings: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "DPC module initialized");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Enable the configured DPC module. */
|
||||
esp_err_t example_isp_dpc_enable(isp_proc_handle_t isp_proc)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE(isp_proc, ESP_ERR_INVALID_ARG, TAG, "Invalid arguments: isp_proc is NULL");
|
||||
|
||||
esp_err_t ret = esp_isp_dpc_enable(isp_proc);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to enable DPC: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "DPC module enabled");
|
||||
return ESP_OK;
|
||||
}
|
||||
65
examples/peripherals/isp/multi_pipelines/main/example_dpc.h
Normal file
65
examples/peripherals/isp/multi_pipelines/main/example_dpc.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file example_dpc.h
|
||||
* @brief Dead Pixel Correction (DPC) Functionality
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "driver/isp.h"
|
||||
#include "driver/isp_dpc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize DPC module
|
||||
*
|
||||
* @param[in] isp_proc ISP processor handle
|
||||
* @param[in] calibration_ref Static calibration coordinate reference, or NULL to skip static correction
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
||||
* - ESP_ERR_INVALID_STATE: DPC is already enabled
|
||||
* - ESP_ERR_NOT_SUPPORTED: Not supported on this chip revision
|
||||
*/
|
||||
esp_err_t example_isp_dpc_init(isp_proc_handle_t isp_proc, const esp_isp_dpc_calibration_ref_t *calibration_ref);
|
||||
|
||||
/**
|
||||
* @brief Calibrate static DPC using the active CSI ISP processor
|
||||
*
|
||||
* The function prompts the user to present uniform white and black images to the
|
||||
* camera and press Enter after each image is ready, then captures one frame of
|
||||
* each to produce a merged calibration result.
|
||||
* DPC must be disabled before calling this function.
|
||||
*
|
||||
* @param[in] isp_proc ISP processor handle receiving CSI input
|
||||
* @param[out] calibration_ref Merged static calibration coordinate reference
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
||||
* - ESP_ERR_TIMEOUT: Calibration frame was not received in time
|
||||
*/
|
||||
esp_err_t example_isp_dpc_calibrate_static(isp_proc_handle_t isp_proc, esp_isp_dpc_calibration_ref_t *calibration_ref);
|
||||
|
||||
/**
|
||||
* @brief Enable DPC module
|
||||
*
|
||||
* @param[in] isp_proc ISP processor handle
|
||||
* @return
|
||||
* - ESP_OK: Success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid arguments
|
||||
* - ESP_ERR_INVALID_STATE: Invalid state
|
||||
*/
|
||||
esp_err_t example_isp_dpc_enable(isp_proc_handle_t isp_proc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "example_af.h"
|
||||
#include "example_awb.h"
|
||||
#include "example_pipelines.h"
|
||||
#include "example_dpc.h"
|
||||
#ifdef CONFIG_EXAMPLE_ISP_CROP_ENABLE
|
||||
#include "example_crop.h"
|
||||
#endif
|
||||
@@ -266,6 +267,33 @@ void app_main(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_EXAMPLE_ISP_ENABLE_DPC
|
||||
const esp_isp_dpc_calibration_ref_t *dpc_calibration_ref = NULL;
|
||||
#if CONFIG_EXAMPLE_ISP_DPC_STATIC_CALIBRATION
|
||||
static esp_isp_dpc_calibration_ref_t static_dpc_calibration_ref;
|
||||
// The calibration function prompts the user to present uniform white and black images.
|
||||
ret = example_isp_dpc_calibrate_static(isp_proc, &static_dpc_calibration_ref);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "DPC static calibration fail[%d]", ret);
|
||||
return;
|
||||
}
|
||||
dpc_calibration_ref = &static_dpc_calibration_ref;
|
||||
#endif /* CONFIG_EXAMPLE_ISP_DPC_STATIC_CALIBRATION */
|
||||
|
||||
//---------------DPC Init and Enable------------------//
|
||||
ret = example_isp_dpc_init(isp_proc, dpc_calibration_ref);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "DPC init fail[%d]", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = example_isp_dpc_enable(isp_proc);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "DPC enable fail[%d]", ret);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_EXAMPLE_ISP_ENABLE_DPC */
|
||||
|
||||
example_dpi_panel_init(mipi_dpi_panel);
|
||||
|
||||
ESP_LOGI(TAG, "ISP DSI example started");
|
||||
|
||||
Reference in New Issue
Block a user