马上注册,看完整文章,学更多FPGA知识。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
——边缘检测工程:灰度转换模块代码解析 作者:陈刀刀 本文为明德扬原创文章,转载请注明出处! 灰度转换模块的功能:该模块将接收到的RGB数据经过灰度转换公式计算,输出灰度数据给下一个模块。
一、设计架构
RGB图像转换成灰度图像的公式为:Gray = (red * 70 + green * 150 + bule *30)>>8 公式中的RGB是888格式,即R、G、B均用8比特表示。注意,本模块输入的是565格式,即R、G、B分别是5、6、5表示。 RGB565转成RGB888的方法,只要后面补0或者低位即可。例如R后面补3个0。
如上图,第1个像素进来的din为16’h0001,即R=5’b00000,G=6’b000000,B=5’b00001。 改为RGB888格式后,R=8’b00000000,G=8b’00000000,B=8’b00001000
如上图,第2个像素进来的din为16’h0203,即R=5’b00000,G=6’b001010,B=5’b00011。 改为RGB888格式后,R=8’b00000000,G=8’b00001010,B=8’b00000011。
二、信号的意义
信号 | | | | | | | | | | | | | | 数据有效信号,din_vld为1,数据有效,din_vld为0,数据无效。 | | | | | | | | | 输出的灰度图像数据。收到din_vld有效信号时,dout输出的数据为(red * 70 + green * 150 + bule *30)的值右移8位。 | | | 输出数据的有效指示信号,dout_vld为1时,数据有效,dout_vld为0,数据无效。 | | | 输出的第一个有效数据指示信号吧,本帧的第1个像素。 | | | 输出的最后一个有效数据指示信号,本帧最后1个像素。 | | | RGB图像中红色数据。该数据为8位,0到2位补0。3到7位为有效数据的11到15位。 | | | RGB图像中的绿色数据。该数据为8位,0到1位补0,2到7位为有效数据的5到10位。 | | | RGB图像中的蓝色数据。该数据为8位,0到2位补0,3到7位为有效数据的0到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 | module rgb565_gray( clk , rst_n , din , din_vld , din_sop , din_eop , dout , dout_vld , dout_sop , dout_eop ); input clk ; input rst_n ; input [15:0] din ; input din_vld ; input din_sop ; input din_eop ; output [7:0] dout ; output dout_vld ; output dout_sop ; output dout_eop ; reg [7:0] dout ; reg dout_vld ; reg dout_sop ; reg dout_eop ; wire [7:0] red ; wire [7:0] green ; wire [7:0] bule ; assign red = {din[15:11] , 3’b0}; assign green = {din[10:5] , 2’b0}; assign bule = {din[4:0] , 3’b0}; always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin dout <= 8'd0; end else if(din_vld)begin dout <= (red * 70 + green * 150 + bule *30) >> 8; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin dout_vld <= 1'b0; end else begin dout_vld <= din_vld; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin dout_sop <= 1'b0; end else begin dout_sop <= din_sop; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin dout_eop <= 1'b0; end else begin dout_eop <= din_eop; end end endmodule |
|