基于FPGA的人脸识别

基于FPGA的人脸识别

一.理论基础

1.基本介绍

模块框图:
基于FPGA的人脸识别_第1张图片

在上一篇文章里,已经实现了基于OV5640的摄像头监控,在此基础上,我们加入一些图像处理的内容,即可实现简单的一些图像处理效果,这次做到的就是最基础的人脸识别功能。

2.理论知识

(1)RGB->YCBCR

因为RGB全彩图像对于图像处理很困难,所以大部分采用的都是将图像信息二值化,也就是我们所理解的黑白图像。所以我们第一个需要的就是将图像信息从RGB转成ycbcr格式。
RGB转换YCBCR格式的公式如下:

Y = 0.299R +0.587G + 0.114B
Cb = 0.568(B-Y) + 128
CR = 0.713(R-Y) + 128

经过上面公式我们就可以将RGB转换成YCBCR格式

(2)图像二值化

得到了YCBCR格式的图像数据之后,我们就可以通过设定阈值的范围来获得我们所需要的图像信息了,处理之后的效果就是人脸部分显示白色,其余部分显示黑色。
比如我们这里要得到的人脸的肤色,根据查询,人脸的阈值如下:
77 < Cb < 127
133 < Cr < 173

(3)滤波

由于我们实现的是最基本的图像处理效果,所以此次的介绍没有加入滤波的方法。但可以介绍一下滤波的原因和方法,具体内容后期随缘介绍哈哈。
滤波的原因:
在我们的摄像头采集图像信息的过程中,由于硬件本来存在的问题,会有一些飘动的白点进行调动,这就是我们所说的图像噪点。(小时候的电视机的雪花就是这样滴)
滤波的方法:
就我所知的图像处理方法比较有限且基础,有中值滤波,均值滤波,服饰和膨胀算法等等,还有一些其他比如帧差发来检测快速运动物体,光流法等。

(4)识别有效区域

为了更加直观的看到处理的结果,我们用红框来框选住我们所处理之后的图像信息。但是我们不能无缘无故就可以准确的框选我们所要的内容,所以我们需要进行识别有效的区域,即得到有效图像的最小和最大的X,Y的坐标,来进行框选。
具体思路就是:用X,Y分别扫描图像信息,第一个得到的1.和第一个从1反转到0的坐标进行寄存,然后经过运算之后就可以准确的得到这四个值:
X min,X max,Y min,Y max.
当然,没有进行滤波的图像会产生很多的噪点,导致框选的内容有问题,这里只是提供一个思路。可以用开运算进行去除噪点。

(5)画框

将上一模块传来的X min,X max,Y min,Y max值分别赋予红色之后,就可以框选出我们想要框选的内容。
具体代码体现:

if(vga_y== y_min && vga_x>= x_min && vga_x<= x_max)
			rgb <= RED;
		else if(vga_y== y_max && vga_x>= x_min && vga_x<= x_max)
			rgb <= RED;
		else if(vga_x== x_min && vga_y>= y_min && vga_y<= y_max)
			rgb <= RED;
		else if(vga_x== x_max && vga_y>= y_min && vga_y<= y_max)
			rgb <= RED

二.系统RTL及模块核心代码

1.系统RTL

基于FPGA的人脸识别_第2张图片基于FPGA的人脸识别_第3张图片

1.模块核心代码

(1)RGB->YCBCR

//step1 计算括号内的各乘法项
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        rgb_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;
    end
    else begin
        rgb_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) begin
    if(!rst_n) begin
        img_y0  <= 16'd0;
        img_cb0 <= 16'd0;
        img_cr0 <= 16'd0;
    end
    else begin
        img_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;
    end

end

//step3 括号内计算的数据右移8位
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        img_y1  <= 8'd0;
        img_cb1 <= 8'd0;
        img_cr1 <= 8'd0;
    end
    else begin
        img_y1  <= img_y0 [15:8];
        img_cb1 <= img_cb0[15:8];
        img_cr1 <= img_cr0[15:8];
    end
end

(2)识别有效区域

//x_min lag 2clk
always @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        x_min <= ROW_CNT;
    end
    else if(flag)
        x_min <= ROW_CNT;
    else if(per_frame_clken && per_img_Bit == 1 && x_min > cnt_x)
        x_min <= cnt_x;
    else 
        x_min <= x_min;
end
//x_max
always @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        x_max <= 0;
    end
    else if(flag)
        x_max <= 0;
    else if(per_frame_clken && per_img_Bit == 1 && x_max < cnt_x)
        x_max <= cnt_x;
    else 
        x_max <= x_max;
end
//y_min
always @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        y_min <= COL_CNT;
    end
    else if(flag)
        y_min <= COL_CNT;
    else if(per_frame_clken && per_img_Bit == 1 && y_min > cnt_y)
        y_min <= cnt_y;
    else 
        y_min <= y_min;
end
//y_max
always @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        y_max <= 0;
    end
    else if(flag)
        y_max <= 0;
    else if(per_frame_clken && per_img_Bit == 1 && y_max < cnt_y)
        y_max <= cnt_y;
    else 
        y_max <= y_max;
end

初学入门,分享学习笔记和心得,如有指教,感激不尽!

由于最近板子做在了课设上,所以暂时没有上板的效果,等课赛开始之后,将即时上传上板的效果图片。

你可能感兴趣的:(人脸识别,人脸识别,fpga)