基于FPGA的彩色图像转灰度算法实现

  昨天才更新了两篇博客,今天又要更新了,并不是我垃圾产,只不过这些在上个月就已经写好了,只是因为比赛忙,一直腾不出时间整理出来发表而已,但是做完一件事情总感觉不写一博文总结一下就少点什么,所以之后的一段时间里我会把我这学期学到的一些东西陆续整理出来发表,给自己一个总结交代。

  将彩色图像转化为灰度的方法有两种,一个是令RGB三个分量的数值相等,输出后便可以得到灰度图像,另一种是转化为YCbCr格式,将Y分量提取出来,YCbCr格式中的Y分量表示的是图像的亮度和浓度所以只输出Y分量,得到的图像就是灰度图像了。我在这里选择第二种方法实现。

  YCBCr是通过有序的三元组来表示的,三元由Y(Luminance)、Cb(Chrominance-Blue)和Cr(Chrominance-Red)组成,其中Y表示颜色的明亮度和浓度,而Cb和Cr则分别表示颜色的蓝色浓度偏移量和红色浓度偏移量。人的肉眼对由YCbCr色彩空间编码的视频中的Y分量更敏感,而Cb和Cr的微小变化不会引起视觉上的不同,根据该原理,通过对Cb和Cr进行子采样来减小图像的数据量,使得图像对存储需求和传输带宽的要求大大降低,从而达到在完成图像压缩的同时也保证了视觉上几乎没有损失的效果,进而使得图像的传输速度更快,存储更加方便。我们要的到灰度图像,首先要将采集到的彩色图像转化为YCbCr。

  我们配置摄像头采集到的数据是RGB565的格式,官方给出的转化公式是RGB888->YCbCr,所以先需要将RGB565转化为RGB888,转化方法如下:

  24bit RGB888 -> 16bit RGB565 的转换(只取高位)

  24ibt RGB888 {R7 R6 R5 R4 R3 R2 R1 R0} {G7 G6 G5 G4 G3 G2 G1 G0} {B7 B6 B5 B4 B3 B2 B1 B0}

  16bit RGB656 {R7 R6 R5 R4 R3} {G7 G6 G5 G4 G3 G2} {B7 B6 B5 B4 B3}

  同样也可以恢复回去。

  16bit RGB565 -> 24bit RGB888 的转换(高位补低位)

  16bit RGB656 {R4 R3 R2 R1 R0} {G5 G4 G3 G2 G1 G0} {B4 B3 B2 B1 B0}

  24ibt RGB888 {R4 R3 R2 R1 R0 R2 R1 R0} {G5 G4 G3 G2 G1 G0 G1 G0} {B4 B3 B2 B1 B0 B2 B1 B0}

1 //--------------------------------------------
2 //RGB565 to RGB 888
3 wire     [7:0]    cmos_R0;
4 wire     [7:0]    cmos_G0;
5 wire     [7:0]    cmos_B0;
6 
7 assign cmos_R0    =     {cmos_R, cmos_R[4:2]};
8 assign cmos_G0    =     {cmos_G, cmos_G[5:4]};
9 assign cmos_B0    =     {cmos_B, cmos_B[4:2]};

  采用高位补低位的方法直接转化即可。

  这是官方给的RGB888 to YCbCr的算法公式,我们可以直接把算法移植到FPGA上,但是我们都知道FPGA无法进行浮点运算,所以我们采取将整个式子右端先都扩大256倍,然后再右移8位,这样就得到了FPGA擅长的乘法运算和加法运算了。

  这个计算式子看起来是十分简单的,但是要是直接用Verilog直接写出来,那么只能说,这个人的代码写的一塌糊涂,所以这里就引出FPGA中流水线的设计思想。

     在这里我们选择加3级流水线,就第一个Y分量而言,先计算括号中得乘法运算,消耗一个时钟,然后将括号中的数据求和,消耗一个时钟,这里为了计算方便,将128也扩大256倍,放到括号中,最终结果除以256就行了也就是右移8位,在FPGA中我们只需要舍弃低8位取高8位就行。具体代码如下

 1 //--------------------------------------------
 2 /*Refer to <OV7725 Camera Module Software Applicaton Note> page 5
 3     Y     =    (77 *R     +     150*G     +     29 *B)>>8
 4     Cb     =    (-43*R    -     85 *G    +     128*B)>>8 + 128
 5     Cr     =    (128*R     -    107*G      -    21 *B)>>8 + 128
 6 --->
 7     Y     =    (77 *R     +     150*G     +     29 *B)>>8
 8     Cb     =    (-43*R    -     85 *G    +     128*B + 32768)>>8
 9     Cr     =    (128*R     -    107*G      -    21 *B + 32768)>>8*/
10 //--------------------------------------------
11 //RGB888 to YCrCb
12 //step1 conmuse 1clk
13 reg     [15:0]    cmos_R1, cmos_R2, cmos_R3;
14 reg     [15:0]    cmos_G1, cmos_G2, cmos_G3;
15 reg     [15:0]    cmos_B1, cmos_B2, cmos_B3;
16 always @(posedge clk or negedge rst_n)
17 begin
18     if(!rst_n)begin
19              cmos_R1 <= 16'd0;
20              cmos_G1 <= 16'd0;
21              cmos_B1 <= 16'd0;
22          cmos_R2 <= 16'd0;
23              cmos_G2 <= 16'd0;
24              cmos_B2 <= 16'd0;
25          cmos_R3 <= 16'd0;
26              cmos_G3 <= 16'd0;
27              cmos_B3 <= 16'd0;
28     end
29     else begin
30         cmos_R1 <= cmos_R0 * 8'd77;
31         cmos_G1 <= cmos_G0 * 8'd150;
32         cmos_B1 <= cmos_B0 * 8'd29; 
33         cmos_R2 <= cmos_R0 * 8'd43; 
34         cmos_G2 <= cmos_G0 * 8'd85; 
35         cmos_B2 <= cmos_B0 * 8'd128; 
36       cmos_R3 <= cmos_R0 * 8'd128;
37       cmos_G3 <= cmos_G0 * 8'd107;
38       cmos_B3 <= cmos_B0 * 8'd21;
39     end
40 end
41 
42 //-----------------------------------------------
43 //step2 consume 1clk
44 reg    [15:0]    img_Y0;
45 reg     [15:0]    img_Cb0;
46 reg     [15:0]    img_Cr0;
47 
48 always @(posedge clk or negedge rst_n)
49 begin
50     if(!rst_n)begin
51         img_Y0 <= 16'd0;
52         img_Cb0 <= 16'd0;
53         img_Cr0 <= 16'd0;
54     end
55     else begin
56         img_Y0  <= cmos_R1 + cmos_G1 + cmos_B1;
57         img_Cb0 <= cmos_B2 - cmos_R2 - cmos_G2 + 16'd32768;
58         img_Cr0 <= cmos_R3 - cmos_G3 - cmos_B3 + 16'd32768;
59     end
60     
61 end
62 //-------------------------------------------
63 //step3 conmuse 1clk
64 reg    [7:0]    img_Y1;
65 reg     [7:0]    img_Cb1;
66 reg     [7:0]    img_Cr1;
67 
68 always @(posedge clk or negedge rst_n)
69 begin
70     if(!rst_n)begin
71         img_Y1  <= 8'd0;
72         img_Cb1 <= 8'd0;
73         img_Cr1 <= 8'd0;
74     end
75     else begin
76         img_Y1  <= img_Y0  [15:8];
77         img_Cb1 <= img_Cb0 [15:8];
78         img_Cr1 <= img_Cr0 [15:8];
79     end
80     
81 end 

流水线

   对于流水线的理论详细解释,请看我另一篇博文:http://www.cnblogs.com/ninghechuan/p/6970750.html

  将RGB565—>YCbCr成功后,提取出Y的值输出,就可以得到灰度色彩的图像了。

  将采集到的RGB565的像素数据,输入到算法处理模块进行操作,由RGB565——>YCbCr——Gray官方给出的公式来算,先将RGB565拆分开R G B三个分量,使用如上公式计算的到Y Cb Cr是三个分量。

  RGB转YCbCr算法的仿真过程,从图中可以看出,加了流水线后的运算过程,每一级运算相差一个时钟,然而每一级都在进行新的运算,我们加了3级流水线,这样运算速度可以提升3倍。

  将行信号、场信号和像素数据使能信号进行延时,消耗多少周期便延时几个周期,保持时钟的同步性。

  最后将Y分量的数据输出,进行位拼接,16位的RGB565像素R、G、B分量分别对应的取Y分量的高位,最后的输出显示出来就是灰度图像了。

1 assign lcd_data = {per_img_Y1 [7:3],per_img_Y1 [7:2],per_img_Y1 [7:3]};//Gray

  这里还是采用高位补低位的方法。

  最终下载到FPGA开发板上,显示如下:

  图上为灰度显示,图下为转化前的原图,可以看出,灰度最终显示的是将彩色图像的颜色过滤掉,这样减小了图像的体积,滤掉多余的影响因素,为后面的滤波,边缘检测等图像处理做出关键性的基础。

转载请注明出处:NingHeChuan(宁河川)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏专知

【论文推荐】最新八篇图像描述生成相关论文—比较级对抗学习、正则化RNNs、深层网络、视觉对话、婴儿说话、自我检索

【导读】专知内容组整理了最近八篇图像描述生成(Image Captioning)相关文章,为大家进行介绍,欢迎查看! 1.Generating Diverse ...

46610
来自专栏专知

【论文推荐】最新5篇目标检测相关论文——显著目标检测、弱监督One-Shot检测、多框检测器、携带物体检测、假彩色图像检测

【导读】专知内容组整理了最近目标检测相关文章,为大家进行介绍,欢迎查看! 1. MSDNN: Multi-Scale Deep Neural Network f...

3797
来自专栏专知

【论文推荐】最新八篇生成对抗网络相关论文—条件翻译、RGB-D动作识别、量子生成对抗网络、语义对齐、视频摘要、视觉-文本注意力

1943
来自专栏专知

【论文推荐】最新六篇命名实体识别相关论文—跨专业医学、阿拉伯命名实体、中国临床、深度多任务学习、多模态、图卷积网络

2082
来自专栏素质云笔记

LSH︱python实现MinHash-LSH及MinHash LSH Forest——datasketch(四)

关于局部敏感哈希算法,之前用R语言实现过,但是由于在R中效能太低,于是放弃用LSH来做相似性检索。学了Python发现很多模块都能实现,而且通过随机投影森林让查...

4246
来自专栏开源FPGA

基于FPGA的肤色识别算法实现

         大家好,给大家介绍一下,这是基于FPGA的肤色识别算法实现。          我们今天这篇文章有两个内容一是实现基于FPGA的彩色图片转灰度...

2026
来自专栏专知

【论文推荐】最新5篇度量学习(Metric Learning)相关论文—人脸验证、BIER、自适应图卷积、注意力机制、单次学习

【导读】专知内容组整理了最近五篇度量学习(Metric Learning)相关文章,为大家进行介绍,欢迎查看! 1. Additive Margin Softm...

1.5K8
来自专栏开源FPGA

基于FPGA的RGB565_YCbCr_Gray算法实现

         前面我们讲了基于FPGA用VGA显示一副静态图片,那么接下来我们就接着前面的工程来实现我们图像处理的基础算法里最简单的一个那就是彩色图像转灰度...

21111
来自专栏专知

【论文推荐】最新五篇度量学习相关论文—无标签、三维姿态估计、主动度量学习、深度度量学习、层次度量学习与匹配

【导读】专知内容组整理了最近五篇度量学习(Metric Learning )相关文章,为大家进行介绍,欢迎查看! 1.Mining on Manifolds: ...

3283
来自专栏专知

【论文推荐】最新十篇度量学习相关论文—可量化表示、非线性度量学习、在线深度量学习、大间隔最近邻、判别深度度量、域自适应

1652

扫码关注云+社区