1-FPGA硬件加速-YUV_YCbCr

news2024/11/15 3:44:03

这是对《基于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 : h
    for j = 1 : w
        IMG_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 clock
    input               clk,                //cmos video pixel clock
    input               rst_n,              //global reset

    //Image data prepred to be processed
    input               per_img_vsync,      //Prepared Image data vsync valid signal
    input               per_img_href,       //Prepared Image data href vaild signal
    input       [7:0]   per_img_red,        //Prepared Image red data to be processed
    input       [7:0]   per_img_green,      //Prepared Image green data to be processed
    input       [7:0]   per_img_blue,       //Prepared Image blue data to be processed
    
    //Image data has been processed
    output              post_img_vsync,     //Processed Image data vsync valid signal
    output              post_img_href,      //Processed Image data href vaild signal
    output      [7:0]   post_img_Y,         //Processed Image brightness output
    output      [7:0]   post_img_Cb,        //Processed Image blue shading output
    output      [7:0]   post_img_Cr         //Processed Image red shading output
);

//--------------------------------------------
/*********************************************
//Refer to full/pc range YCbCr format
    Y   =  R*0.299 + G*0.587 + B*0.114
    Cb  = -R*0.169 - G*0.331 + B*0.5   + 128
    Cr  =  R*0.5   - G*0.419 - B*0.081 + 128
--->      
    Y   = (76 *R + 150*G + 29 *B)>>8
    Cb  = (-43*R - 84 *G + 128*B + 32768)>>8
    Cr  = (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)
begin
    img_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)
begin
    img_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)
begin
    img_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)
begin
    if(!rst_n)
        begin
        per_img_vsync_r <= 0;
        per_img_href_r <= 0;
        end
    else
        begin
        per_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.coloradmin.cn/o/1013278.html

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

相关文章

微信小程序——常用组件的属性介绍

常用的组件内容标签 text 文本组件类似于HTML中的span标签&#xff0c;是一个行内元素rich-text 富文本标签支持把HTML字符串渲染为WXML结构 text标签的基本使用 通过text组件的selectable属性&#xff0c;实现长按选中文本内容的效果。只有text标签支持长按选中效果&#x…

爬虫代理在数据采集中的应用详解

随着互联网技术的不断发展&#xff0c;数据采集已经成为了各个行业中必不可少的一项工作。在数据采集的过程中&#xff0c;爬虫代理的应用越来越受到了重视。本文将详细介绍爬虫代理在数据采集中的应用。 什么是爬虫代理&#xff1f; 爬虫代理是指利用代理服务器来隐藏真实的IP…

string的使用和模拟实现

&#x1f493;博主个人主页:不是笨小孩&#x1f440; ⏩专栏分类:数据结构与算法&#x1f440; C&#x1f440; 刷题专栏&#x1f440; C语言&#x1f440; &#x1f69a;代码仓库:笨小孩的代码库&#x1f440; ⏩社区&#xff1a;不是笨小孩&#x1f440; &#x1f339;欢迎大…

Pytest系列-使用自定义标记mark(6)

简介 pytest 可以支持自定义标记&#xff0c;自定义标记可以把一个 web 项目划分为多个模块&#xff0c;然后指定模块名称执行 Pytest 里面自定义标记 用法&#xff1a;将pytest.mark.标记名称 放到测试函数或者类上面 使用&#xff1a; 执行时加上 -m 标记名 进行用例筛选…

[交互]交互的实战问题1

[交互]交互的实战问题1 状态码 431 Request Header Fields Too LargeReferrer Policy: no-referrer-when-downgrade路径参数高并发问题使用场景使用的方法异常情况 状态码 431 Request Header Fields Too Large 最近做项目&#xff0c;遇到一个问题&#xff0c;后台导出表格时…

牛客: BM4 合并两个排序的链表

牛客: BM4 合并两个排序的链表 文章目录 牛客: BM4 合并两个排序的链表题目描述题解思路题解代码 题目描述 题解思路 以链表一为主链表,遍历两条链表 若当前链表二的节点val小于当前链表一的下一个节点val,则将链表链表二的该节点连到链表一的节点的下一个,链表一的当前节点往…

sql存储引擎

-- 查询建表语句 --可以查看引擎 show create table account; -- 可以看到默认引擎 InnoDB ENGINEInnoDB -- 查看当前数据库支持得存储引擎 show engines ; # InnoDB 默认 存储引擎 # MyISAM sql早期默认 存储引擎 # MEMORY 存储在内存中 用来做临时表和缓存 存储引擎 …

Adobe Acrobat Reader 中的漏洞

另一个流行漏洞 Adobe Acrobat 和 Acrobat Reader - 流行的便携式文档格式 (PDF) 工具 - 存在风险。该漏洞 CVE-2023-26369影响 Windows 和 macOS 安装。 攻击者创建的恶意 PDF 文档打开后&#xff0c;会利用与在缓冲区外写入有关的 CVE-2023-26369漏洞。因此&#xff0c;攻击…

数据中心液冷服务器详情说明

目录 前言 何为液冷服务器&#xff1f; 为什么需要液冷&#xff1f; 1.数据中心降低PUE的需求 2.政策导向 3.芯片热功率已经达到风冷散热极限 4.液冷比热远大于空气 液冷VS风冷&#xff0c;区别在哪&#xff1f; 1.液冷服务器跟风冷服务器的区别 2.液冷数据中心跟风冷…

linux安装常见的中间件和数据库

文章目录 一、数据库二、redis三、tomcat四、nginx五、mq六、es七、nacos八、neo4j&#xff08;图数据库&#xff09;九、fastdfs其他 一、数据库 linux环境上使用压缩包安装mysql【数据库】Mysql 创建用户与授权 二、redis redis是没有账号的&#xff0c;只能设置密码Linux…

对IP协议概念以及IP地址的概念进行简单整理

网络层重要协议 参考模型和协议栈IP协议IPv4数据报IP数据报格式IPv4地址特殊IP地址私有IP地址和公有IP地址子网划分 参考模型和协议栈 IP协议 IP协议定义了网络层数据传送的基本单元&#xff0c;也制定了一系列关于网络层的规则。 IPv4数据报 网络层的协议数据单元PDU 叫做分…

GeoSOS-FLUS未来土地利用变化情景模拟模型

软件简介 适用场景 GeoSOS-FLUS软件能较好的应用于土地利用变化模拟与未来土地利用情景 的预测和分析中&#xff0c;是进行地理空间模拟、参与空间优化、辅助决策制定的有效工 具。FLUS 模型可直接用于&#xff1a; 城市发展模拟及城市增长边界划定&#xff1b;城市内 部高分…

分布式事务解决方案之TCC

分布式事务解决方案之TCC 什么是TCC事务 TCC是Try、Confirm、Cancel三个词语的缩写&#xff0c;TCC要求每个分支事务实现三个操作&#xff1a;预处理Try、确认 Confirm、撤销Cancel。Try操作做业务检查及资源预留&#xff0c;Confirm做业务确认操作&#xff0c;Cancel实现一个…

Golang代码漏洞扫描工具介绍——govulncheck

Golang Golang作为一款近年来最火热的服务端语言之一&#xff0c;深受广大程序员的喜爱&#xff0c;笔者最近也在用&#xff0c;特别是高并发的场景下&#xff0c;golang易用性的优势十分明显&#xff0c;但笔者这次想要介绍的并不是golang本身&#xff0c;而且golang代码的漏洞…

微信小程序+echart实现点亮旅游地图

背景 最近看抖音有个很火的特效就是点亮地图&#xff0c;去过哪些地方&#xff0c;于是乎自己也想做一个&#xff0c;结合自己之前做的以家庭为单位的小程序&#xff0c;可以考虑做一个家庭一起点亮地图的功能。 效果图 过程 1&#xff0c;首先就是得去下微信小程序适配的ec…

react 实现拖动元素

demo使用create-react-app脚手架创建 删除一些文件&#xff0c;创建一些文件后 结构目录如下截图com/index import Movable from ./move import { useMove } from ./move.hook import * as Operations from ./move.opMovable.useMove useMove Movable.Operations Operationse…

ABB 1TGE120010R... Rev控制模块

ABB 1TGE120010R... Rev 控制器模块是一种高性能控制器&#xff0c;可用于工业自动化和过程控制应用。它具有以下主要特点&#xff1a; 多功能性&#xff1a;该控制器模块可用于多种应用&#xff0c;包括机器控制、过程控制和自动化系统等。 高性能&#xff1a;该控制器模块具…

竞赛选题 基于机器视觉的火车票识别系统

文章目录 0 前言1 课题意义课题难点&#xff1a; 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器视觉的火车票识别系统 该项目较为新颖&#xff0c;适合作为竞赛…

408强化(番外)文件管理

有点看不下去书&#xff0c;408&#xff0c;哎好久没看了&#xff0c;死磕数学时完全不想看其他科目&#xff0c;数学分数也尚未质变。 突然想到一个好点子&#xff0c;只看大纲尝试回忆一下这章的内容。 文件就是为了方便用户使用&#xff0c;按名访问而提出的&#xff0c;从…

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

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