基于FPGA:肤色识别算法实现(OV5640摄像头+Cyclone芯片)含工程源码
目录
- 前言:
- 一、进入正文:
- 二、Verilog代码实现:
前言:
肤色识别算法的Verilog代码基于FPGA 的彩色图片转灰度实现的。本文参考硅农图像处理教学文章。一个良心公众号,有很多开源技术含量高的东西,有需要的可以找他们获取。
一、进入正文:
将彩色图像转化为灰度的方法有两种,一个是令RGB三个分量的数值相等,输出后便可以得到灰度图像,另一种是转化为YCbCr格式,将Y分量提取出来,YCbCr格式中的Y分量表示的是图像的亮度和浓度所以只输出Y分量,得到的图像就是灰度图像了。我在这里选择第二种方法实现。YCBCr是通过有序的三元组来表示的,三元由Y( Luminance )、Cb(Chrominance-Blue)和Cr (Chrominance-Red)组成,其中Y表示颜色的明亮度和浓度,而Cb和Cr则分别表示颜色的蓝色浓度偏移量和红色浓度偏移量。人的肉眼对由 YCbCr色彩空间编码的视频中的Y分量更敏感,而Cb和Cr的微小变化不会引起视觉上的不同,根据该原理,通过对Cb和Cr进行子采样来减小图像的数据量,使得图像对存储需求和传输带宽的要求大大降低,从而达到在完成图像压缩的同时也保证了视觉上几乎没有损失的效果,进而使得图像的传输速度
更快,存储更加方便。我们要的到灰度图像,首先要将采集到的彩色图像转化为YCbCr。
我通过串口发送的彩色图片数据是 RGB332 8bit,根据官方给出的转化公式是RGB888->YCbCr,所以我首先要将8bit RGB332转化为24bit RGB888。转化如下,这里用到了循环补偿的概念。
循环补偿的概念
8bit RGB332 -> 24bit RGB888的转换
8bit RGB332{ R2 R1 RO} { G2 G1 G0} {B1 B0}
24bit RGB888{ R2 R1 R0 0000o} G2G1 G0 o00 o 0} {B1 B0 0oooo 0}
24bit RGB888 {R2R1RO R2 R1 R0 0 0} G2 G1 G0 G2 G1 G0 0 0 H B1B0 B1 B0 0 00 o}
24bit RGB888 { R2R1 R0 R2 R1RO R2R1}{G2 G1 G0 G2 G1 GO G2 G1]} { B1B0B1B0B1B0 0 0}
24bit RGB888{R2R1RO R2R1 RO R2R1 ][ G2 G1 G0 G2 G1 G0 G2 G1 ]}[B1BOB1B0 B1B0B1B0}
从如上转化可以看出,B分量进行了四轮补偿。进行这样的补偿,在做色彩格式转化的时候,能够明显的改善色彩效果,减少精度上的损失。代码实现部分如下。
assign cmos_R0={ cmos_R, cmos_R, cmos_R[2:1]};
assign cmos_G0={ cmos_G, cmos_G,cmos_G[2:1]};
assign cmos_B0={ cmos_B, cmos_B, cmos_B, cmos_B}
下面是官方给的RGB888 to YCbCr 的算法公式,我们可以直接把算法移植到FPGA 上,但是我们都知FPUA 元公L1就不了FPDGA擅长的乘法运算和加端先都扩大256倍,然后再右移8位,这样就得到了FPGA 擅长的乘法运算和加法运算了。
这个计算式子看起来是十分简单的,但是要是直接用Verilog直接写出来,那么只能说,这个人的代码写的一塌糊涂,所以这里就引出FPGA 中流水线的设计思想。
在这里我们选择加3级流水线,就第一个Y分量而言,先计算括号中得乘法运算,消耗一个时钟,然后将括号中的数据求和,消耗一个时钟,这里为了计算方便,将128也扩大256倍,放到括号中,最终结果除以256就行了也就是右移8位,在FPGA中我们只需要舍弃低8位取高8位就行。
将RGB565—>YCbCr成功后,提取出Y的值输出,就可以得到灰度色彩的图像了。
将采集到的RGB565的像素数据,输入到算法处理模块进行操作,由RGB565——>YCbCr——Gray官方给出的公式来算,先将RGB565拆分开RGB三个分量,使用如上公式计算的到Y Cb Cr是三个分量。
对于肤色检测其实也是基于这个基础上,首先利用如上图公式将RGB转化为YCbCr,然后通过对Cb和Cr分量设置阈值,我这边设置的是当Cb和Cr分量在这个阈值之间时,输出为全1,即白色,其他情况输出为全0,即为黑色,我使用前面的200x200的图片做实验,效果不怎么好﹐最后借用业界前辈CrazyBingo大神的摄像头驱动,试了一下这个肤色识别算法,最后得到的效果还是可以的。这个用YCbCr阈值法实现肤色识别的方法,是不很精确,后面我会尝试用另一种识别方法来试着实现。
肤色识别YCbCr阈值
77< Cb < 127
133 < Cr < 173
二、Verilog代码实现:
`timescale 1ns/1psmodule RGB565_YCbCr_gray(input clk,//COMS pixel clk 24Mhzinput rst_n,//others input [4:0] cmos_R,input [5:0] cmos_G,input [4:0] cmos_B,input per_frame_clken,input per_frame_vsync,input per_frame_href,output [7:0] img_Y,output [7:0] img_Cb,output [7:0] img_Cr,output post_frame_clken,output post_frame_vsync,output post_frame_href
);//--------------------------------------------
//RGB565 to RGB 888 高位补低位
wire [7:0] cmos_R0;
wire [7:0] cmos_G0;
wire [7:0] cmos_B0;assign cmos_R0 = {cmos_R, cmos_R[4:2]};
assign cmos_G0 = {cmos_G, cmos_G[5:4]};
assign cmos_B0 = {cmos_B, cmos_B[4:2]};//--------------------------------------------
/*//Refer to <OV7725 Camera Module Software Applicaton Note> page 5Y = (77 *R + 150*G + 29 *B)>>8Cb = (-43*R - 85 *G + 128*B)>>8 + 128Cr = (128*R - 107*G - 21 *B)>>8 + 128
--->Y = (77 *R + 150*G + 29 *B)>>8Cb = (-43*R - 85 *G + 128*B + 32768)>>8Cr = (128*R - 107*G - 21 *B + 32768)>>8*/
//--------------------------------------------
//RGB888 to YCrCb
//step1 conmuse 1clk
reg [15:0] cmos_R1, cmos_R2, cmos_R3;
reg [15:0] cmos_G1, cmos_G2, cmos_G3;
reg [15:0] cmos_B1, cmos_B2, cmos_B3;
always @(posedge clk or negedge rst_n)
beginif(!rst_n)begincmos_R1 <= 16'd0;cmos_G1 <= 16'd0;cmos_B1 <= 16'd0;cmos_R2 <= 16'd0;cmos_G2 <= 16'd0;cmos_B2 <= 16'd0;cmos_R3 <= 16'd0;cmos_G3 <= 16'd0;cmos_B3 <= 16'd0;endelse begincmos_R1 <= cmos_R0 * 8'd77;cmos_G1 <= cmos_G0 * 8'd150;cmos_B1 <= cmos_B0 * 8'd29; cmos_R2 <= cmos_R0 * 8'd43; cmos_G2 <= cmos_G0 * 8'd85; cmos_B2 <= cmos_B0 * 8'd128; cmos_R3 <= cmos_R0 * 8'd128;cmos_G3 <= cmos_G0 * 8'd107;cmos_B3 <= cmos_B0 * 8'd21;end
end//-----------------------------------------------
//step2 consume 1clk
reg [15:0] img_Y0;
reg [15:0] img_Cb0;
reg [15:0] img_Cr0;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 <= cmos_R1 + cmos_G1 + cmos_B1;img_Cb0 <= cmos_B2 - cmos_R2 - cmos_G2 + 16'd32768;img_Cr0 <= cmos_R3 - cmos_G3 - cmos_B3 + 16'd32768;endend
//-------------------------------------------
//step3 conmuse 1clk
reg [7:0] img_Y1;
reg [7:0] img_Cb1;
reg [7:0] img_Cr1;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];endend//------------------------------------------
//step4 consume 1clk
reg [7:0] gray_data_r;
always @(posedge clk or negedge rst_n)beginif(!rst_n)gray_data_r <= 'b0;else if(img_Cb1 > 77 && img_Cb1 < 127 && img_Cr1 > 133 && img_Cr1 < 173)gray_data_r <= 8'hff;else gray_data_r <= 'b0;
end//---------------------------------------------
//pre_frame_clken, pre_frame_href, pre_frame_vsync,lag 3clkreg [3:0] per_frame_clken_r;
reg [3:0] per_frame_href_r;
reg [3:0] per_frame_vsync_r;always @(posedge clk or negedge rst_n)
beginif(!rst_n)beginper_frame_clken_r <= 4'b0;per_frame_href_r <= 4'b0;per_frame_vsync_r <= 4'b0;end else beginper_frame_clken_r <= {per_frame_clken_r [2:0], per_frame_clken};per_frame_href_r <= {per_frame_href_r [2:0],per_frame_href};per_frame_vsync_r <= {per_frame_vsync_r [2:0],per_frame_vsync};end
endassign post_frame_clken = per_frame_clken_r [3];
assign post_frame_href = per_frame_href_r [3];
assign post_frame_vsync = per_frame_vsync_r [3];assign img_Y = post_frame_href? gray_data_r: 1'b0;
assign img_Cb = post_frame_href? img_Cb1: 1'b0;
assign img_Cr = post_frame_href? img_Cr1: 1'b0;endmodule
基于FPGA:肤色识别算法实现(OV5640摄像头+Cyclone芯片)含工程源码相关推荐
- 【SVM分类】基于matlab哈里斯鹰算法优化支持向量机SVM分类【含Matlab源码 2243期】
⛄一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[SVM分类]基于matlab哈里斯鹰算法优化支持向量机SVM分类[含Matlab源码 2243期] 获取代码方式2: 付费专栏Matla ...
- 【ACO TSP】基于matlab蚁群算法求解31城市旅行商问题【含Matlab源码 1147期】
一.获取代码方式 获取代码方式1: 完整代码已上传我的资源:[TSP]基于matlab蚁群算法求解31城市旅行商问题[含Matlab源码 1147期] 点击上面蓝色字体,直接付费下载,即可. 获取代码 ...
- FPGA基于Tri Mode Ethernet MAC实现UDP通信 提供3套工程源码和技术支持
目录 1.前言 2.我这里已有的UDP方案 3.米联客UDP协议栈 4.详细设计方案 5.Tri Mode Ethernet MAC的使用 6.vivado工程1详解 7.vivado工程2详解 8. ...
- FPGA基于SFP光口实现1G千兆网UDP通信 1G/2.5G Ethernet PCS/PMA or SGMII替代网络PHY芯片 提供工程源码和技术支持
目录 1.前言 2.我这里已有的UDP方案 3.详细设计方案 4.vivado工程详解 5.上板调试验证并演示 6.福利:工程代码的获取 1.前言 目前网上的fpga实现udp基本生态如下: 1:ve ...
- FPGA基于SFP光口实现10G万兆网UDP通信 10G Ethernet Subsystem替代网络PHY芯片 提供工程源码和技术支持
目录 1.前言 2.我这里已有的UDP方案 3.详细设计方案 4.vivado工程详解 5.上板调试验证并演示 6.福利:工程代码的获取 1.前言 目前网上的fpga实现udp基本生态如下: 1:ve ...
- FPGA实现UDP传输视频,提供2套verilog工程源码和接收显示上位机程序
FPGA实现UDP传输是FPGA在通信领域的应用之一,只要有UDP收发模块,那么实现UDP传输就只剩下数据组包的事项了: 之前我写过一篇文章介绍过FPGA实现UDP协议的文章FPGA实现UDP协议 后 ...
- FPGA驱动silicon9011和silicon9134完成HDMI收发,提供工程源码和技术支持
目录 1.HDMI输入输出设计框架 2.silicon9011/9013芯片详解及配置 3.silicon9134芯片详解及配置 4.FPGA工程介绍 5.上板调试验证 6.福利:工程源码获取 1.H ...
- FPGA采集IT6802视频HDMI输出,提供两套工程源码和技术支持
IT6802是宝岛台湾联阳半导体设计生产的HDMI接受芯片,数据手册有49页,编程手册79页,想要看懂并操作还是有难度的,所以直接上干货. 开发板:Kintex7板子: 开发环境:vivado2019 ...
- 【PSO三维路径规划】基于matlab粒子群算法无人机三维路径规划【含Matlab源码 192期】
⛄一.无人机简介 无人机的航迹规划是指在综合考虑无人机飞行油耗.威胁.飞行区域以及自身物理条件限制等因素的前提下, 为飞行器在飞行区域内规划出从初始点到目标点最优或者满意的飞行航迹, 其本质是一个多约 ...
最新文章
- 模拟一个简单计算器_阅读模拟器的简单介绍
- java 异常何时抛出_何时适合抛出异常?
- python判断值是否为空(亲测)
- ViewDragHelper
- quartz集群报错but has failed to stop it. This is very likely to create a memory leak.
- Python一些很实用的知识
- day31(GIL锁)
- Hive 复杂数据类型之map
- 欧拉工程第54题:Poker hands
- [洛谷P3919]【模板】可持久化数组
- pandas求协方差、相关系数、显著性检验
- pr cpu100%_PR插件Sapphire2019.52安装教程
- Html5 postmessage 子父窗口传值
- Android 面试题(答案最全) 转:http://www.jobui.com/mianshiti/it/android/2682/
- python 压缩算法_lzma — 用 LZMA 算法压缩
- 【004】国家企业信用信息公示系统-官方渠道查询企业信息
- CISCO Switchport trunk encap dot1q 与 Switchport trunk 区别
- 如何使用 Java 将 PDF 转换为文本 (TXT)
- Redis常用命令入门4:集合类型
- 人体信号基线漂移问题