基于FPGA的图像RGB转HLS实现,包含testbench和MATLAB辅助验证程序

1.算法运行效果图预览

 

将FPGA结果导入到MATLAB显示效果:

 

2.算法运行软件版本

Vivado2019.2

 

matlab2022a

 

3.算法理论概述

        在数字图像处理中,RGB和HLS是两种常见的颜色空间。RGB基于红绿蓝三种基本颜色的叠加来定义其他颜色,而HLS则代表色调、亮度和饱和度,它更接近人类视觉对颜色的感知。将RGB图像转换为HLS图像的目的通常是为了更方便地进行某些类型的图像处理,比如色彩平衡和色彩分离。RGB颜色空间基于笛卡尔坐标系,其中R、G、B分别代表红、绿、蓝三种颜色的强度。HLS颜色空间则是基于圆柱坐标系,其中H代表色调(0-360度),L代表亮度(0-1),S代表饱和度(0-1)。

 

        转换的第一步是将RGB值归一化到[0,1]范围。然后,通过计算RGB颜色空间的最大值和最小值来得到亮度L。色调H由RGB中的最大值和最小值决定,并使用反正切函数来得到0-360度的角度。最后,饱和度S基于最大值和亮度L来计算。

 

具体的转换公式如下:

 

将RGB值归一化到[0,1]:

R' = R/255

G' = G/255

B' = B/255

 

3.1计算最大值和最小值

 

Max = max(R', G', B')

Min = min(R', G', B')

Diff = Max - Min

 

3.2计算亮度L

 

L = (Max + Min) / 2

 

 

3.3计算饱和度S

if L < 0.5:

S = Diff / (Max + Min)

else:

S = Diff / (2 - Max - Min)

 

3.4计算色调H

 

if Diff == 0:

H = 0

else:

if Max == R':

H = (60 * ((G' - B') / Diff) + 360) % 360

elif Max == G':

H = (60 * ((B' - R') / Diff) + 120) % 360

elif Max == B':

H = (60 * ((R' - G') / Diff) + 240) % 360

 

       这些公式可以将每一个像素从RGB颜色空间转换到HLS颜色空间。值得注意的是,这种转换通常是可逆的,也就是说,你也可以从HLS颜色空间转换回RGB颜色空间。在实现RGB到HLS的转换时,通常会先读取一幅RGB图像,然后将上述公式应用于图像中的每一个像素。

 

 

 

 

4.部分核心程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/08/01 
// Design Name:
// Module Name: RGB2gray
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
  
module test_image;
  
reg i_clk;
reg i_rst;
reg [7:0] Rbuff [0:100000];
reg [7:0] Gbuff [0:100000];
reg [7:0] Bbuff [0:100000];
reg [7:0] i_Ir,i_Ig,i_Ib;
wire [7:0] o_H;
wire [7:0] o_L,o_S;
integer fids1,dat1,fids2,dat2,fids3,dat3,jj=0;
  
  
  
  
//D:\FPGA_Proj\FPGAtest\codepz
initial
begin
    fids1 = $fopen("D:\\FPGA_Proj\\FPGAtest\\codepz\\R.bmp","rb");
    dat1  = $fread(Rbuff,fids1);
    $fclose(fids1);
end
  
initial
begin
    fids2 = $fopen("D:\\FPGA_Proj\\FPGAtest\\codepz\\G.bmp","rb");
    dat2  = $fread(Gbuff,fids2);
    $fclose(fids2);
end
  
initial
begin
    fids3 = $fopen("D:\\FPGA_Proj\\FPGAtest\\codepz\\B.bmp","rb");
    dat3 = $fread(Bbuff,fids3);
    $fclose(fids3);
end
  
  
  
initial
begin
i_clk=1;
i_rst=1;
#1200;
i_rst=0;
end
  
always #5  i_clk=~i_clk;
  
always@(posedge i_clk)
begin
    i_Ir<=Rbuff[jj];
    i_Ig<=Gbuff[jj];
    i_Ib<=Bbuff[jj];
    jj<=jj+1;
end
  
  
  
main_RGB2HLS main_RGB2HLS_u(
.i_clk    (i_clk),
.i_rst    (i_rst),
.i_image_R      (i_Ir),
.i_image_G      (i_Ig),
.i_image_B      (i_Ib),
.o_H            (o_H),// Y
.o_L            (o_L),// Y
.o_S            (o_S)
);
  
  
integer fout1;
initial begin
 fout1 = $fopen("H.txt","w");
end
  
always @ (posedge i_clk)
 begin
    if(jj<=66616)
    $fwrite(fout1,"%d\n",o_H);
    else
    $fwrite(fout1,"%d\n",0);
end
  
integer fout2;
initial begin
 fout2 = $fopen("L.txt","w");
end
  
always @ (posedge i_clk)
 begin
    if(jj<=66616)
    $fwrite(fout2,"%d\n",o_L);
    else
    $fwrite(fout2,"%d\n",0);
end
  
  
integer fout3;
initial begin
 fout3 = $fopen("S.txt","w");
end
  
always @ (posedge i_clk)
 begin
    if(jj<=66616)
    $fwrite(fout3,"%d\n",o_S);
    else
    $fwrite(fout3,"%d\n",0);
end
endmodule

  

 

posted @   简简单单做算法  阅读(59)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示