1-FPGA硬件加速-YUV_YCbCr

这是对《基于Matlab与FPGA的图像处理教程》的学习笔记,代码和内容摘取自书中。
心得: 使用FPGA进行硬件加速的重点是消除或者减少浮点数运算,转换为定点运算,然后通过pipeline流水设计转为并行实现加速。

原理和方法

RGB与(YUV/YCbCr444)之间的原始公式(基于生物仿真学(Biometric)实验结果的),使用摄像头或者其他传感器进行转换的时候应先了解转换公式(参数会有不同,否则会导致偏色),下面是常用的计算公式。
image.png
image.png
公式放大256倍(也就是向高位移8位)得到参数
然后忽略小数(fpga中消耗资源较大)进行运算
运算完毕后移位回来
Y = ( R76 + G150 + B*29) >>8
Cb = (-R43 - G84 + B*128 + 32768) >>8
Cr = ( R128 - G107 - B*20 + 32768) >>8

Matlab程序

clc;% -------------------------------------------------------------------------
% Read PC image to Matlab
IMG1 = imread('../../0_images/Scart.jpg');    % 读取jpg图像
h = size(IMG1,1);         % 读取图像高度
w = size(IMG1,2);         % 读取图像宽度
subplot(221);imshow(IMG1);title('RGB Image');% -------------------------------------------------------------------------
% Relized by user logic
% Y = ( R*76 + G*150 + B*29) >>8
% Cb = (-R*43 - G*84 + B*128 + 32768) >>8
% Cr = ( R*128 - G*107 - B*20  + 32768) >>8
IMG1 = double(IMG1);
IMG_YCbCr = zeros(h,w,3);
for i = 1 : hfor j = 1 : wIMG_YCbCr(i,j, 1) = bitshift(( IMG1(i,j,1)*76 + IMG1(i,j,2)*150 + IMG1(i,j,3)*29),-8);IMG_YCbCr(i,j,2) = bitshift((-IMG1(i,j,1)*43 - IMG1(i,j,2)*84 + IMG1(i,j,3)*128 + 32768),-8);IMG_YCbCr(i,j,3) = bitshift(( IMG1(i,j,1)*128 - IMG1(i,j,2)*107 - IMG1(i,j,3)*20 + 32768),-8);end
end% -------------------------------------------------------------------------
% Display Y Cb Cr Channel
IMG_YCbCr = uint8(IMG_YCbCr);
subplot(222); imshow(IMG_YCbCr(:,:,1));  title('Y Channel');
subplot(223); imshow(IMG_YCbCr(:,:,2));  title('Cb Channel');
subplot(224); imshow(IMG_YCbCr(:,:,3));  title('Cr Channel');

image.png

Verilog程序

里需要注意的是pipeline,在FPGA中把这套公式拆解成了三个step。
第一步是乘积,会延时1个clk。
第二步是累加,会延时1个clk。
第三部是移位,会延时1个clk。
综上所述,需要使用3个clk的延时来实现pipeline。

`timescale 1ns/1ns
module VIP_RGB888_YCbCr444
(//global clockinput               clk,                //cmos video pixel clockinput               rst_n,              //global reset//Image data prepred to be processedinput               per_img_vsync,      //Prepared Image data vsync valid signalinput               per_img_href,       //Prepared Image data href vaild signalinput       [7:0]   per_img_red,        //Prepared Image red data to be processedinput       [7:0]   per_img_green,      //Prepared Image green data to be processedinput       [7:0]   per_img_blue,       //Prepared Image blue data to be processed//Image data has been processedoutput              post_img_vsync,     //Processed Image data vsync valid signaloutput              post_img_href,      //Processed Image data href vaild signaloutput      [7:0]   post_img_Y,         //Processed Image brightness outputoutput      [7:0]   post_img_Cb,        //Processed Image blue shading outputoutput      [7:0]   post_img_Cr         //Processed Image red shading output
);//--------------------------------------------
/*********************************************
//Refer to full/pc range YCbCr formatY   =  R*0.299 + G*0.587 + B*0.114Cb  = -R*0.169 - G*0.331 + B*0.5   + 128Cr  =  R*0.5   - G*0.419 - B*0.081 + 128
--->      Y   = (76 *R + 150*G + 29 *B)>>8Cb  = (-43*R - 84 *G + 128*B + 32768)>>8Cr  = (128*R - 107*G - 20 *B + 32768)>>8
**********************************************/
//Step 1
reg [15:0]  img_red_r0,   img_red_r1,   img_red_r2; 
reg [15:0]  img_green_r0, img_green_r1, img_green_r2; 
reg [15:0]  img_blue_r0,  img_blue_r1,  img_blue_r2; 
always@(posedge clk)
beginimg_red_r0   <= per_img_red   * 8'd76;img_red_r1   <= per_img_red   * 8'd43;  img_red_r2   <= per_img_red   * 8'd128;img_green_r0 <= per_img_green * 8'd150;img_green_r1 <= per_img_green * 8'd84;img_green_r2 <= per_img_green * 8'd107;img_blue_r0  <= per_img_blue  * 8'd29;img_blue_r1  <= per_img_blue  * 8'd128;img_blue_r2  <= per_img_blue  * 8'd20;
end//--------------------------------------------------
//Step 2
reg [15:0]  img_Y_r0;   
reg [15:0]  img_Cb_r0; 
reg [15:0]  img_Cr_r0; 
always@(posedge clk)
beginimg_Y_r0  <= img_red_r0  + img_green_r0 + img_blue_r0;img_Cb_r0 <= img_blue_r1 - img_red_r1   - img_green_r1 +  16'd32768;img_Cr_r0 <= img_red_r2  - img_green_r2 - img_blue_r2  +  16'd32768;
end//--------------------------------------------------
//Step 3
reg [7:0] img_Y_r1; 
reg [7:0] img_Cb_r1; 
reg [7:0] img_Cr_r1; 
always@(posedge clk)
beginimg_Y_r1  <= img_Y_r0[15:8];img_Cb_r1 <= img_Cb_r0[15:8];img_Cr_r1 <= img_Cr_r0[15:8]; 
end//------------------------------------------
//lag 3 clocks signal sync  
reg [2:0] per_img_vsync_r;
reg [2:0] per_img_href_r;   
always@(posedge clk or negedge rst_n)
beginif(!rst_n)beginper_img_vsync_r <= 0;per_img_href_r <= 0;endelsebeginper_img_vsync_r <=  {per_img_vsync_r[1:0],  per_img_vsync};per_img_href_r  <=  {per_img_href_r[1:0],   per_img_href};end
end
assign  post_img_vsync = per_img_vsync_r[2];
assign  post_img_href  = per_img_href_r[2];
assign  post_img_Y     = post_img_href ? img_Y_r1 : 8'd0;
assign  post_img_Cb    = post_img_href ? img_Cb_r1: 8'd0;
assign  post_img_Cr    = post_img_href ? img_Cr_r1: 8'd0;endmodule

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

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

相关文章

【Spring面试】四、Bean的生命周期、循环依赖、BeanDefinition

文章目录 Q1、Bean有哪些生命周期回调方法&#xff1f;有哪几种实现方式&#xff1f;Q2、Spring在加载过程中Bean有哪几种形态Q3、解释下Spring框架中Bean的生命周期Q4、Spring是如何解决Bean的循环依赖的Q5、Spring是如何帮我们在并发下避免获取不完整的Bean的&#xff1f;Q6、…

基于springboot+vue的大学生智能消费记账系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

【电源专题】案例:异常样机为什么只在40%以下电量时与其他样机显示电量差异10%,40%以上电量差异却都在5%以内。

本案例发生在一个量产产品的测试中,因为产品带电池,所以需要测试产品对于电池电量显示的精确程度。产品使用的是最简单的开路电压查表法进行设计。 案例测试报告的问题在于不同样机之间电量百分比存在差异,大部分是在3%~4%之间。但在7.2V电压时,能够差异10%左右。 在文章:…

ESIM实战文本匹配

引言 今天我们来实现ESIM文本匹配&#xff0c;这是一个典型的交互型文本匹配方式&#xff0c;也是近期第一个测试集准确率超过80%的模型。 我们来看下是如何实现的。 模型架构 我们主要实现左边的ESIM网络。 从下往上看&#xff0c;分别是 输入编码层(Input Ecoding) 对前…

【Android知识笔记】进程通信(二)

一、Binder对象是如何跨进程传递的 binder传递有哪些方式?binder在传递过程中是怎么存储的?binder对象序列化和反序列化过程?binder对象传递过程中驱动层做了什么?总结 Binder 对象的跨进程传递主要靠 Parcel 的两个关键方法 writeStrongBinder() 和

nvm 一个nodejs版本管理工具

nvm 一个nodejs版本管理工具 NVM是什么 nvm全英文也叫node.js version management&#xff0c;是一个nodejs的版本管理工具。nvm和n都是node.js版本管理工具&#xff0c;为了解决node.js各种版本存在不兼容现象可以通过它可以安装和切换不同版本的node.js NVM下载 可在点此在…

vueshowpdf 移动端pdf文件预览

1、安装 npm install vueshowpdf -S2、参数 属性说明类型默认值v-model是否显示pdf--pdfurlpdf的文件地址String- scale 默认放大倍数 Number1.2 minscale 最小放大倍数 Number0.8 maxscale 最大放大倍数 Number2 3、事件 名称说明回调参数closepdf pdf关闭事件-pdferr文…

jmeter接口测试及详细步骤以及项目实战教程

在接口测试项目实战中&#xff0c;JMeter是一款非常强大和流行的自动化测试工具&#xff0c;它可以测试各种类型的应用程序&#xff0c;并通过采样和报告来识别性能瓶颈和API的问题。本文将为你提供一个基于实际项目的JMeter接口测试项目实战教程&#xff0c;指导你如何使用JMe…

潍坊科技学院图书馆藏《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书

潍坊科技学院图书馆藏《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书

金融行业的软件测试分析

随着金融行业的业务不断增加&#xff0c;金融交易模式的不断变化&#xff0c;金融机构对信息化的要求也越来越高&#xff0c;高质量的金融软件对于金融机构来说显得尤为重要。如何保证金融行业软件的质量&#xff0c;对金融行业软件的测试人员来说&#xff0c;也提出了更高的要…

Python进阶教学——多线程高级应用

目录 一、线程间的通讯机制 二、线程中的消息隔离机制 三、线程同步信号量 四、线程池和进程池 一、线程间的通讯机制 1、Queue消息队列 消息队列是在消息的传输过程中保存消息的容器&#xff0c;主要用于不同线程间任意类型数据的共享。消息队列最经典的用法就是消费者和…

Lua脚本

基本语法 注释 print(“script lua win”) – 单行注释 – [[ 多行注释 ]] – 标识符 类似于&#xff1a;java当中 变量、属性名、方法名。 以字母&#xff08;a-z,A-Z&#xff09;、下划线 开头&#xff0c;后面加上0个或多个 字母、下划线、数字。 不要用下划线大写字母…

变压器寿命预测(python代码,Logistic Regression模型预测效果一般,可以做对比实验)

1.数据来源官网&#xff1a;Data for: Root cause analysis improved with machine learning for failure analysis in power transformers - Mendeley Data 点Download All 10kb即可下载数据 2.下载下来后是这样 每一列的介绍&#xff1a; Hydrogen 氢气&#xff1b; Oxyge…

01目标检测-问题引入

目录 一、目标检测问题定义 二、目标检测过程中的常见的问题 三、目标检测VS图像分类区别 目标检测&#xff1a; 图像分类&#xff1a; 总结&#xff1a; 四、目标检测VS目标分割 目标分割&#xff1a; 目标检测是计算机视觉领域的一个重要任务&#xff0c;旨在从图像或…

DBeaver 下载、安装与数据库连接(MySQL)详细教程【超详细,保姆级教程!!!】

本文介绍DBeaver 下载、安装与数据库连接&#xff08;MySQL&#xff09;的详细教程 一、DBeaver 下载 官网下载地址&#xff1a;https://dbeaver.io/download/ 二、安装 1、双击下载的安装包&#xff0c;选择中文 2、点击下一步 3、点击我接受 4、如下勾选&#xff0c;…

Linux中使用Docker安装ElasticSearch7.10.x集群

使用Docker安装ElasticSearch7.10.x单节点请访问这里 一、集群环境说明 服务器IP地址192.168.137.1&#xff0c;192.168.137.2&#xff0c;192.168.137.3 二、前期准备 1. 拉取镜像 docker pull elasticsearch:7.10.12. 首先需要创建一个用于生成秘钥的初始容器&#xff0…

面试官:我们深入聊聊Java虚拟机吧

哈喽&#xff01;大家好&#xff0c;我是奇哥&#xff0c;一位专门给面试官添堵的职业面试员 文章持续更新&#xff0c;可以微信搜索【小奇JAVA面试】第一时间阅读&#xff0c;回复【资料】更有我为大家准备的福利哟&#xff01; 文章目录 前言面试Java虚拟机内存模型垃圾收集器…

Mac版本破解Typora,解决Mac安装软件的“已损坏,无法打开。 您应该将它移到废纸篓”问题

一、修改配置文件 首先去官网选择mac版本下载安装 typora下载 然后打开typora包内容找到 /Applications/Typora.app/Contents/Resources/TypeMark/ 编辑器打开上面文件夹&#xff0c;这里我拉到vscode 找到page-dist/static/js/Licen..如下图 输入 hasActivated"…

Docker--未完结

一.Docker是干什么的 在没亲自使用过之前&#xff0c;再多的术语也仅仅是抽象&#xff0c;只有写的人或者使用过的人能看懂。 所以&#xff0c;作为新手来说&#xff0c;只要知道Docker是用于部署项目就够了&#xff0c;下面展示如何用Docker部署项目及Docker常用命令。 二、…

ajax day4

1、promise链式调用 /*** 目标&#xff1a;把回调函数嵌套代码&#xff0c;改成Promise链式调用结构* 需求&#xff1a;获取默认第一个省&#xff0c;第一个市&#xff0c;第一个地区并展示在下拉菜单中*/let pname axios({url: http://hmajax.itheima.net/api/province,}).t…