4. 图像预处理算法基础:色彩空间转换、白平衡与伽马校正

各位同学,今天我们来聊聊内窥镜图像预处理中最核心的几个算法。说白了,就是让原始传感器数据变成人眼看着舒服、医生能诊断的图像。我在做内窥镜项目时,发现很多新手一上来就搞深度学习,结果发现原始图像质量太差,算法根本跑不动。嗯,预处理这步,其实比你想的重要得多。

4.1 色彩空间转换:RGB2YUV

为什么要把RGB转成YUV?你想想看,人眼对亮度敏感,对颜色没那么敏感。YUV刚好把亮度和色度分开。我习惯用YUV422格式,因为它在FPGA里特别好处理——说白了就是节省带宽。

RGB到YUV的转换公式其实很简单:

Y = 0.299 * R + 0.587 * G + 0.114 * B
U = -0.147 * R - 0.289 * G + 0.436 * B
V = 0.615 * R - 0.515 * G - 0.100 * B

但在FPGA里,浮点数是个大麻烦。我建议直接用定点化处理。举个例子,把系数放大256倍:

Y = (77 * R + 150 * G + 29 * B) >> 8
U = (-38 * R - 74 * G + 112 * B) >> 8
V = (157 * R - 132 * G - 26 * B) >> 8

这里要注意,负数处理要小心。我曾经踩过一个坑——直接用有符号乘法器,结果符号位扩展搞错了,图像出现条纹。后来我改成先做无符号乘法,再单独处理符号位,问题就解决了。

流水线设计思路:

  • 第一级:并行读取R、G、B三个像素值
  • 第二级:三个乘法器同时计算(每个通道独立)
  • 第三级:加法器累加,移位操作
  • 第四级:输出Y、U、V

整个流水线只需要4个时钟周期,吞吐量能达到一个像素/时钟。

4.2 白平衡算法

内窥镜图像经常偏色,因为光源色温不稳定。白平衡说白了就是让白色物体在图像里看起来是白的。我常用的方法是灰度世界法——假设整幅图像的平均颜色是灰色。

算法步骤:

  1. 统计整帧图像的R、G、B均值
  2. 计算增益系数:Gain_R = G_avg / R_avg,Gain_B = G_avg / B_avg
  3. 对每个像素应用增益

在FPGA里实现时,我建议用行累加的方式。为什么?因为整帧统计需要存一帧图像,太浪费BRAM了。我习惯的做法是:

// 伪代码示意
always @(posedge clk) begin
    if (vsync) begin  // 帧同步信号
        sum_r <= 0;
        sum_g <= 0;
        sum_b <= 0;
        pixel_cnt <= 0;
    end else if (de) begin  // 数据有效
        sum_r <= sum_r + r_data;
        sum_g <= sum_g + g_data;
        sum_b <= sum_b + b_data;
        pixel_cnt <= pixel_cnt + 1;
    end
end

等一帧结束,用除法器算出均值。这里有个技巧——除法器很贵,我一般用查找表或者移位近似。比如把像素数近似成2的幂次,直接用移位代替除法。

注意:白平衡增益不能无限大。我曾经遇到过极端情况——某个通道均值接近0,增益算出来几百倍,图像直接饱和。一定要加限幅处理,我一般限制增益在0.5到2.0之间。

4.3 伽马校正

伽马校正,说白了就是调整图像的亮度曲线。人眼对暗部细节更敏感,所以我们要把暗部拉开,亮部压缩。标准伽马值是2.2。

公式:

V_out = V_in ^ (1 / gamma)

在FPGA里做幂运算?别闹。我建议用查找表(LUT)。把0-255的输入值对应的输出值提前算好,存到ROM里。这样每个像素只需要一次查表操作。

但这里有个问题——8位输入对应256个地址,精度够吗?我个人习惯用10位输入,1024个地址,精度更好。代价就是多用了4个BRAM块,但效果提升明显。

我的经验:伽马校正可以和前面的白平衡合并成一个查找表。把白平衡增益和伽马校正系数融合,提前算好一个综合LUT。这样能省一级流水线,延迟更小。我在一个4K@60fps的项目里就是这么干的,效果很好。

4.4 定点化与流水线设计总结

这三个算法在FPGA里实现,核心思路就两点:

  • 定点化:浮点转整数,用移位代替除法,用LUT代替复杂运算
  • 流水线:每个算法拆成3-4级,级间用寄存器打拍,保证吞吐量

我建议你把这三个算法串成一条流水线:

流水线级 操作 延迟(时钟周期)
第1级 RGB输入,寄存器打拍 1
第2级 RGB2YUV乘法运算 1
第3级 白平衡增益乘法 1
第4级 伽马校正查表 1
第5级 输出YUV数据 1

总共5级流水线,延迟5个时钟周期。对于1080p@60fps的图像,每个像素只有约7.7ns的处理时间,5级流水线完全能跑满。嗯,这就是FPGA的魅力——用空间换时间。

好了,这一章的内容就这些。下一章我们会讲图像增强算法,包括直方图均衡化和锐化滤波。到时候我会分享一个我在内窥镜项目中遇到的噪声问题,挺有意思的。