FPGA + 图像处理 (二) RGB转YUV色域、转灰度图及仿真

前言

具体关于色域的知识就不细说了,简单来讲YUV中Y通道可以理解为就是图像的灰度图,因此,将RGB转化为YUV是求彩色图的灰度直方图、进行二值化操作等的基础。

HDMI时序生成模块

这里先介绍一下仿真时用于生成HDMI时序,用这个时序来向数据处理模块输入数据,一是可以做到通过同步信号简化对图像数据的管理,二是可以让测试的数据处理模块更方便的适配用HDMI显示的图像处理工程。

 HDMI的单帧时序如图,具体时序知识不细说,下面代码实现的功能简单理解就是当data_req(数据请求)信号拉高时,开始向模块内输入图像数据,连续输入一行的数据,然后直接输出图像数据,当输出数据时拉高hdmi_de(数据有效)信号。因为本次是单帧的图像,所以hdmi_vs(场同步)信号以及hdmi_hs(行同步)信号是用不到的。

要注意不同尺寸的图像对应的参数不同,本模块适用于1280*720像素的图像

module hdmi_tim_gen(input           	clk			,input           	rst_n	    ,input   	[23:0]  data_in		,output          	hdmi_hs		,     //行同步信号output          	hdmi_vs		,     //场同步信号output          	hdmi_de		,     //数据使能output  	[23:0]  hdmi_data	,     //图像数据output		reg		data_req 	
);//1280*720 分辨率时序参数
parameter  H_SYNC   =  11'd40;  
parameter  H_BACK   =  11'd220; 
parameter  H_DISP   =  11'd1280;
parameter  H_FRONT  =  11'd110; 
parameter  H_TOTAL  =  11'd1650;parameter  V_SYNC   =  11'd5;   
parameter  V_BACK   =  11'd20;  
parameter  V_DISP   =  11'd720; 
parameter  V_FRONT  =  11'd5;   
parameter  V_TOTAL  =  11'd750; reg  [11:0] 	cnt_h;
reg  [11:0] 	cnt_v;reg [10:0] pixel_xpos;
reg [10:0] pixel_ypos;assign hdmi_de  = data_req;
assign hdmi_hs  = ( cnt_h < H_SYNC ) ? 1'b0 : 1'b1; 
assign hdmi_vs  = ( cnt_v < V_SYNC ) ? 1'b0 : 1'b1; //图像数据输出
assign hdmi_data = hdmi_de ? data_in : 24'd0;//请求像素点数据输入
always @(posedge clk or negedge rst_n) beginif(!rst_n)data_req <= 1'b0;else if(((cnt_h >= H_SYNC + H_BACK - 2'd2) && (cnt_h < H_SYNC + H_BACK + H_DISP - 2'd2))&& ((cnt_v >= V_SYNC + V_BACK) && (cnt_v < V_SYNC + V_BACK+V_DISP)))data_req <= 1'b1;elsedata_req <= 1'b0;
end//像素点x坐标
always@ (posedge clk or negedge rst_n) beginif(!rst_n)pixel_xpos <= 11'd0;else if(data_req)pixel_xpos <= cnt_h + 2'd2 - H_SYNC - H_BACK ;else pixel_xpos <= 11'd0;
end//像素点y坐标	
always@ (posedge clk or negedge rst_n) beginif(!rst_n)pixel_ypos <= 11'd0;else if((cnt_v >= (V_SYNC + V_BACK)) && (cnt_v < (V_SYNC + V_BACK + V_DISP)))pixel_ypos <= cnt_v + 1'b1 - (V_SYNC + V_BACK) ;else pixel_ypos <= 11'd0;
end//行计数器对像素时钟计数
always @(posedge clk or negedge rst_n) beginif (!rst_n)cnt_h <= 11'd0;else beginif(cnt_h < H_TOTAL - 1'b1)cnt_h <= cnt_h + 1'b1;else cnt_h <= 11'd0;end
end//场计数器对行计数
always @(posedge clk or negedge rst_n) beginif (!rst_n)cnt_v <= 11'd0;else if(cnt_h == H_TOTAL - 1'b1) beginif(cnt_v < V_TOTAL - 1'b1)cnt_v <= cnt_v + 1'b1;else cnt_v <= 11'd0;end
endendmodule

RGB转YUV模块

前面也说过了,YUV中的Y通道就是图像的灰度图,以此,单独将Y通道输出就可以得到彩色图像的灰度图

module rgb2yuv
(input               clk          	,  input               rst_n        	,  input               vs_i    		,  input               de_i    		,  input       [23:0]  data_i     		,  output              vs_o  			,  output              de_o  			,  output      [23:0]  data_yuv       	, output      [7:0]   data_gray       	);//YUV中Y指明亮度,也就是灰度值,(U,V)指色度,即饱和度和色调reg  [15:0]   rgb_r_m0, rgb_r_m1, rgb_r_m2;
reg  [15:0]   rgb_g_m0, rgb_g_m1, rgb_g_m2;
reg  [15:0]   rgb_b_m0, rgb_b_m1, rgb_b_m2;
reg  [15:0]   img_y0 ;
reg  [15:0]   img_cb0;
reg  [15:0]   img_cr0;
reg  [ 7:0]   img_y1 ;
reg  [ 7:0]   img_cb1;
reg  [ 7:0]   img_cr1;
reg  [ 2:0]   vs_i_d;
reg  [ 2:0]   de_i_d   ;//wire define
wire [ 7:0]   rgb888_r;
wire [ 7:0]   rgb888_g;
wire [ 7:0]   rgb888_b;
wire [ 7:0]   img_y;
wire [ 7:0]   img_cb;
wire [ 7:0]   img_cr;assign rgb888_r         = data_i[23:16];
assign rgb888_g         = data_i[15:8];
assign rgb888_b         = data_i[7:0];
//同步输出数据接口信号
assign vs_o   		= vs_i_d[2]      	;
assign de_o 		= de_i_d[2]         ;
assign img_y		= img_y1 			;
assign img_cb		= img_cb1			;
assign img_cr		= img_cr1			;
assign data_yuv		= {img_y,img_cb,img_cr};		
assign data_gray	= img_y;
/********************************************************RGB888 to YCbCrY  = 0.299R +0.587G + 0.114BCb = 0.568(B-Y) + 128 = -0.172R-0.339G + 0.511B + 128CR = 0.713(R-Y) + 128 = 0.511R-0.428G -0.083B + 128Y  = (77 *R    +    150*G    +    29 *B)>>8Cb = (-43*R    -    85 *G    +    128*B)>>8 + 128Cr = (128*R    -    107*G    -    21 *B)>>8 + 128Y  = (77 *R    +    150*G    +    29 *B        )>>8Cb = (-43*R    -    85 *G    +    128*B + 32768)>>8Cr = (128*R    -    107*G    -    21 *B + 32768)>>8
*********************************************************///step1 计算括号内的各乘法项
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginrgb_r_m0 <= 16'd0;rgb_r_m1 <= 16'd0;rgb_r_m2 <= 16'd0;rgb_g_m0 <= 16'd0;rgb_g_m1 <= 16'd0;rgb_g_m2 <= 16'd0;rgb_b_m0 <= 16'd0;rgb_b_m1 <= 16'd0;rgb_b_m2 <= 16'd0;endelse beginrgb_r_m0 <= rgb888_r * 8'd77 ;rgb_r_m1 <= rgb888_r * 8'd43 ;rgb_r_m2 <= rgb888_r * 8'd128;rgb_g_m0 <= rgb888_g * 8'd150;rgb_g_m1 <= rgb888_g * 8'd85 ;rgb_g_m2 <= rgb888_g * 8'd107;rgb_b_m0 <= rgb888_b * 8'd29 ;rgb_b_m1 <= rgb888_b * 8'd128;rgb_b_m2 <= rgb888_b * 8'd21 ;end
end//step2 括号内各项相加
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginimg_y0  <= 16'd0;img_cb0 <= 16'd0;img_cr0 <= 16'd0;endelse beginimg_y0  <= rgb_r_m0 + rgb_g_m0 + rgb_b_m0;img_cb0 <= rgb_b_m1 - rgb_r_m1 - rgb_g_m1 + 16'd32768;img_cr0 <= rgb_r_m2 - rgb_g_m2 - rgb_b_m2 + 16'd32768;endend//step3 括号内计算的数据右移8位
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginimg_y1  <= 8'd0;img_cb1 <= 8'd0;img_cr1 <= 8'd0;endelse beginimg_y1  <= img_y0 [15:8];img_cb1 <= img_cb0[15:8];img_cr1 <= img_cr0[15:8];end
end//延时3拍以同步数据信号
always@(posedge clk or negedge rst_n) beginif(!rst_n) beginvs_i_d 		<= 3'd0;de_i_d    	<= 3'd0;endelse beginvs_i_d 		<= {vs_i_d[1:0], vs_i};de_i_d    	<= {de_i_d[1:0], de_i};end
endendmodule

仿真TB文件

注意文件读取和保存的路径

关于一些仿真中用的系统命令可以参考我的testbench中一些常用的系统命令-CSDN博客这篇

本次仿真读取的是txt文件,需要通过matlab或者python将图像转化为txt,具体实现程序可看本人主页文章

`timescale 1ns/1nsmodule pic_tb();//hdmi_tim_gen模块接口reg             clk,rst_n				;
reg [23:0]      data_in					;wire      		hdmi_hs,hdmi_vs,hdmi_de ;
wire [23:0]  	hdmi_data  				;
wire 			data_req   				;//rgb2yuv模块接口reg  			vs_i,de_i	    ;
wire 			vs_o,de_o	    ;
wire [23:0] 	data_yuv		;
wire [7:0]        data_gray    ;
//延迟1clk,与data同步
always @(posedge clk)beginvs_i <= hdmi_vs;de_i <= hdmi_de;
end initial beginclk = 1;rst_n = 0;#20 rst_n = 1;
end
always #10 clk = ~clk;reg [23:0] img[0:1280*720-1];
reg [31:0] addr;
initial begin$readmemh("D:/pic/img2txt.txt",img);
endalways @(posedge clk or negedge rst_n)beginif(!rst_n)beginaddr <= 0		;data_in <= 0	;endelse if(data_req)begindata_in	 <= img[addr];addr	 <= addr + 1;if(addr == (1280*720-1))addr <= 0;end
endinteger file_out_yuv;
integer file_out_gray;
reg [31:0] out_addr;
initial beginfile_out_yuv = $fopen("D:/pic/fileout_yuv.txt","w");file_out_gray = $fopen("D:/pic/fileout_gray.txt","w");
endalways @(posedge clk or negedge rst_n)beginif(!rst_n)beginout_addr <= 0;endelse if(out_addr == 1280*720)begin$display("task finish \n");$fclose(file_out_yuv);$fclose(file_out_gray);$finish;endelse if(de_o)beginout_addr <= out_addr + 1;$fwrite(file_out_yuv,"%x\n",data_yuv);$fwrite(file_out_gray,"%x\n",data_gray);end
end//例化hdmi_tim_gen模块hdmi_tim_gen u_hdmi_tim_gen(.clk		 	(clk),	.rst_n	  		(rst_n),//input.data_in	 	(data_in),//output.hdmi_hs	 	(hdmi_hs),.hdmi_vs	 	(hdmi_vs),.hdmi_de	 	(hdmi_de),.hdmi_data 		(hdmi_data),.data_req  		(data_req)
);//例化rgb2yuv模块rgb2yuv u_rgb2yuv
(.clk         (clk),  	.rst_n       (rst_n),  		.vs_i    	(vs_i),  	.de_i    	(de_i),  	.data_i     (hdmi_data),.vs_o  		(vs_o),  	.de_o  		(de_o),  	.data_yuv     (data_yuv),.data_gray    (data_gray)	
);endmodule

运行与结果

工程层级

直接在vivado内部仿真即可

 仿真结果

可以看到这部分符合HDMI时序波形

原图

YUV格式

灰度图

结语

本次实验比较简单,直接拷贝到工程,路径也没有问题应该可以直接运行,不过还是把工程附上,供大家免费下载,共同学习。 

【免费】RGB图像转YUV及灰度图FPGA实现工程资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/788397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自贡市第一人民医院:超融合与 SKS 承载 HIS 等核心业务应用,加速国产化与云原生转型

自贡市第一人民医院始建于 1908 年&#xff0c;现已发展成为集医疗、科研、教学、预防、公共卫生应急处置为一体的三级甲等综合公立医院。医院建有“全国综合医院中医药工作示范单位”等 8 个国家级基地&#xff0c;建成高级卒中中心、胸痛中心等 6 个国家级中心。医院日门诊量…

【Docker】搭建便捷的Docker容器管理工具 - dockerCopilot

【Docker】搭建便捷的Docker容器管理工具 - dockerCopilot 前言 本教程基于绿联的NAS设备DX4600 Pro的docker功能进行搭建。前面有介绍过OneKey&#xff0c;而dockerCopilot便是OneKey的升级版&#xff0c;作者对其进行了重新命名&#xff0c;并且对界和功能都进行了全面的优…

负载均衡集群

一、集群的基本原理 集群&#xff1a;数据内容是一致的&#xff0c;集群可以被替代 分布式&#xff1a;各司其职&#xff0c;每台服务器存储自己独有的数据&#xff0c;对外作为单点被访问是访问整体的数据&#xff1b; 分布式是不能被替代的&#xff1b;分布式分为MFS、GFS、…

结构体内存对齐和位段(重点)!!!

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 点击主页&#xff1a;optimistic_chen和专栏&#xff1a;c语言&#xff0c; 创作不易&#xff0c;大佬们点赞鼓…

数据结构栈和堆列

目录 栈&#xff1a; 栈的概念&#xff1a; 栈的实现&#xff1a; 栈接口的实现&#xff1a; 1.初始化栈&#xff1a; 2.入栈&#xff1a; 3.出栈&#xff1a; 4. 获取栈顶元素&#xff1a; 5.获取栈中有效数据的个数&#xff1a; 6.检测栈是否为空&#xff0c;如果为…

Java代码示例:演示多态特性及子类方法重写(day17)

java代码里面体现多态的特点&#xff1a; 第一步创建一个父类father&#xff0c; 然后创建子类subclasses&#xff0c; 最后创建一个DemoMulti, 上面的父类特有的方法不是私有的&#xff0c;因此子类能够继承。 新建一个父类方法Father 创建子类subclasses 在下面的代码中…

LabVIEW深度学习

目录 一、配置环境1.1、显卡选择1.2、下载显卡驱动1.3、下载并安装Anaconda1.4、配置Anaconda软件包下载服务器1.5、配置虚拟环境tf_gpu1.6、安装vscode1.7、安装tensorflow1.8、下载安装Git1.9、安装TensorFlow Object Detection API框架1.10、安装依赖的python软件包1.11、配…

Python 简单使用 RabbitMQ

一、安装 pip install pika 二、推送消息到队列中 执行pythone方法 import pika import time# 用户名和密码 user_info pika.PlainCredentials(admin,admin)# 连接服务器上的rabbitMQ服务 connection pika.BlockingConnection(pika.ConnectionParameters(127.0.0.1, 5672,…

在开源的基础上构建 AI 需要一种全新的应用程序安全方法

人工智能已经从科幻小说中涌现出来&#xff0c;进入了我们的日常生活。 在开源软件&#xff08;OSS&#xff09;模型的支持下&#xff0c;人工智能革命正在加速。这些模型是专为开发 AI 而制作的复杂开源代码包&#xff0c;使组织能够高效、大规模地部署 AI 模型。 虽然大多数…

StreamingT2V文本生成视频多模态大模型,即将开源!

1、前言 Picsart人工智能研究所、德克萨斯大学和SHI实验室的研究人员联合推出了StreamingT2V视频模型。通过文本就能直接生成2分钟、1分钟等不同时间&#xff0c;动作一致、连贯、没有卡顿的高质量视频。 虽然StreamingT2V在视频质量、多元化等还无法与Sora媲美&#xff0c;但…

【C++第二阶段】文件操作

以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 文件操作文件写入流程简单的demo写操作 文件读流程二进制写文件二进制读文件 文件操作 文件写入流程 写文件包括以下几个步骤 1.包含头文件 2.创建流对象 3.打开文件&#xff0…

大数据学习第十二天(hadoop概念)

1、服务器之间数据文件传递 1&#xff09;服务器之间传递数据&#xff0c;依赖ssh协议 2&#xff09;http协议是web网站之间的通讯协议&#xff0c;用户可已通过http网址访问到对应网站数据 3&#xff09;ssh协议是服务器之间&#xff0c;或windos和服务器之间传递的数据的协议…

IP SSL的应用与安装

IP SSL&#xff0c;即互联网协议安全套接字层&#xff0c;它是一种为网络通信提供安全及数据完整性的安全协议。在网络传输过程中&#xff0c;IP SSL可以对数据进行加密&#xff0c;这样即便数据在传输途中被截取&#xff0c;没有相应的解密密钥也无法解读内容。这一过程如同将…

合并两个单链表

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 但行前路&#xff0c;不负韶华&#…

redis的键值基本操作

设置数据 首先设置键值对 删除age&#xff0c;会得到nil&#xff0c;表示这个键已经被删除掉了 判断age键还在不在 查找所有键 查找所有以me结尾的键 删除所有键 redis的键和值都是二进制存储的&#xff0c;所以默认不支持中文。 但是&#xff0c;我们重新登录客户端&#xff…

Unity自定义框架(1)-----------单例模式

前言&#xff1a; Unity作为一款强大的游戏开发引擎&#xff0c;其基础框架的设计对于项目的结构和性能有着重要的影响。其中&#xff0c;单例模式是一种常用的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 什么是单例模式&#xff1f…

基于深度学习的机场航拍小目标检测系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要&#xff1a;在本博客中介绍了基于YOLOv8/v7/v6/v5的机场航拍小目标检测系统。该系统的核心技术是采用YOLOv8&#xff0c;并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;从而进行性能指标的综合对比。我们详细介绍了国内外在机场航拍小目标检测领域的研究现状、数据集处理…

分布式唯一ID 雪花算法

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 算法具体介绍 雪花算法是 64 位 的二进制&#xff0c;一共包含了四部分&#xff1a; 1位是符号位&#xff0c;也就是最高位&#xff0c;…

大数据实验一,Hadoop安装及使用

目录 一&#xff0e;实验内容 二&#xff0e;实验目的 三&#xff0e;实验过程截图及说明 1、安装SSH&#xff0c;并配置SSH无密码登录 2、配置java环境 3.Hadoop的安装与配置 4、修改四个配置文件&#xff1a; 5、格式化HDFS的NameNode&#xff1a; 6、启动Hadoop 7、…

如何使用极狐GitLab 启用自动备份功能

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了如何极狐GitLab 自…