基于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 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)