【正点原子FPGA连载】第四十九章OV5640摄像头HDMI灰度显示实验 您所在的位置:网站首页 ov5640时钟配置 【正点原子FPGA连载】第四十九章OV5640摄像头HDMI灰度显示实验

【正点原子FPGA连载】第四十九章OV5640摄像头HDMI灰度显示实验

2023-08-27 08:46| 来源: 网络整理| 查看: 265

1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-300792-1-1.html 3)对正点原子FPGA感兴趣的同学可以加群讨论:994244016 4)关注正点原子公众号,获取最新资料更新 在这里插入图片描述

第四十九章OV5640摄像头HDMI灰度显示实验

前面的实验介绍了OV5640摄像头的HDMI显示实验,而在数字图像处理领域YUV是一种常用的图像格式,其特点是将亮度和色度进行分离,更适合运用于图像处理领域。在本次实验中,将摄像头采集的RGB565格式数据到转换为YUV格式的数据,转换后的灰度数据送到HDMI显示器显示。 本章包括以下几个部分: 4848.1简介 48.2实验任务 48.3硬件设计 48.4程序设计 48.5下载验证 49.1简介 人眼中的锥状细胞是负责彩色视觉的传感器,可分为三个主要的感知类别,分别对应红色、绿色、蓝色,而人眼看到的彩色实际上是红、绿、蓝三原色的各种组合。之前所有的图像显示实验用到的RGB就是以红、绿、蓝为三原色的颜色空间模型,通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。 YUV(YCbCr)是欧洲电视系统所采用的一种颜色编码方法。‘Y’表示明亮度(Luminance或Luma),也就是灰阶值;‘U’和‘V’表示色度,用于描述影像的饱和度和色调。RGB与YUV的转换实际上是色彩空间的转换,即将RGB的三原色色彩空间转换为YUV所表示的亮度与色度的色彩空间模型。YUV 主要应用在模拟系统中,而 YCbCr 是通过 YUV 信号的发展,并通过校正的主要应用在数字视频中的一种编码方法。YUV适用于PAL和SECAM彩色电视制式,而YCrCb适用于计算机用的显示器。 一般意义上 YCbCr 即为 YUV 信号,没有严格的划分。 CbCr 分别为蓝色色度分量、红色色度分量。 RGB着重于人眼对色彩的感应,YUV则着重于视觉对于亮度的敏感程度。使用YUV描述图像的好处在于以下两个方面: (1)亮度(Y)与色度(U、V)是独立的; (2)人眼能够识别数千种不同的色彩,但只能识别20多种灰阶值,采用YUV标准可以降低数字彩色图像所需的储存容量。因而YUV在数字图像处理中是一种很常用的颜色标准。 YUV格式运用最多是以下两种格式: (1)YUV4:4:4 在YUV4:4:4格式中,YUV三个信道的采样率相同。因此在生成的图像里,每个像素都有各自独立的三个分量,每个分量通常为8bit,故每个像素占用3个字节。下图为YUV444单个像素的模型图,可以看出,每个Y都对应一组U、V数据,共同组成一个像素。 在这里插入图片描述

图 49.1.1 单个V444的素 (2)YUV4:2:2 在YUV4:2:2格式中,U和V的采样率是Y的一半(两个相邻的像素共用一对U、V数据)。如下图所示,图中包含两个相邻的像素。第一个像素的三个YUV分量分别是Y1、U1、V1,第二个像素的三个YUV分量分别是Y2、U1、V1,两个像素共用一组U1、V1。 在这里插入图片描述

图 49.1.2 两个相邻的YUV422像素 YUV4:4:4格式和YUV4:2:2格式的数据流也是不同的。如一组连续的四个像素P1、P2、P3、P4,采用YUV444的采样格式时,数据流为Y0 U0 V0、Y1 U1 V1、Y2 U2 V2、Y3 U3 V3,每组数据代表一个像素点。而用YUV422的采样格式时,数据流为Y0 U0 Y1 V1、Y2 U2 Y3 V3。其中,Y0 U0 Y1 V1表示P1、P2两个像素,Y2 U2 Y3 V3表示P3、P4两个像素。本次实验运用的是YUV4:4:4格式。 一般意义上 YCbCr 即为 YUV 信号,没有严格的划分。大家通常说的YUV就是指Ycbcr。 CbCr 分别为蓝色色度分量、红色色度分量。下面为 RGB 与 YCbCr 色彩空间转换的算法公式, RGB 转 YCbCr 的公式如下所示: 在这里插入图片描述

图 49.1.3 RGB 转 YcbCr算法 由于 Verilog HDL 无法进行浮点运算,因此使用扩大 256 倍,再向右移 8Bit的方式,来转换公式,如下所示: 在这里插入图片描述

图 49.1.4 RGB 转 YcbCr算法 为了防止运算过程中出现负数,对上述公式进行进一步变换,得到如下公式: 在这里插入图片描述

图 49.1.5 RGB 转 YcbCr算法 实际上OV5640本身支持输出RGB、YUV格式的数据,本章节实验是着重于RGB转YUV的HDL算法实现,因此把摄像头设置为RGB565格式。当需要显示器显示灰度图时,只需要将转换后的Y值作为R、G、B三原色通道的输入就可以实现了。

49.2实验任务

本节实验任务是使用新起点开发板达到OV5640摄像头采集RGB565格式的数据,RGB565格式的数据通过算法转换,将数据格式转换为YCbCr格式,然后通过HDMI显示器实时显示灰度图的目的。

49.3硬件设计

本章节中硬件设计与OV5640的HDMI显示实验完全相同,此处不再赘述。

49.4程序设计

根据实验任务,首先设计如图 49.4.1所示的系统框图,本章实验的系统框架延续了“OV5640摄像头HDMI显示实验”的整体架构。本次实验包括以下模块:时钟模块、SDRAM控制器模块、IIC驱动模块、IIC配置模块、摄像头采集模块、图像处理模块和HDMI顶层模块。其中时钟模块、SDRAM控制器模块、IIC驱动模块、IIC配置模块、摄像头采集模块和HDMI顶层模块本次实验没有做任何修改,这些模块在“OV5640摄像头HDMI显示实验”中已经说明过,这里不再详述,本次实验只是添加了图像处理模块。 OV5640摄像头HDMI灰度显示系统框图如下图所示: 在这里插入图片描述

图 49.4.1 顶层系统框图 由上图可知,时钟模块(pll和pll_hdmi)为HDMI顶层模块、SDRAM控制模块以及IIC驱动模块提供驱动时钟。IIC驱动模块和IIC配置模块控制着传感器初始化的开始与结束,传感器初始化完成后将采集到的数据写入摄像头采集模块。数据在摄像头采集模块处理完成后写入图像处理模块,图像处理模块将摄像头数据进行处理后存入SDRAM控制模块。顶层模块从SDRAM控制模块中读出数据并驱动显示器显示,这时整个系统才完成了数据的采集、缓存与显示。需要注意的是图像数据采集模块是在SDRAM和传感器都初始化完成之后才开始输出数据的,避免了在SDRAM初始化过程中向里面写入数据。 顶层模块代码如下所示:

1 module ov5640_hdmi_yuv( 2 input sys_clk , //系统时钟 3 input sys_rst_n , //系统复位,低电平有效 4 //摄像头 5 input cam_pclk , //cmos 数据像素时钟 6 input cam_vsync , //cmos 场同步信号 7 input cam_href , //cmos 行同步信号 8 input [7:0] cam_data , //cmos 数据 9 output cam_rst_n , //cmos 复位信号,低电平有效 10 output cam_pwdn , //cmos 电源休眠模式选择信号 11 output cam_scl , //cmos SCCB_SCL线 12 inout cam_sda , //cmos SCCB_SDA线 13 //SDRAM 14 output sdram_clk , //SDRAM 时钟 15 output sdram_cke , //SDRAM 时钟有效 16 output sdram_cs_n , //SDRAM 片选 17 output sdram_ras_n, //SDRAM 行有效 18 output sdram_cas_n, //SDRAM 列有效 19 output sdram_we_n , //SDRAM 写有效 20 output [1:0] sdram_ba , //SDRAM Bank地址 21 output [1:0] sdram_dqm , //SDRAM 数据掩码 22 output [12:0] sdram_addr , //SDRAM 地址 23 inout [15:0] sdram_data , //SDRAM 数据 24 //HDMI接口 25 output tmds_clk_p, // TMDS 时钟通道 26 output tmds_clk_n, 27 output [2:0] tmds_data_p, // TMDS 数据通道 28 output [2:0] tmds_data_n 29 ); 30 31 //parameter define 32 parameter SLAVE_ADDR = 7'h3c ; //OV5640的器件地址7'h3c 33 parameter BIT_CTRL = 1'b1 ; //OV5640的字节地址为16位 0:8位 1:16位 34 parameter CLK_FREQ = 27'd50_000_000 ; //i2c_dri模块的驱动时钟频率 35 parameter I2C_FREQ = 18'd250_000 ; //I2C的SCL时钟频率,不超过400KHz 36 parameter V_CMOS_DISP = 11'd800 ; //CMOS分辨率--行 37 parameter H_CMOS_DISP = 11'd1280 ; //CMOS分辨率--列 38 parameter TOTAL_H_PIXEL = 13'd2570 ; //CMOS分辨率--行 39 parameter TOTAL_V_PIXEL = 13'd980 ; 40 41 //wire define 42 wire clk_100m ; //100mhz时钟,SDRAM操作时钟 43 wire clk_100m_shift ; //100mhz时钟,SDRAM相位偏移时钟 44 wire clk_50m ; 45 wire hdmi_clk ; 46 wire hdmi_clk_5 ; 47 wire locked ; 48 wire locked_hdmi ; 49 wire rst_n ; 50 wire sys_init_done ; //系统初始化完成(sdram初始化+摄像头初始化) 51 wire i2c_exec ; //I2C触发执行信号 52 wire [23:0] i2c_data ; //I2C要配置的地址与数据(高8位地址,低8位数据) 53 wire i2c_done ; //I2C寄存器配置完成信号 54 wire i2c_dri_clk ; //I2C操作时钟 55 wire [ 7:0] i2c_data_r ; //I2C读出的数据 56 wire i2c_rh_wl ; //I2C读写控制信号 57 wire cam_init_done ; //摄像头初始化完成 58 wire wr_en ; //sdram_ctrl模块写使能 59 wire [15:0] wr_data ; //sdram_ctrl模块写数据 60 wire rd_en ; //sdram_ctrl模块读使能 61 wire [15:0] rd_data ; //sdram_ctrl模块读数据 62 wire sdram_init_done ; //SDRAM初始化完成 63 wire [10:0] pixel_xpos_w ; //HDMI横坐标 64 wire [10:0] pixel_ypos_w ; //HDMI纵坐标 65 wire post_frame_vsync ; //处理后的场信号 66 wire post_frame_hsync ; //处理后的行信号 67 wire post_frame_de ; //处理后的数据使能 68 wire [15:0] post_rgb ; //处理后的数据 69 70 //***************************************************** 71 //** main code 72 //***************************************************** 73 74 assign rst_n = sys_rst_n & locked & locked_hdmi; 75 //系统初始化完成:SDRAM和摄像头都初始化完成 76 //避免了在SDRAM初始化过程中向里面写入数据 77 assign sys_init_done = sdram_init_done & cam_init_done; 78 //电源休眠模式选择 0:正常模式 1:电源休眠模式 79 assign cam_pwdn = 1'b0; 80 assign cam_rst_n = 1'b1; 81 82 //锁相环 83 pll u_pll( 84 .areset (~sys_rst_n), 85 .inclk0 (sys_clk), 86 .c0 (clk_100m), 87 .c1 (clk_100m_shift), 88 .c2 (clk_50m), 89 .locked (locked) 90 ); 91 92 pll_hdmi pll_hdmi_inst ( 93 .areset ( ~sys_rst_n ), 94 .inclk0 ( sys_clk ), 95 .c0 ( hdmi_clk ),//hdmi pixel clock 71Mhz 96 .c1 ( hdmi_clk_5 ),//hdmi pixel clock*5 355Mhz 97 .locked ( locked_hdmi ) 98 ); 99 100 //I2C配置模块 101 i2c_ov5640_rgb565_cfg u_i2c_cfg( 102 .clk (i2c_dri_clk), 103 .rst_n (rst_n ), 104 105 .i2c_exec (i2c_exec ), 106 .i2c_data (i2c_data ), 107 .i2c_rh_wl (i2c_rh_wl ), //I2C读写控制信号 108 .i2c_done (i2c_done ), 109 .i2c_data_r (i2c_data_r ), 110 111 .cmos_h_pixel (H_CMOS_DISP ), //CMOS水平方向像素个数 112 .cmos_v_pixel (V_CMOS_DISP ) , //CMOS垂直方向像素个数 113 .total_h_pixel (TOTAL_H_PIXEL), //水平总像素大小 114 .total_v_pixel (TOTAL_V_PIXEL), //垂直总像素大小 115 116 .init_done (cam_init_done) 117 ); 118 119 //I2C驱动模块 120 i2c_dri #( 121 .SLAVE_ADDR (SLAVE_ADDR ), //参数传递 122 .CLK_FREQ (CLK_FREQ ), 123 .I2C_FREQ (I2C_FREQ ) 124 ) 125 u_i2c_dr( 126 .clk (clk_50m ), 127 .rst_n (rst_n ), 128 129 .i2c_exec (i2c_exec ), 130 .bit_ctrl (BIT_CTRL ), 131 .i2c_rh_wl (i2c_rh_wl ), //固定为0,只用到了IIC驱动的写操作 132 .i2c_addr (i2c_data[23:8]), 133 .i2c_data_w (i2c_data[7:0] ), 134 .i2c_data_r (i2c_data_r ), 135 .i2c_done (i2c_done ), 136 .scl (cam_scl ), 137 .sda (cam_sda ), 138 .dri_clk (i2c_dri_clk ) //I2C操作时钟 139 ); 140 141 //CMOS图像数据采集模块 142 cmos_capture_data u_cmos_capture_data( //系统初始化完成之后再开始采集数据 143 .rst_n (rst_n & sys_init_done), 144 145 .cam_pclk (cam_pclk ), 146 .cam_vsync (cam_vsync), 147 .cam_href (cam_href ), 148 .cam_data (cam_data ), 149 150 .cmos_frame_vsync (cmos_frame_vsync), 151 .cmos_frame_href (cmos_frame_href), 152 .cmos_frame_valid (wr_en ), //数据有效使能信号 153 .cmos_frame_data (wr_data ) //有效数据 154 ); 155 156 //图像处理模块 157 vip u_vip( 158 //module clock 159 .clk (cam_pclk), // 时钟信号 160 .rst_n (rst_n ), // 复位信号(低有效) 161 //图像处理前的数据接口 162 .pre_frame_vsync (cmos_frame_vsync ), 163 .pre_frame_hsync (cmos_frame_href ), 164 .pre_frame_de (wr_en ), 165 .pre_rgb (wr_data), 166 .xpos (pixel_xpos_w ), 167 .ypos (pixel_ypos_w ), 168 //图像处理后的数据接口 169 .post_frame_vsync (post_frame_vsync ), // 场同步信号 170 .post_frame_hsync ( ), // 行同步信号 171 .post_frame_de (post_frame_de ), // 数据输入使能 172 .post_rgb (post_rgb) // RGB565颜色数据 173 174 ); 175 176 //SDRAM 控制器顶层模块,封装成FIFO接口 177 //SDRAM 控制器地址组成: {bank_addr[1:0],row_addr[12:0],col_addr[8:0]} 178 sdram_top u_sdram_top( 179 .ref_clk (clk_100m), //sdram 控制器参考时钟 180 .out_clk (clk_100m_shift), //用于输出的相位偏移时钟 181 .rst_n (rst_n), //系统复位 182 183 //用户写端口 184 .wr_clk (cam_pclk), //写端口FIFO: 写时钟 185 .wr_en (post_frame_de), //写端口FIFO: 写使能 186 .wr_data (post_rgb), //写端口FIFO: 写数据 187 188 .wr_min_addr (24'd0), //写SDRAM的起始地址 189 .wr_max_addr (V_CMOS_DISP*H_CMOS_DISP-1), //写SDRAM的结束地址 190 .wr_len (10'd512), //写SDRAM时的数据突发长度 191 .wr_load (~rst_n), //写端口复位: 复位写地址,清空写FIFO 192 193 //用户读端口 194 .rd_clk (hdmi_clk), //读端口FIFO: 读时钟 195 .rd_en (rd_en), //读端口FIFO: 读使能 196 .rd_data (rd_data), //读端口FIFO: 读数据 197 .rd_min_addr (24'd0), //读SDRAM的起始地址 198 .rd_max_addr (V_CMOS_DISP*H_CMOS_DISP-1), //读SDRAM的结束地址 199 .rd_len (10'd512), //从SDRAM中读数据时的突发长度 200 .rd_load (~rst_n), //读端口复位: 复位读地址,清空读FIFO 201 202 //用户控制端口 203 .sdram_read_valid (1'b1), //SDRAM 读使能 204 .sdram_pingpang_en (1'b1), //SDRAM 乒乓操作使能 205 .sdram_init_done (sdram_init_done), //SDRAM 初始化完成标志 206 207 //SDRAM 芯片接口 208 .sdram_clk (sdram_clk), //SDRAM 芯片时钟 209 .sdram_cke (sdram_cke), //SDRAM 时钟有效 210 .sdram_cs_n (sdram_cs_n), //SDRAM 片选 211 .sdram_ras_n (sdram_ras_n), //SDRAM 行有效 212 .sdram_cas_n (sdram_cas_n), //SDRAM 列有效 213 .sdram_we_n (sdram_we_n), //SDRAM 写有效 214 .sdram_ba (sdram_ba), //SDRAM Bank地址 215 .sdram_addr (sdram_addr), //SDRAM 行/列地址 216 .sdram_data (sdram_data), //SDRAM 数据 217 .sdram_dqm (sdram_dqm) //SDRAM 数据掩码 218 ); 219 220 //例化HDMI顶层模块 221 hdmi_top u_hdmi_top( 222 .hdmi_clk (hdmi_clk ), 223 .hdmi_clk_5 (hdmi_clk_5 ), 224 .rst_n (rst_n ), 225 226 .rd_data (rd_data ), 227 .rd_en (rd_en ), 228 .h_disp (), 229 .v_disp (), 230 .pixel_xpos (pixel_xpos_w), 231 .pixel_ypos (pixel_ypos_w), 232 .video_vs (), 233 .tmds_clk_p (tmds_clk_p ), 234 .tmds_clk_n (tmds_clk_n ), 235 .tmds_data_p (tmds_data_p), 236 .tmds_data_n (tmds_data_n) 237 ); 238 239 endmodule

FPGA顶层模块(ov5640_hdmi_yuv)例化了以下八个模块:时钟模块1(pll)、时钟模块2(pll_hdmi)、I2C驱动模块(i2c_dri)、I2C配置模块(i2c_ov5640_rgb565_cfg)、图像采集模块(cmos_capture_data)、图像处理模块(vip)、SDRAM控制模块(sdram_top)和HDMI顶层模块(hdmi_top)。 时钟模块:时钟模块通过调用PLL IP核实现,共输出5个时钟,频率分别为100M时钟、100M偏移-75度时钟、50M时钟、71Mhz时钟和355M时钟(HDMI像素时钟的5倍频)。其中pll 产生了50M时钟、100M时钟和100M偏移-75度时钟,pll_hdmi 产生了71Mhz时钟和355M时钟,这里之所以用两个锁相环是因为HDMI所用的时钟71Mhz与SDRAM控制模块使用的100M时钟不是整数倍,使用一个锁相环不符合设计要求。100Mhz时钟作为SDRAM控制模块的驱动时钟,100M偏移-75度时钟用来输出给外部SDRAM芯片使用,50Mhz时钟作为I2C驱动模块的驱动时钟,71Mhz时钟和355M时钟(HDMI像素时钟的5倍频)负责驱动HDMI顶层模块。 I2C驱动模块(i2c_dri):I2C驱动模块负责驱动OV5640 SCCB接口总线,用户可根据该模块提供的用户接口可以很方便的对OV5640的寄存器进行配置,该模块和“EEPROM读写实验”章节中用到的I2C驱动模块为同一个模块,有关该模块的详细介绍请大家参考“EEPROM读写实验”章节。 I2C配置模块(i2c_ov5640_rgb565_cfg):I2C配置模块的驱动时钟是由I2C驱动模块输出的时钟提供的,这样方便了I2C驱动模块和I2C配置模块之间的数据交互。该模块寄存需要配置的寄存器地址、数据以及控制初始化的开始与结束,同时该模块输出OV5640的寄存器地址和数据以及控制I2C驱动模块开始执行的控制信号,直接连接到I2C驱动模块的用户接口,从而完成对OV5640传感器的初始化。 图像采集模块(cmos_capture_data):摄像头采集模块在像素时钟的驱动下将传感器输出的场同步信号、行同步信号以及8位数据转换成写使能信号和16位写数据信号,完成对OV5640传感器图像的采集。OV5640和OV7725图像输出时序非常相似,有关该模块的详细介绍请大家参考“OV7725摄像头LCD显示实验”章节。 图像处理模块(vip):对采集后的图像数据进行处理,并将处理后的数据存入SDRAM控制模块。 SDRAM控制模块(sdram_top):SDRAM读写控制器模块负责驱动SDRAM片外存储器,缓存图像传感器输出的图像数据。有关该模块的详细介绍请大家参考“SDRAM读写测试实验”章节。 HDMI顶层模块(hdmi_top):HDMI顶层模块负责驱动HDMI显示器的驱动信号的输出,同时为其他模块提供显示器参数、场同步信号和数据请求信号。关HDMI顶层模块的详细介绍请大家参考“OV5640摄像头HDMI显示实验”章节。 图像处理模块负责图像数据的格式转换,代码如下:

1 module vip( 2 //module clock 3 input clk , // 时钟信号 4 input rst_n , // 复位信号(低有效) 5 6 //图像处理前的数据接口 7 input pre_frame_vsync, 8 input pre_frame_hsync, 9 input pre_frame_de , 10 input [15:0] pre_rgb , 11 input [10:0] xpos , 12 input [10:0] ypos , 13 14 //图像处理后的数据接口 15 output post_frame_vsync, // 场同步信号 16 output post_frame_hsync, // 行同步信号 17 output post_frame_de , // 数据输入使能 18 output [15:0] post_rgb // RGB565颜色数据 19 ); 20 21 //wire define 22 wire [ 7:0] img_y; 23 24 //***************************************************** 25 //** main code 26 //***************************************************** 27 28 assign post_rgb = {img_y[7:3],img_y[7:2],img_y[7:3]}; 29 30 //RGB转YCbCr模块 31 rgb2ycbcr u_rgb2ycbcr( 32 //module clock 33 .clk (clk ), // 时钟信号 34 .rst_n (rst_n ), // 复位信号(低有效) 35 //图像处理前的数据接口 36 .pre_frame_vsync (pre_frame_vsync), // vsync信号 37 .pre_frame_hsync (pre_frame_hsync), // href信号 38 .pre_frame_de (pre_frame_de ), // data enable信号 39 .img_red (pre_rgb[15:11] ), 40 .img_green (pre_rgb[10:5 ] ), 41 .img_blue (pre_rgb[ 4:0 ] ), 42 //图像处理后的数据接口 43 .post_frame_vsync(post_frame_vsync), // vsync信号 44 .post_frame_hsync(post_frame_hsync), // href信号 45 .post_frame_de (post_frame_de), // data enable信号 46 .img_y (img_y), 47 .img_cb (), 48 .img_cr () 49 ); 50 51 endmodule

代码的第28行表示对转换后的8bit灰度数据进行位拼接,形成16bit的RGB565格式的数据输出。 代码的第31行至49行是对灰度转换模块的例化,在该模块以摄像头采集的16位RGB565红、绿、蓝三原色数据作为输入数据,通过算法实现RGB到YCbCr的转换,并输出8位灰度数据,并输出数据输出使能信号。 灰度转换模块负责将RGB565格式的图像数据转换为YCbCr格式数据,代码如下:

1 module rgb2ycbcr 2 ( 3 //module clock 4 input clk , // 模块驱动时钟 5 input rst_n , // 复位信号 6 7 //图像处理前的数据接口 8 input pre_frame_vsync , // vsync信号 9 input pre_frame_hsync , // hsync信号 10 input pre_frame_de , // data enable信号 11 input [4:0] img_red , // 输入图像数据R 12 input [5:0] img_green , // 输入图像数据G 13 input [4:0] img_blue , // 输入图像数据B 14 15 //图像处理后的数据接口 16 output post_frame_vsync, // vsync信号 17 output post_frame_hsync, // hsync信号 18 output post_frame_de , // data enable信号 19 output [7:0] img_y , // 输出图像Y数据 20 output [7:0] img_cb , // 输出图像Cb数据 21 output [7:0] img_cr // 输出图像Cr数据 22 ); 23 24 //reg define 25 reg [15:0] rgb_r_m0, rgb_r_m1, rgb_r_m2; 26 reg [15:0] rgb_g_m0, rgb_g_m1, rgb_g_m2; 27 reg [15:0] rgb_b_m0, rgb_b_m1, rgb_b_m2; 28 reg [15:0] img_y0 ; 29 reg [15:0] img_cb0; 30 reg [15:0] img_cr0; 31 reg [ 7:0] img_y1 ; 32 reg [ 7:0] img_cb1; 33 reg [ 7:0] img_cr1; 34 reg [ 2:0] pre_frame_vsync_d; 35 reg [ 2:0] pre_frame_hsync_d; 36 reg [ 2:0] pre_frame_de_d ; 37 38 //wire define 39 wire [ 7:0] rgb888_r; 40 wire [ 7:0] rgb888_g; 41 wire [ 7:0] rgb888_b; 42 43 //***************************************************** 44 //** main code 45 //***************************************************** 46 47 //RGB565 to RGB 888 48 assign rgb888_r = {img_red , img_red[4:2] }; 49 assign rgb888_g = {img_green, img_green[5:4]}; 50 assign rgb888_b = {img_blue , img_blue[4:2] }; 51 //同步输出数据接口信号 52 assign post_frame_vsync = pre_frame_vsync_d[2] ; 53 assign post_frame_hsync = pre_frame_hsync_d[2] ; 54 assign post_frame_de = pre_frame_de_d[2] ; 55 assign img_y = post_frame_hsync ? img_y1 : 8'd0; 56 assign img_cb = post_frame_hsync ? img_cb1: 8'd0; 57 assign img_cr = post_frame_hsync ? img_cr1: 8'd0; 58 59 //-------------------------------------------- 60 //RGB 888 to YCbCr 61 62 /******************************************************** 63 RGB888 to YCbCr 64 Y = 0.299R +0.587G + 0.114B 65 Cb = 0.568(B-Y) + 128 = -0.172R-0.339G + 0.511B + 128 66 CR = 0.713(R-Y) + 128 = 0.511R-0.428G -0.083B + 128 67 68 Y = (77 *R + 150*G + 29 *B)>>8 69 Cb = (-43*R - 85 *G + 128*B)>>8 + 128 70 Cr = (128*R - 107*G - 21 *B)>>8 + 128 71 72 Y = (77 *R + 150*G + 29 *B )>>8 73 Cb = (-43*R - 85 *G + 128*B + 32768)>>8 74 Cr = (128*R - 107*G - 21 *B + 32768)>>8 75 *********************************************************/ 76 77 //step1 pipeline mult 78 always @(posedge clk or negedge rst_n) begin 79 if(!rst_n) begin 80 rgb_r_m0


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有