基于FPGA的图像RGB转CIE-Lab实现,包含testbench和MATLAB辅助验证程序
1.算法运行效果图预览
将FPGA的结果导入到matlab,并和matlab的仿真结果进行对比:
2.算法运行软件版本
vivado2019.2
matlab2022a
3.算法理论概述
RGB和CIE-Lab是两种常用的颜色空间,它们在不同的应用领域中各有优势。RGB颜色空间主要用于显示设备,而CIE-Lab颜色空间则更适用于颜色测量和计算。因此,将RGB颜色空间转换为CIE-Lab颜色空间具有重要的应用价值。
RGB颜色模式是一种常见的颜色表示方法,它是通过红、绿、蓝三种颜色的不同比例来表示不同的颜色。其中,红、绿、蓝三种颜色的值分别范围在0到255之间。
CIELAB颜色模式是一种更加科学的颜色表示方法,它是基于人眼对颜色的感知来定义的。CIELAB颜色模式包括三个分量:L表示亮度,a表示绿色到红色的色差,b表示蓝色到黄色的色差。RGB到CIELAB转换可以通过以下步骤进行:
将RGB颜色模式转换为X, Y, Z三个分量的CIE XYZ颜色模式。
将CIE XYZ颜色模式转换为CIE Lab*颜色模式。
计算CIELAB颜色模式的L, a, b三个分量。
3.1RGB颜色空间
RGB颜色空间是一种基于红、绿、蓝三种基本颜色的颜色空间。在该空间中,任意一种颜色都可以由这三种基本颜色的不同强度组合而成。RGB颜色空间通常用于显示设备,如电视、计算机显示器等。
3.2CIE-Lab颜色空间
CIE-Lab颜色空间是一种基于人类视觉系统的颜色空间,由国际照明委员会(CIE)制定。在该空间中,颜色的表示与人眼的感知更加一致。CIE-Lab颜色空间由三个分量组成:L表示亮度,a表示红绿色差,b*表示黄蓝色差。
3.3RGB转CIE-Lab算法原理
RGB转CIE-Lab的转换过程可以分为两个步骤:首先将RGB颜色空间转换为XYZ颜色空间,然后将XYZ颜色空间转换为CIE-Lab颜色空间。
RGB转XYZ
RGB转XYZ的转换公式如下:
X = 0.4124R + 0.3576G + 0.1805B
Y = 0.2126R + 0.7152G + 0.0722B
Z = 0.0193R + 0.1192G + 0.9505B
其中,R、G、B分别表示红、绿、蓝三个通道的颜色值,取值范围为[0,255]。X、Y、Z表示转换后的XYZ颜色空间的三个分量。
XYZ转CIE-Lab
XYZ转CIE-Lab的转换公式如下:
L* = 116f(Y/Yn) - 16
a* = 500[f(X/Xn) - f(Y/Yn)]
b* = 200[f(Y/Yn) - f(Z/Zn)]
其中,Xn、Yn、Zn表示XYZ颜色空间的参考白点的坐标值。f(t)是一个非线性函数,定义如下:
f(t) = t^(1/3) (当t>0.008856时)
= 7.787t + 16/116 (当t≤0.008856时)
在FPGA设计过程中,一般将上述公式转换为如下表达式进行处理:
fX = XT .* X.^(1/3) + (~XT) .* (7.787 .* X + 4/29);
fY = YT .* Y.^(1/3) + (~YT) .* (7.787 .* Y + 4/29);
fZ = ZT .* Z.^(1/3) + (~ZT) .* (7.787 .* Z + 4/29);
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | `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_X,o_Y,o_Z; wire [15:0] o_L; wire signed[15:0] o_A,o_B; integer fids1,dat1,fids2,dat2,fids3,dat3,jj=0; //D:\D:\FPGA_Proj\FPGAtest\code_proj initial begin fids1 = $ fopen ( "D:\\FPGA_Proj\\FPGAtest\\code_proj\\R.bmp" , "rb" ); dat1 = $ fread (Rbuff,fids1); $ fclose (fids1); end initial begin fids2 = $ fopen ( "D:\\FPGA_Proj\\FPGAtest\\code_proj\\G.bmp" , "rb" ); dat2 = $ fread (Gbuff,fids2); $ fclose (fids2); end initial begin fids3 = $ fopen ( "D:\\FPGA_Proj\\FPGAtest\\code_proj\\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_lab main_lab_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_X (o_X), .o_Y (o_Y), .o_Z (o_Z), .o_L (o_L), .o_A (o_A), .o_B (o_B) ); integer fout1; initial begin fout1 = $ fopen ( "X.txt" , "w" ); end always @ (posedge i_clk) begin if (jj<=66615) $ fwrite (fout1, "%d\n" ,o_X); else $ fwrite (fout1, "%d\n" ,0); end integer fout2; initial begin fout2 = $ fopen ( "Y.txt" , "w" ); end always @ (posedge i_clk) begin if (jj<=66615) $ fwrite (fout2, "%d\n" ,o_Y); else $ fwrite (fout2, "%d\n" ,0); end integer fout3; initial begin fout3 = $ fopen ( "Z.txt" , "w" ); end always @ (posedge i_clk) begin if (jj<=66615) $ fwrite (fout3, "%d\n" ,o_Z); else $ fwrite (fout3, "%d\n" ,0); end integer fout4; initial begin fout4 = $ fopen ( "L.txt" , "w" ); end always @ (posedge i_clk) begin if (jj<=66615) $ fwrite (fout4, "%d\n" ,o_L); else $ fwrite (fout4, "%d\n" ,0); end integer fout5; initial begin fout5 = $ fopen ( "A.txt" , "w" ); end always @ (posedge i_clk) begin if (jj<=66615) $ fwrite (fout5, "%d\n" ,o_A); else $ fwrite (fout5, "%d\n" ,0); end integer fout6; initial begin fout6 = $ fopen ( "B.txt" , "w" ); end always @ (posedge i_clk) begin if (jj<=66615) $ fwrite (fout6, "%d\n" ,o_B); else $ fwrite (fout6, "%d\n" ,0); end endmodule |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下