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;