尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

多目直方图融合

多目直方图融合 目录一、需求目标二、核心检测原理1、通道异常判定公式2、帧间防抖去抖动机制3、业务分支开关逻辑4、直方图自适应权重分配 (Q8 定点256 代表 1.0)5、异常掩码输出三、完整模块划分四、测试案例验证五、产线参数标定参考10‑bit Raw 图像六、逻辑伪代码七、优化收益总结一、需求目标三路传感器 (A/B/C) 直方图融合用于 AE 曝光统计正常场景三路直方图 1:1:1 均等融合提升直方图信噪比可使用融合后直方图计算全局亮度三路亮度可以融合。异常场景只要任意一路传感器亮度与另外两路差异过大如镜头盖遮挡三路平均亮度必须独立计算禁止亮度融合直方图仅使用有效通道加权融合剔除失效通道数据。全部定点整数运算无浮点运算适配嵌入式 ISP 平台。核心旧方案缺陷修正 原先以三路亮度平均值(yAyByC)/3作为偏差基准。当一路遮挡异常亮度会污染参考均值导致正常两目被误判为异常。 ✅优化判定方式判断某通道是否异常时参考基准取另外两目的亮度平均值待测通道本身数据不会干扰基准离群检测精准可靠。二、核心检测原理1、通道异常判定公式判断 A 是否异常判断 B 是否异常判断 C 是否异常判定条件如果当前通道直方图总像素 0 → 直接判定通道失效否则当原始帧标记该通道异常。2、帧间防抖去抖动机制单帧瞬时噪声、闪光容易造成亮度跳变引发异常状态误触发导致 AE 闪烁。 增加防抖计数器连续 N 帧检测到原始异常 → 防抖后判定通道稳定失效只要一帧恢复正常 → 计数器清零通道恢复有效。 防抖帧数建议2‑5 帧可动态配置。3、业务分支开关逻辑只要防抖后任意一路通道标记为异常失效bUseSeparateY true→三路亮度独立闭环计算不再做亮度融合。 三路全部正常bUseSeparateY false→ 可使用融合直方图做全局 AE 亮度统计。4、直方图自适应权重分配 (Q8 定点256 代表 1.0)有效通道数目权重分配3 路全部正常等价 (1/3)2 路有效、1 路异常有效两路权重 128 (0.5)失效通道权重 01 路有效、两路异常有效通道权重 256 (1.0)其余两路权重 0三路全部失效三路权重全部置 0直方图融合公式计算时使用uint64_t做中间累加防止像素计数溢出最后右移 8 位归一化。5、异常掩码输出输出abnormalMask调试标记位bit01 → A 通道异常bit11 → B 通道异常bit21 → C 通道异常 上层调试可直接读取快速定位哪一目被遮挡。三、完整模块划分表格子函数功能abs_diff_u16无符号 16 位数求差值绝对值ChannelIsAbnormal单通道离群检测以另外两目均值为参考基准空像素保护DebounceFilter帧间防抖滤波抑制瞬时误触发CalcFusionWeight根据通道有效状态计算 Q8 融合权重FuseHistogram定点加权直方图融合运算TriAeHistAdaptiveFusion主入口函数注意事项防抖状态结构体ChannelDebounce_t必须放在帧循环外层使用 static / 全局保存不可作为局部变量否则帧间计数丢失防抖失效。四、测试案例验证场景A 镜头被遮挡Y_A100Y_B800Y_C820Th_severe384 (10bit)→ A 原始异常→ B 正常→ C 正常 防抖连续 3 帧后稳定判定 A 失效abnormalMask BIT0 (A 异常)bUseSeparateY true → 三路亮度独立计算 AE直方图权重 wA0wB128wC128直方图仅融合 B、C 两路。五、产线参数标定参考10‑bit Raw 图像参数推荐值说明Th_severe384亮度偏差阈值超过判定严重遮挡 / 失效debounceFrameThresh2~5 帧防抖帧数越大抗干扰越强遮挡响应速度变慢BIN_NUM1024直方图 bin 数量根据硬件统计模块修改六、逻辑伪代码void AeFrameProcess(void) { /* 防抖状态必须全局/静态保存帧与帧之间不能丢失 */ static ChannelDebounce_t debounceState {0}; HistBin_t histA[BIN_NUM] {0}; HistBin_t histB[BIN_NUM] {0}; HistBin_t histC[BIN_NUM] {0}; TriYMean_t yMean {.yA 100, .yB 800, .yC 820}; TriHistPixelSum_t pixelSum {.sumA 0, .sumB120000, .sumC120000}; TriHistFusionOut_t fusionResult; /* 10bit示例阈值防抖连续3帧异常才判定遮挡 */ const uint16_t TH_SEVERE 384U; const uint8_t DEBOUNCE_FRAME 3U; TriAeHistAdaptiveFusion(histA,histB,histC,yMean,pixelSum, debounceState,TH_SEVERE,DEBOUNCE_FRAME, fusionResult); if(fusionResult.bUseSeparateY) { /* 任意一目异常三路AE亮度独立闭环禁止亮度融合 */ } else { /* 三路正常使用融合直方图统一计算全局亮度 */ } }具体逻辑实现#include stdint.h #include stdbool.h #include stdlib.h #define BIN_NUM 1024U #define Q8_SCALE 256U // 单目状态掩码定义 #define CH_MASK_A (1U 0U) #define CH_MASK_B (1U 1U) #define CH_MASK_C (1U 2U) // 三路平均亮度 typedef struct { uint16_t yA; uint16_t yB; uint16_t yC; }TriYMean_t; // 三路直方图总像素计数(用于空直方图检测) typedef struct { uint32_t sumA; uint32_t sumB; uint32_t sumC; }TriHistPixelSum_t; typedef uint32_t HistBin_t; // 融合输出结果 typedef struct { HistBin_t histOut[BIN_NUM]; uint8_t wA; /* Q8权重 [0,256] */ uint8_t wB; uint8_t wC; bool bUseSeparateY; /* true:亮度独立计算不融合 */ uint8_t abnormalMask; /* bit0:A异常 bit1:B异常 bit2:C异常 */ }TriHistFusionOut_t; /* 防抖状态结构体放在上层帧循环保存不要局部变量 */ typedef struct { uint8_t debounceCntA; uint8_t debounceCntB; uint8_t debounceCntC; bool stableA; bool stableB; bool stableC; }ChannelDebounce_t; /** * brief u16绝对值差 */ static inline uint16_t abs_diff_u16(uint16_t a, uint16_t b) { return (a b) ? (a - b) : (b - a); } /** * brief 单通道离群检测 * param ySelf 当前通道亮度 * param yOther1 另一路亮度 * param yOther2 第三路亮度 * param pixelSum 当前通道直方图总像素 * param thSevere 严重遮挡亮度阈值 * retval true 通道异常失效 */ static bool ChannelIsAbnormal(uint16_t ySelf, uint16_t yOther1, uint16_t yOther2, uint32_t pixelSum, uint16_t thSevere) { /* 直方图无有效像素 → 直接判定失效 */ if(pixelSum 0U) { return true; } /* 参考值 另外两目的均值不受自身亮度污染 */ uint16_t ref (yOther1 yOther2) / 2U; uint16_t diff abs_diff_u16(ySelf, ref); return (diff thSevere); } /** * brief 通道状态防抖滤波抑制瞬时跳变误触发 * param isRawAbnormal 当前帧原始检测结果 * param pDebounceCnt 计数缓存 * param pStableState 防抖后稳定状态 * param debounceThresh 防抖帧数例连续3帧异常才判定 */ static void DebounceFilter(bool isRawAbnormal, uint8_t *pDebounceCnt, bool *pStableState, uint8_t debounceThresh) { if(isRawAbnormal) { if(*pDebounceCnt debounceThresh) { (*pDebounceCnt); } if(*pDebounceCnt debounceThresh) { *pStableState true; } } else { /* 正常立刻清零计数器 */ *pDebounceCnt 0U; *pStableState false; } } /** * brief 根据通道有效状态分配Q8融合权重 */ static void CalcFusionWeight(bool validA, bool validB, bool validC, uint8_t *wA, uint8_t *wB, uint8_t *wC) { uint8_t validCnt 0U; validCnt validA ? 1U : 0U; validCnt validB ? 1U : 0U; validCnt validC ? 1U : 0U; *wA 0U; *wB 0U; *wC 0U; if(validCnt 3U) { /* 三路均等融合 1/3 ≈ 85/256 */ *wA 85U; *wB 85U; *wC 85U; } else if(validCnt 2U) { /* 两路有效 权重0.5 128 */ *wA validA ? 128U : 0U; *wB validB ? 128U : 0U; *wC validC ? 128U : 0U; } else if(validCnt 1U) { /* 单路有效权重1.0256 */ *wA validA ? Q8_SCALE : 0U; *wB validB ? Q8_SCALE : 0U; *wC validC ? Q8_SCALE : 0U; } else { /* 全部通道失效权重置零 */ *wA 0U; *wB 0U; *wC 0U; } } /** * brief 直方图加权融合 */ static void FuseHistogram(const HistBin_t histA[BIN_NUM], const HistBin_t histB[BIN_NUM], const HistBin_t histC[BIN_NUM], uint8_t wA,uint8_t wB,uint8_t wC, HistBin_t histOut[BIN_NUM]) { uint32_t i; for(i0U; iBIN_NUM; i) { uint64_t acc 0ULL; acc (uint64_t)histA[i] * wA; acc (uint64_t)histB[i] * wB; acc (uint64_t)histC[i] * wC; histOut[i] (HistBin_t)(acc 8U); } } /** * brief 三目AE直方图自适应融合主入口 * param histA/B/C 三路直方图输入 * param yMean 三路平均亮度 * param sumPixel 三路直方图像素总数 * param pDebounce 防抖状态(帧间必须保留不可局部变量) * param thSevere 严重遮挡亮度阈值 * param debounceFrameThresh 防抖帧数(推荐2~5帧) * param pOut 融合输出结果 */ void TriAeHistAdaptiveFusion( const HistBin_t histA[BIN_NUM], const HistBin_t histB[BIN_NUM], const HistBin_t histC[BIN_NUM], const TriYMean_t yMean, const TriHistPixelSum_t sumPixel, ChannelDebounce_t *pDebounce, uint16_t thSevere, uint8_t debounceFrameThresh, TriHistFusionOut_t *pOut ) { bool rawAbnA, rawAbnB, rawAbnC; bool validA, validB, validC; /* 步骤1离群检测以另外两目均值为参考基准 */ rawAbnA ChannelIsAbnormal(yMean.yA, yMean.yB, yMean.yC, sumPixel.sumA, thSevere); rawAbnB ChannelIsAbnormal(yMean.yB, yMean.yA, yMean.yC, sumPixel.sumB, thSevere); rawAbnC ChannelIsAbnormal(yMean.yC, yMean.yA, yMean.yB, sumPixel.sumC, thSevere); /* 步骤2帧间防抖滤波 */ DebounceFilter(rawAbnA, pDebounce-debounceCntA, pDebounce-stableA, debounceFrameThresh); DebounceFilter(rawAbnB, pDebounce-debounceCntB, pDebounce-stableB, debounceFrameThresh); DebounceFilter(rawAbnC, pDebounce-debounceCntC, pDebounce-stableC, debounceFrameThresh); /* 防抖稳定结果true异常失效false正常有效 */ validA !pDebounce-stableA; validB !pDebounce-stableB; validC !pDebounce-stableC; /* 步骤3异常掩码标记 */ pOut-abnormalMask 0U; if(pDebounce-stableA) pOut-abnormalMask | CH_MASK_A; if(pDebounce-stableB) pOut-abnormalMask | CH_MASK_B; if(pDebounce-stableC) pOut-abnormalMask | CH_MASK_C; /* 步骤4业务逻辑只要任意一目异常亮度独立计算不再融合 */ pOut-bUseSeparateY (pOut-abnormalMask ! 0U) ? true : false; /* 步骤5权重分配 直方图融合 */ CalcFusionWeight(validA, validB, validC, pOut-wA, pOut-wB, pOut-wC); FuseHistogram(histA,histB,histC,pOut-wA,pOut-wB,pOut-wC,pOut-histOut); }七、优化收益总结✅离群检测基准改进彻底解决异常通道污染参考均值造成正常通道误判的缺陷✅空直方图保护无有效像素通道直接判定失效✅帧间防抖消除瞬时跳变带来的 AE 曝光闪烁✅亮度‑直方图逻辑解耦直方图依然可用剩余有效通道融合亮度严格独立✅模块拆分函数可重入、无全局变量耦合便于 ISP 固件移植✅输出异常掩码便于调试定位故障通道✅全部定点整数运算无浮点除法适合嵌入式低算力平台。
返回列表