Bootstrap

FPGA图像处理之饱和度增强(附源码以及仿真代码)

FPGA图像处理之饱和度增强(附源码以及仿真代码)

什么是饱和度?

图像饱和度(Saturation) 是图像处理中用于描述颜色鲜艳程度的参数。饱和度越高,颜色越鲜艳(如纯红色);饱和度越低,颜色越接近灰度(如灰色),在FPGA(现场可编程门阵列)中实现图像饱和度调整,通常需要结合硬件逻辑设计,以满足实时性和低功耗的需求。

饱和度实现的核心原理

在数字图像处理中,调整饱和度通常需要对颜色空间进行转换和运算。常见的方法包括:

RGB到HSV/HSL/YUV转换:将图像从RGB颜色空间转换到HSV(色相、饱和度、明度)或YUV(亮度、色度)等颜色空间,直接调整饱和度分量,再转换回RGB。
直接数学运算:在RGB空间中通过线性组合调整颜色通道的权重,增强或减弱颜色的鲜艳程度。

源码

`timescale 1ns / 1ps

module Saturation_adj#(
parameter [8:0]  ADJUST_VAL = 128 // 饱和度调节参数,9位,默认值为128
)  
(
    input                   I_clk  ,    // 输入时钟信号
    input                   I_rst_n,    // 输入复位信号,低电平有效

    input                   I_tlast  ,  // 行结束信号
    input                   I_tuser  ,  // 帧开始信号
    input [23:0]            I_tdata  ,  // 输入数据,总共包含4个像素的RGB值,每个像素24位,4*24=96位
    input                   I_tvalid ,  // 输入数据有效信号
    output                  I_tready ,  // 输入数据准备好信号

    output                  O_tlast  ,  // 输出行结束信号
    output                  O_tuser  ,  // 输出帧开始信号
    output [23:0]           O_tdata  ,  // 输出数据
    output                  O_tvalid ,  // 输出数据有效信号
    input                   O_tready    // 输出数据准备好信号
);

/*****************************************************************
                        将输入的96位数据切分为4个24位的像素,以便后续处理                                        
*****************************************************************/


    // 定义RGB888格式的数组,存储每个像素的R、G、B分量
    wire [7:0]  rgb888_r;
    wire [7:0]  rgb888_g;
    wire [7:0]  rgb888_b;

    // 从每个像素中提取R、G、B分量,注意位宽和位置
    assign   rgb888_r = I_tdata[16+:8];   // 第1个像素的R分量
    assign   rgb888_g = I_tdata[8+:8] ;   // 第1个像素的G分量
    assign   rgb888_b = I_tdata[0+:8] ;   // 第1个像素的B分量



/*****************************************************************
                        信号声明部分                                         
*****************************************************************/
    // 定义调整值数组,每个像素一个调整值
    wire [8:0]   adjust_val;

    // 将参数ADJUST_VAL赋值给每个像素的调整值
    assign adjust_val = ADJUST_VAL;

    
    // 定义用于同步的寄存器,延迟输入的控制信号
    reg  [3:0]   I_tlast_r ;
    reg  [3:0]   I_tuser_r ;
    reg  [3:0]   I_tvalid_r;

    // 定义用于计算亮度Y的中间变量
    reg  [16:0]  Y_R_m;
    reg  [17:0]  Y_G_m;
    reg  [14:0]  Y_B_m;

    // 定义用于存储第一级流水线的RGB值
    reg  [7:0]   rgb888_r_r0;
    reg  [7:0]   rgb888_g_r0;
    reg  [7:0]   rgb888_b_r0;
    reg  [8:0]   RGB_C;
    
    // 定义Y的计算结果
    wire [17:0]  Y_w;
    reg  [7:0]   Y  ;

    // 定义用于存储第二级流水线的RGB值
    reg  [7:0]   rgb888_r_r1;
    reg  [7:0]   rgb888_g_r1;
    reg  [7:0]   rgb888_b_r1;

    // 定义Y_C的符号位和绝对值,用于判断调整值的正负
    reg          Y_C_sign;
    reg  [7:0]   Y_C_abs ;

    // 定义用于存储第三级流水线的中间结果
    reg  [16:0]   Y_m;

    reg  [16:0]   rgb888_r_r2;
    reg  [16:0]   rgb888_g_r2;
    reg  [16:0]   rgb888_b_r2;

    // 定义Y_m_s等用于符号扩展的变量
    wire [18:0] Y_m_s;
    wire [18:0] Y_R_m_s;
    wire [18:0] Y_G_m_s;
    wire [18:0] Y_B_m_s;

    // 定义最终新的RGB值
    reg  [7:0]  R_new;
    reg  [7:0]  G_new;
    reg  [7:0]  B_new;
    

    // 定义用于亮度计算的常数系数
    parameter C0 = 9'd306;  // 0.299*1024,用于R分量
    parameter C1 = 10'd601; // 0.587*1024,用于G分量
    parameter C2 = 7'd117;  // 0.114*1024,用于B分量

/*****************************************************************
                    计算部分,实现饱和度调整                                         
*****************************************************************/


        // 第一级流水线,计算Y的各部分并保存RGB值
        // Y=0.299*R+0.587*G+0.114*B
        always @(posedge I_clk or negedge I_rst_n) begin
            if(!I_rst_n) begin
                {Y_R_m, Y_G_m, Y_B_m} <= 0;
                {rgb888_r_r0, rgb888_g_r0, rgb888_b_r0} <= 0;
   
;