forked from espressif/esp-idf
feat(isp_hist): change coeff and weight of HIST to integer/decimal struct
This commit is contained in:
@@ -15,14 +15,25 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
/*
|
||||||
isp_window_t window; /*!< The sampling window of histogram, see `isp_window_t`*/
|
* ISP Histogram Struct
|
||||||
isp_hist_sampling_mode_t hist_mode; /*!< ISP histogram sampling mode */
|
* |<----------------------------- INTERVAL_NUMS = 16 ------------------------------>|
|
||||||
isp_hist_rgb_coefficient rgb_coefficient; /*!< RGB coefficients, adjust the sensitivity to red, geen, and blue colors in the image,
|
* | | | | |
|
||||||
only effect when hist_mode is ISP_HIST_SAMPLING_RGB, the sum of all coefficients should be 100**/
|
* | Segment 0 | Segment 1 | ............ | Segment 15 |
|
||||||
uint32_t windows_weight[ISP_HIST_BLOCK_X_NUM][ISP_HIST_BLOCK_Y_NUM]; /*!< Weights of histogram's each subwindows, the sum of all subwindows's weight should be 100*/
|
* 0 threshold 0 threshold 1 ... threshold 14 255
|
||||||
uint32_t segment_threshold[ISP_HIST_INTERVAL_NUMS]; /*!< Threshold to segment the histogram into intervals, range 0~256 */
|
* |<------------------------------------------------------------------------------->|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Hist controller config
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
isp_window_t window; /*!< The sampling window of histogram, see `isp_window_t`*/
|
||||||
|
isp_hist_sampling_mode_t hist_mode; /*!< ISP histogram sampling mode */
|
||||||
|
isp_hist_rgb_coefficient_t rgb_coefficient; /*!< RGB coefficients, adjust the sensitivity to red, geen, and blue colors in the image,
|
||||||
|
only effect when hist_mode is ISP_HIST_SAMPLING_RGB, the sum of all coefficients decimal should be 256**/
|
||||||
|
isp_hist_weight_t window_weight[ISP_HIST_BLOCK_X_NUM * ISP_HIST_BLOCK_Y_NUM]; /*!< Weights of histogram's each subwindows, the sum of all subwindows's weight decimal should be 256*/
|
||||||
|
uint32_t segment_threshold[ISP_HIST_INTERVAL_NUMS]; /*!< Threshold to segment the histogram into intervals, range 0~255 */
|
||||||
} esp_isp_hist_config_t;
|
} esp_isp_hist_config_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -70,6 +70,34 @@ static void s_isp_hist_free_controller(isp_hist_ctlr_t hist_ctlr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t s_esp_isp_hist_config_hardware(isp_proc_handle_t isp_proc, const esp_isp_hist_config_t *hist_cfg)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < SOC_ISP_HIST_INTERVAL_NUMS; i++) {
|
||||||
|
ESP_RETURN_ON_FALSE((hist_cfg->segment_threshold[i] > 0 && hist_cfg->segment_threshold[i] < 256), ESP_ERR_INVALID_ARG, TAG, "invalid segment threshold");
|
||||||
|
}
|
||||||
|
ESP_RETURN_ON_FALSE(hist_cfg->rgb_coefficient.coeff_r.integer == 0 && hist_cfg->rgb_coefficient.coeff_g.integer == 0 && hist_cfg->rgb_coefficient.coeff_b.integer == 0, \
|
||||||
|
ESP_ERR_INVALID_ARG, TAG, "The rgb_coefficient's integer value is bigger than 0");
|
||||||
|
|
||||||
|
int weight_sum = 0;
|
||||||
|
for (int i = 0; i < SOC_ISP_HIST_BLOCK_X_NUMS * SOC_ISP_HIST_BLOCK_Y_NUMS; i++) {
|
||||||
|
ESP_RETURN_ON_FALSE(hist_cfg->window_weight[i].integer == 0, ESP_ERR_INVALID_ARG, TAG, "The subwindow weight's integer value is bigger than -");
|
||||||
|
weight_sum = weight_sum + hist_cfg->window_weight[i].decimal;
|
||||||
|
}
|
||||||
|
ESP_RETURN_ON_FALSE(weight_sum == 256, ESP_ERR_INVALID_ARG, TAG, "The sum of all subwindow weight's decimal value is not 256");
|
||||||
|
|
||||||
|
isp_ll_hist_set_mode(isp_proc->hal.hw, hist_cfg->hist_mode);
|
||||||
|
isp_hal_hist_window_config(&isp_proc->hal, &hist_cfg->window);
|
||||||
|
|
||||||
|
isp_ll_hist_set_subwindow_weight(isp_proc->hal.hw, hist_cfg->window_weight);
|
||||||
|
|
||||||
|
isp_ll_hist_set_segment_threshold(isp_proc->hal.hw, hist_cfg->segment_threshold);
|
||||||
|
if (hist_cfg->hist_mode == ISP_HIST_SAMPLING_RGB) {
|
||||||
|
isp_ll_hist_set_rgb_coefficient(isp_proc->hal.hw, &hist_cfg->rgb_coefficient);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t esp_isp_new_hist_controller(isp_proc_handle_t isp_proc, const esp_isp_hist_config_t *hist_cfg, isp_hist_ctlr_t *ret_hdl)
|
esp_err_t esp_isp_new_hist_controller(isp_proc_handle_t isp_proc, const esp_isp_hist_config_t *hist_cfg, isp_hist_ctlr_t *ret_hdl)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_FAIL;
|
esp_err_t ret = ESP_FAIL;
|
||||||
@@ -85,22 +113,8 @@ esp_err_t esp_isp_new_hist_controller(isp_proc_handle_t isp_proc, const esp_isp_
|
|||||||
hist_ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
hist_ctlr->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||||
hist_ctlr->isp_proc = isp_proc;
|
hist_ctlr->isp_proc = isp_proc;
|
||||||
|
|
||||||
for (int i = 0; i < SOC_ISP_HIST_INTERVAL_NUMS; i++) {
|
// Configure the hardware
|
||||||
ESP_GOTO_ON_FALSE((hist_cfg->segment_threshold[i] > 0 && hist_cfg->segment_threshold[i] < 256), ESP_ERR_INVALID_ARG, err1, TAG, "invalid segment threshold");
|
ESP_GOTO_ON_ERROR(s_esp_isp_hist_config_hardware(isp_proc, hist_cfg), err1, TAG, "configure HIST hardware failed");
|
||||||
}
|
|
||||||
|
|
||||||
int weight_sum = 0;
|
|
||||||
for (int i = 0; i < SOC_ISP_HIST_BLOCK_X_NUMS; i++) {
|
|
||||||
for (int j = 0; j < SOC_ISP_HIST_BLOCK_Y_NUMS; j++) {
|
|
||||||
weight_sum = weight_sum + hist_cfg->windows_weight[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ESP_GOTO_ON_FALSE(weight_sum == 100, ESP_ERR_INVALID_ARG, err1, TAG, "The sum of all subwindow's weight is not 100");
|
|
||||||
|
|
||||||
if (hist_cfg->hist_mode == ISP_HIST_SAMPLING_RGB) {
|
|
||||||
int rgb_coefficient_sum = hist_cfg->rgb_coefficient.coeff_r + hist_cfg->rgb_coefficient.coeff_g + hist_cfg->rgb_coefficient.coeff_b;
|
|
||||||
ESP_GOTO_ON_FALSE(rgb_coefficient_sum == 100, ESP_ERR_INVALID_ARG, err1, TAG, "The sum of rgb_coefficient is not 100");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Claim an hist controller
|
// Claim an hist controller
|
||||||
ESP_GOTO_ON_ERROR(s_isp_claim_hist_controller(isp_proc, hist_ctlr), err1, TAG, "no available controller");
|
ESP_GOTO_ON_ERROR(s_isp_claim_hist_controller(isp_proc, hist_ctlr), err1, TAG, "no available controller");
|
||||||
@@ -108,17 +122,6 @@ esp_err_t esp_isp_new_hist_controller(isp_proc_handle_t isp_proc, const esp_isp_
|
|||||||
// Register the HIGT ISR
|
// Register the HIGT ISR
|
||||||
ESP_GOTO_ON_ERROR(esp_isp_register_isr(hist_ctlr->isp_proc, ISP_SUBMODULE_HIST), err2, TAG, "fail to register ISR");
|
ESP_GOTO_ON_ERROR(esp_isp_register_isr(hist_ctlr->isp_proc, ISP_SUBMODULE_HIST), err2, TAG, "fail to register ISR");
|
||||||
|
|
||||||
// Configure the hardware
|
|
||||||
isp_ll_hist_set_mode(isp_proc->hal.hw, hist_cfg->hist_mode);
|
|
||||||
isp_hal_hist_window_config(&isp_proc->hal, &hist_cfg->window);
|
|
||||||
|
|
||||||
isp_ll_hist_set_subwindow_weight(isp_proc->hal.hw, hist_cfg->windows_weight);
|
|
||||||
|
|
||||||
isp_ll_hist_set_segment_threshold(isp_proc->hal.hw, hist_cfg->segment_threshold);
|
|
||||||
if (hist_cfg->hist_mode == ISP_HIST_SAMPLING_RGB) {
|
|
||||||
isp_ll_hist_set_rgb_coefficient(isp_proc->hal.hw, &hist_cfg->rgb_coefficient);
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret_hdl = hist_ctlr;
|
*ret_hdl = hist_ctlr;
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
@@ -191,7 +194,7 @@ esp_err_t esp_isp_hist_controller_get_oneshot_statistics(isp_hist_ctlr_t hist_ct
|
|||||||
// Start the histogram reference statistics and waiting it done
|
// Start the histogram reference statistics and waiting it done
|
||||||
isp_ll_hist_enable(hist_ctlr->isp_proc->hal.hw, true);
|
isp_ll_hist_enable(hist_ctlr->isp_proc->hal.hw, true);
|
||||||
// Wait the statistics to finish and receive the result from the queue
|
// Wait the statistics to finish and receive the result from the queue
|
||||||
if ((ticks > 0) && xQueueReceive(hist_ctlr->evt_que, out_res, ticks) != pdTRUE) {
|
if (xQueueReceive(hist_ctlr->evt_que, out_res, ticks) != pdTRUE) {
|
||||||
ret = ESP_ERR_TIMEOUT;
|
ret = ESP_ERR_TIMEOUT;
|
||||||
}
|
}
|
||||||
// Stop the histogram reference statistics
|
// Stop the histogram reference statistics
|
||||||
|
@@ -358,17 +358,33 @@ TEST_CASE("ISP HIST driver basic function", "[isp]")
|
|||||||
/* Test when sum of weight is not 256 */
|
/* Test when sum of weight is not 256 */
|
||||||
esp_isp_hist_config_t hist_config_error = {
|
esp_isp_hist_config_t hist_config_error = {
|
||||||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
||||||
.windows_weight = {{5, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}},
|
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
||||||
|
.rgb_coefficient.coeff_r = {{86, 0}},
|
||||||
|
.rgb_coefficient.coeff_g = {{85, 0}},
|
||||||
|
.rgb_coefficient.coeff_b = {{85, 0}},
|
||||||
|
.window_weight = {
|
||||||
|
{{15, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_isp_new_hist_controller(isp_proc, &hist_config_error, &hist_ctlr));
|
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, esp_isp_new_hist_controller(isp_proc, &hist_config_error, &hist_ctlr));
|
||||||
|
|
||||||
esp_isp_hist_config_t hist_config = {
|
esp_isp_hist_config_t hist_config = {
|
||||||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
||||||
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
||||||
.rgb_coefficient.coeff_r = 33,
|
.rgb_coefficient.coeff_r = {{86, 0}},
|
||||||
.rgb_coefficient.coeff_g = 33,
|
.rgb_coefficient.coeff_g = {{85, 0}},
|
||||||
.rgb_coefficient.coeff_b = 34,
|
.rgb_coefficient.coeff_b = {{85, 0}},
|
||||||
.windows_weight = {{4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}},
|
.window_weight = {
|
||||||
|
{{16, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(esp_isp_new_hist_controller(isp_proc, &hist_config, &hist_ctlr));
|
TEST_ESP_OK(esp_isp_new_hist_controller(isp_proc, &hist_config, &hist_ctlr));
|
||||||
|
|
||||||
@@ -408,10 +424,16 @@ TEST_CASE("ISP HIST controller exhausted allocation", "[isp]")
|
|||||||
esp_isp_hist_config_t hist_config = {
|
esp_isp_hist_config_t hist_config = {
|
||||||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
||||||
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
||||||
.rgb_coefficient.coeff_r = 33,
|
.rgb_coefficient.coeff_r = {{86, 0}},
|
||||||
.rgb_coefficient.coeff_g = 33,
|
.rgb_coefficient.coeff_g = {{85, 0}},
|
||||||
.rgb_coefficient.coeff_b = 34,
|
.rgb_coefficient.coeff_b = {{85, 0}},
|
||||||
.windows_weight = {{4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}},
|
.window_weight = {
|
||||||
|
{{16, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
isp_hist_ctlr_t hist_ctlr[SOC_ISP_HIST_CTLR_NUMS + 1] = {};
|
isp_hist_ctlr_t hist_ctlr[SOC_ISP_HIST_CTLR_NUMS + 1] = {};
|
||||||
|
@@ -1635,12 +1635,11 @@ static inline void isp_ll_hist_clk_enable(isp_dev_t *hw, bool enable)
|
|||||||
* @param[in] hw Hardware instance address
|
* @param[in] hw Hardware instance address
|
||||||
* @param[in] window_weight array for window weight
|
* @param[in] window_weight array for window weight
|
||||||
*/
|
*/
|
||||||
static inline void isp_ll_hist_set_subwindow_weight(isp_dev_t *hw, const uint32_t window_weight[SOC_ISP_HIST_BLOCK_X_NUMS][SOC_ISP_HIST_BLOCK_Y_NUMS])
|
static inline void isp_ll_hist_set_subwindow_weight(isp_dev_t *hw, const isp_hist_weight_t hist_window_weight[SOC_ISP_HIST_BLOCK_X_NUMS * SOC_ISP_HIST_BLOCK_Y_NUMS])
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SOC_ISP_HIST_BLOCK_X_NUMS; i++) {
|
for (int i = 0; i < SOC_ISP_HIST_BLOCK_X_NUMS * SOC_ISP_HIST_BLOCK_Y_NUMS; i++) {
|
||||||
for (int j = 0; j < SOC_ISP_HIST_BLOCK_Y_NUMS; j++) {
|
// On ESP32P4, hist_weight [7,0] are decimal
|
||||||
hw->hist_weight[i / 4].hist_weight_b[3 - (i % 4)] = (window_weight[i][j] * 256) / 100;
|
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_weight[i / 4], hist_weight_b[3 - (i % 4)], hist_window_weight[i].decimal);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1652,9 +1651,8 @@ static inline void isp_ll_hist_set_subwindow_weight(isp_dev_t *hw, const uint32_
|
|||||||
*/
|
*/
|
||||||
static inline void isp_ll_hist_set_segment_threshold(isp_dev_t *hw, const uint32_t segment_threshold[SOC_ISP_HIST_INTERVAL_NUMS])
|
static inline void isp_ll_hist_set_segment_threshold(isp_dev_t *hw, const uint32_t segment_threshold[SOC_ISP_HIST_INTERVAL_NUMS])
|
||||||
{
|
{
|
||||||
for (int i = 0; i < SOC_ISP_HIST_INTERVAL_NUMS; i++)
|
for (int i = 0; i < SOC_ISP_HIST_INTERVAL_NUMS; i++) {
|
||||||
{
|
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_seg[i / 4], hist_seg_b[3 - (i % 4)], segment_threshold[i]);
|
||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_seg[i / 4], hist_seg_b[3 - (i % 4)], segment_threshold[i])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1717,11 +1715,11 @@ static inline void isp_ll_hist_set_mode(isp_dev_t *hw, isp_hist_sampling_mode_t
|
|||||||
* @param[in] hw Hardware instance address
|
* @param[in] hw Hardware instance address
|
||||||
* @param[in] rgb_coeff RGB coefficients
|
* @param[in] rgb_coeff RGB coefficients
|
||||||
*/
|
*/
|
||||||
static inline void isp_ll_hist_set_rgb_coefficient(isp_dev_t *hw, const isp_hist_rgb_coefficient *rgb_coeff)
|
static inline void isp_ll_hist_set_rgb_coefficient(isp_dev_t *hw, const isp_hist_rgb_coefficient_t *rgb_coeff)
|
||||||
{
|
{
|
||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_coeff, hist_coeff_r, (rgb_coeff->coeff_r * 256) / 100);
|
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_coeff, hist_coeff_r, rgb_coeff->coeff_r.decimal);
|
||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_coeff, hist_coeff_g, (rgb_coeff->coeff_g * 256) / 100);
|
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_coeff, hist_coeff_g, rgb_coeff->coeff_g.decimal);
|
||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_coeff, hist_coeff_b, (rgb_coeff->coeff_b * 256) / 100);
|
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hist_coeff, hist_coeff_b, rgb_coeff->coeff_b.decimal);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@@ -23,6 +23,19 @@ typedef soc_periph_isp_clk_src_t isp_clk_src_t; ///< Clock source type of
|
|||||||
typedef int isp_clk_src_t; ///< Default type
|
typedef int isp_clk_src_t; ///< Default type
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
ISP window and subwindow
|
||||||
|
+----------------------------------------------------------+
|
||||||
|
| <-- top left point coordinate |
|
||||||
|
| | subwindow[0][0] |......| subwindow[0][Y_NUM]| |
|
||||||
|
| . |
|
||||||
|
| . |
|
||||||
|
| . |
|
||||||
|
| | subwindow[X_NUM][0] |......| subwindow[X_NUM][Y_NUM]| |
|
||||||
|
| bottom right point coordinate --> |
|
||||||
|
+----------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ISP coordinate type
|
* @brief ISP coordinate type
|
||||||
*
|
*
|
||||||
@@ -180,14 +193,13 @@ typedef enum {
|
|||||||
#define ISP_SHARPEN_M_FREQ_COEF_RES_BITS 16
|
#define ISP_SHARPEN_M_FREQ_COEF_RES_BITS 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief High freq pixel sharpeness coeff
|
* @brief High freq pixel sharpeness coeff
|
||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t decimal:ISP_SHARPEN_H_FREQ_COEF_DEC_BITS; ///< Integer part
|
uint32_t decimal:ISP_SHARPEN_H_FREQ_COEF_DEC_BITS; ///< Decimal part
|
||||||
uint32_t integer:ISP_SHARPEN_H_FREQ_COEF_INT_BITS; ///< Decimal part
|
uint32_t integer:ISP_SHARPEN_H_FREQ_COEF_INT_BITS; ///< Integer part
|
||||||
uint32_t reserved:ISP_SHARPEN_H_FREQ_COEF_RES_BITS; ///< Reserved
|
uint32_t reserved:ISP_SHARPEN_H_FREQ_COEF_RES_BITS; ///< Reserved
|
||||||
};
|
};
|
||||||
uint32_t val; ///< 32-bit high freq pixel sharpeness coeff register value
|
uint32_t val; ///< 32-bit high freq pixel sharpeness coeff register value
|
||||||
@@ -198,8 +210,8 @@ typedef union {
|
|||||||
*/
|
*/
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t decimal:ISP_SHARPEN_M_FREQ_COEF_DEC_BITS; ///< Integer part
|
uint32_t decimal:ISP_SHARPEN_M_FREQ_COEF_DEC_BITS; ///< Decimal part
|
||||||
uint32_t integer:ISP_SHARPEN_M_FREQ_COEF_INT_BITS; ///< Decimal part
|
uint32_t integer:ISP_SHARPEN_M_FREQ_COEF_INT_BITS; ///< Integer part
|
||||||
uint32_t reserved:ISP_SHARPEN_M_FREQ_COEF_RES_BITS; ///< Reserved
|
uint32_t reserved:ISP_SHARPEN_M_FREQ_COEF_RES_BITS; ///< Reserved
|
||||||
};
|
};
|
||||||
uint32_t val; ///< 32-bit medium freq pixel sharpeness coeff register value
|
uint32_t val; ///< 32-bit medium freq pixel sharpeness coeff register value
|
||||||
@@ -238,43 +250,74 @@ typedef struct {
|
|||||||
HIST
|
HIST
|
||||||
---------------------------------------------------------------*/
|
---------------------------------------------------------------*/
|
||||||
#if (SOC_ISP_HIST_BLOCK_X_NUMS && SOC_ISP_HIST_BLOCK_Y_NUMS)
|
#if (SOC_ISP_HIST_BLOCK_X_NUMS && SOC_ISP_HIST_BLOCK_Y_NUMS)
|
||||||
#define ISP_HIST_BLOCK_X_NUM SOC_ISP_HIST_BLOCK_X_NUMS // The AF window number for sampling
|
#define ISP_HIST_BLOCK_X_NUM SOC_ISP_HIST_BLOCK_X_NUMS // The AF window number for sampling
|
||||||
#define ISP_HIST_BLOCK_Y_NUM SOC_ISP_HIST_BLOCK_Y_NUMS // The AF window number for sampling
|
#define ISP_HIST_BLOCK_Y_NUM SOC_ISP_HIST_BLOCK_Y_NUMS // The AF window number for sampling
|
||||||
#else
|
#else
|
||||||
#define ISP_HIST_BLOCK_X_NUM 0
|
#define ISP_HIST_BLOCK_X_NUM 0
|
||||||
#define ISP_HIST_BLOCK_Y_NUM 0
|
#define ISP_HIST_BLOCK_Y_NUM 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (SOC_ISP_HIST_SEGMENT_NUMS && SOC_ISP_HIST_INTERVAL_NUMS)
|
#if (SOC_ISP_HIST_SEGMENT_NUMS && SOC_ISP_HIST_INTERVAL_NUMS)
|
||||||
#define ISP_HIST_SEGMENT_NUMS SOC_ISP_HIST_SEGMENT_NUMS // The segment of histogram
|
#define ISP_HIST_SEGMENT_NUMS SOC_ISP_HIST_SEGMENT_NUMS // The segment of histogram
|
||||||
#define ISP_HIST_INTERVAL_NUMS SOC_ISP_HIST_INTERVAL_NUMS // The interval of histogram
|
#define ISP_HIST_INTERVAL_NUMS SOC_ISP_HIST_INTERVAL_NUMS // The interval of histogram
|
||||||
#else
|
#else
|
||||||
#define ISP_HIST_SEGMENT_NUMS 0
|
#define ISP_HIST_SEGMENT_NUMS 0
|
||||||
#define ISP_HIST_INTERVAL_NUMS 0
|
#define ISP_HIST_INTERVAL_NUMS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ISP_HIST_WEIGHT_INT_BITS 8
|
||||||
|
#define ISP_HIST_WEIGHT_DEC_BITS 7
|
||||||
|
#define ISP_HIST_WEIGHT_RES_BITS 17
|
||||||
|
#define ISP_HIST_COEFF_INT_BITS 8
|
||||||
|
#define ISP_HIST_COEFF_DEC_BITS 7
|
||||||
|
#define ISP_HIST_COEFF_RES_BITS 17
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ISP histogram mode.
|
* @brief ISP histogram mode.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ISP_HIST_SAMPLING_RAW_RGB_B, ///< histogram mode for B component of raw image
|
ISP_HIST_SAMPLING_RAW_B, ///< histogram mode for B component of raw image
|
||||||
ISP_HIST_SAMPLING_RAW_RGB_GB, ///< histogram mode for GB component of raw image
|
ISP_HIST_SAMPLING_RAW_GB, ///< histogram mode for GB component of raw image
|
||||||
ISP_HIST_SAMPLING_RAW_RGB_GR, ///< histogram mode for GR component of raw image
|
ISP_HIST_SAMPLING_RAW_GR, ///< histogram mode for GR component of raw image
|
||||||
ISP_HIST_SAMPLING_RAW_RGB_R, ///< histogram mode for R component of raw image
|
ISP_HIST_SAMPLING_RAW_R, ///< histogram mode for R component of raw image
|
||||||
ISP_HIST_SAMPLING_RGB, ///< histogram mode for RGB
|
ISP_HIST_SAMPLING_RGB, ///< histogram mode for RGB
|
||||||
ISP_HIST_SAMPLING_YUV_Y, ///< histogram mode for Y component for YUV
|
ISP_HIST_SAMPLING_YUV_Y, ///< histogram mode for Y component for YUV
|
||||||
ISP_HIST_SAMPLING_YUV_U, ///< histogram mode for U component for YUV
|
ISP_HIST_SAMPLING_YUV_U, ///< histogram mode for U component for YUV
|
||||||
ISP_HIST_SAMPLING_YUV_V, ///< histogram mode for V component for YUV
|
ISP_HIST_SAMPLING_YUV_V, ///< histogram mode for V component for YUV
|
||||||
} isp_hist_sampling_mode_t;
|
} isp_hist_sampling_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISP histogram weight value
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint32_t decimal:ISP_HIST_WEIGHT_DEC_BITS; ///< Decimal part
|
||||||
|
uint32_t integer:ISP_HIST_WEIGHT_INT_BITS; ///< Integer part
|
||||||
|
uint32_t reserved:ISP_HIST_WEIGHT_RES_BITS; ///< Reserved
|
||||||
|
};
|
||||||
|
uint32_t val; ///< 32-bit histogram weight value
|
||||||
|
} isp_hist_weight_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ISP histogram coefficient value
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
uint32_t decimal:ISP_HIST_COEFF_DEC_BITS; ///< Decimal part
|
||||||
|
uint32_t integer:ISP_HIST_COEFF_INT_BITS; ///< Integer part
|
||||||
|
uint32_t reserved:ISP_HIST_COEFF_RES_BITS; ///< Reserved
|
||||||
|
};
|
||||||
|
uint32_t val; ///< 32-bit histogram coefficient value
|
||||||
|
} isp_hist_coeff_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ISP histogram r,g,b coefficient
|
* @brief ISP histogram r,g,b coefficient
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t coeff_r; ///< R coefficient
|
isp_hist_coeff_t coeff_r; ///< R coefficient
|
||||||
uint8_t coeff_g; ///< G coefficient
|
isp_hist_coeff_t coeff_g; ///< G coefficient
|
||||||
uint8_t coeff_b; ///< B coefficient
|
isp_hist_coeff_t coeff_b; ///< B coefficient
|
||||||
} isp_hist_rgb_coefficient;
|
} isp_hist_rgb_coefficient_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief ISP histogram result.
|
* @brief ISP histogram result.
|
||||||
|
@@ -36,6 +36,7 @@ INPUT += \
|
|||||||
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_sharpen.h \
|
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_sharpen.h \
|
||||||
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_core.h \
|
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_core.h \
|
||||||
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_gamma.h \
|
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_gamma.h \
|
||||||
|
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_hist.h \
|
||||||
$(PROJECT_PATH)/components/esp_driver_jpeg/include/driver/jpeg_decode.h \
|
$(PROJECT_PATH)/components/esp_driver_jpeg/include/driver/jpeg_decode.h \
|
||||||
$(PROJECT_PATH)/components/esp_driver_jpeg/include/driver/jpeg_encode.h \
|
$(PROJECT_PATH)/components/esp_driver_jpeg/include/driver/jpeg_encode.h \
|
||||||
$(PROJECT_PATH)/components/esp_driver_ppa/include/driver/ppa.h \
|
$(PROJECT_PATH)/components/esp_driver_ppa/include/driver/ppa.h \
|
||||||
|
@@ -158,17 +158,38 @@ Install ISP histogram (HIST) Driver
|
|||||||
|
|
||||||
ISP histogram (HIST) driver requires the configuration that specified by :cpp:type:`esp_isp_hist_config_t`.
|
ISP histogram (HIST) driver requires the configuration that specified by :cpp:type:`esp_isp_hist_config_t`.
|
||||||
|
|
||||||
If the configurations in :cpp:type:`esp_isp_hist_config_t` is specified, users can call :cpp:func:`esp_isp_new_hist_controller` to allocate and initialize an ISP HISTG processor. This function will return an ISP HIST processor handle if it runs correctly. You can take following code as reference.
|
If the configurations in :cpp:type:`esp_isp_hist_config_t` is specified, users can call :cpp:func:`esp_isp_new_hist_controller` to allocate and initialize an ISP Histogram processor. This function will return an ISP HIST processor handle if it runs correctly. You can take following code as reference.
|
||||||
|
|
||||||
|
.. list::
|
||||||
|
|
||||||
|
- The sum of all subwindows weight's decimal value should be 256 or the statistics will be small, and integer value should be 0.
|
||||||
|
- The sum of all RGB coefficients' decimal value should be 256 or the statistics will be small, and integer value should be 0.
|
||||||
|
- The segment_threshold must be 0 ~ 255 and in order
|
||||||
|
|
||||||
.. code:: c
|
.. code:: c
|
||||||
|
|
||||||
esp_isp_hist_config_t hist_cfg = {
|
esp_isp_hist_config_t hist_cfg = {
|
||||||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
||||||
.rgb_coefficient.coeff_r = 33,
|
|
||||||
.rgb_coefficient.coeff_g = 33,
|
|
||||||
.rgb_coefficient.coeff_b = 34,
|
|
||||||
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
||||||
.windows_weight = {{4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}},
|
.rgb_coefficient.coeff_r = {
|
||||||
|
.integer = 0,
|
||||||
|
.decimal = 86,
|
||||||
|
},
|
||||||
|
.rgb_coefficient.coeff_g = {
|
||||||
|
.integer = 0,
|
||||||
|
.decimal = 85,
|
||||||
|
},
|
||||||
|
.rgb_coefficient.coeff_b = {
|
||||||
|
.integer = 0,
|
||||||
|
.decimal = 85,
|
||||||
|
},
|
||||||
|
.window_weight = {
|
||||||
|
{{16, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
{{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}}, {{10, 0}},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
isp_hist_ctlr_t hist_ctlr_ctlr = NULL;
|
isp_hist_ctlr_t hist_ctlr_ctlr = NULL;
|
||||||
ESP_ERROR_CHECK(esp_isp_new_hist_controller(isp_proc, &hist_config, &hist_ctlr));
|
ESP_ERROR_CHECK(esp_isp_new_hist_controller(isp_proc, &hist_config, &hist_ctlr));
|
||||||
@@ -444,8 +465,6 @@ Aside from the above oneshot API, the ISP histogram driver also provides a way t
|
|||||||
|
|
||||||
Note that if you want to use the continuous statistics, you need to register the :cpp:member:`esp_isp_hist_cbs_t::on_statistics_done` callback to get the statistics result. See how to register it in `Register Event Callbacks <#isp-callback>`__
|
Note that if you want to use the continuous statistics, you need to register the :cpp:member:`esp_isp_hist_cbs_t::on_statistics_done` callback to get the statistics result. See how to register it in `Register Event Callbacks <#isp-callback>`__
|
||||||
|
|
||||||
Note that the sum of all subwindows's weight should be 100, the sum of all RGB coefficients should be 100, and segment_threshold must be 0 ~ 256.
|
|
||||||
|
|
||||||
.. code:: c
|
.. code:: c
|
||||||
|
|
||||||
static bool s_hist_scheme_on_statistics_done_callback(isp_hist_ctlr_t awb_ctrlr, const esp_isp_hist_evt_data_t *edata, void *user_data)
|
static bool s_hist_scheme_on_statistics_done_callback(isp_hist_ctlr_t awb_ctrlr, const esp_isp_hist_evt_data_t *edata, void *user_data)
|
||||||
@@ -456,17 +475,6 @@ Note that the sum of all subwindows's weight should be 100, the sum of all RGB c
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
isp_hist_ctlr_t hist_ctlr = NULL;
|
|
||||||
esp_isp_hist_config_t hist_cfg = {
|
|
||||||
.segment_threshold = {16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240},
|
|
||||||
.rgb_coefficient.coeff_r = 33,
|
|
||||||
.rgb_coefficient.coeff_g = 33,
|
|
||||||
.rgb_coefficient.coeff_b = 34,
|
|
||||||
.hist_mode = ISP_HIST_SAMPLING_RGB,
|
|
||||||
.windows_weight = {{4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4}},
|
|
||||||
};
|
|
||||||
|
|
||||||
esp_isp_new_hist_controller(isp_proc, &hist_cfg, &hist_ctlr);
|
|
||||||
esp_isp_hist_cbs_t hist_cbs = {
|
esp_isp_hist_cbs_t hist_cbs = {
|
||||||
.on_statistics_done = s_hist_scheme_on_statistics_done_callback,
|
.on_statistics_done = s_hist_scheme_on_statistics_done_callback,
|
||||||
};
|
};
|
||||||
@@ -715,3 +723,4 @@ API Reference
|
|||||||
.. include-build-file:: inc/isp_ccm.inc
|
.. include-build-file:: inc/isp_ccm.inc
|
||||||
.. include-build-file:: inc/isp_sharpen.inc
|
.. include-build-file:: inc/isp_sharpen.inc
|
||||||
.. include-build-file:: inc/isp_gamma.inc
|
.. include-build-file:: inc/isp_gamma.inc
|
||||||
|
.. include-build-file:: inc/isp_hist.inc
|
||||||
|
Reference in New Issue
Block a user