基于FPGA的人脸检测(1)

项目简述

我们上一篇文章讲解了MATLABl利用肤色检测模型进行人脸检测,也给出了完整的MATLAB代码。同学们学习本篇博客的时候一定要先学习上篇文章,因为上篇文章介绍了整个算法的流程,比看FPGA的实现要简单的多。

本篇博客,我们将利用FPGA实现一副图片中的人脸检测:PC机通过千兆网发送一幅图片经过肤色检测、腐蚀、定位之后将定位信息传递给USB3.0驱动端,再将原始图像转存到DDR3中,然后经过USB3.0将定位后的原始图像发送到上位机显示。

本次实验所用到的软硬件环境如下:
1、VIVADO2019.1软件环境
2、Modelsim10.7c仿真环境
3.米联客MA7035FA(100T)开发板
4、米联客USB3.0上位机软件
5、V3学院千兆网上位机
在这里插入图片描述
整个项目的流程图如上图,我们利用上面的程序框图进行书写便可以完成图像定位。

肤色检测

肤色检测的原理我们上一篇博客已经进行了介绍,首先将RGB分量信息转换成YYCrCb信息,其中Y是亮度信息、Cr表示红色信息、Cb表示绿色信息。然后利用红色分量、绿色分量信息进行肤色定位。

肤色检测代码

这里原理相信大家经过上篇博客的学习已经学会,这里我们直接给出相应的代码供大家学习:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : face_test.v
// Create Time  : 2020-04-11 10:57:34
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module face_test(
    //System Interfaces
    input                   sclk            ,
    input                   rst_n           ,
    //Communication Interfaces
    input           [23:0]  ycbcr_data      ,
    input                   ycbcr_flag      ,
    output  reg     [ 7:0]  face_data       ,
    output  reg             face_flag           
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
parameter       CB_LOWER        =           77;
parameter       CB_UPPER        =           127;
parameter       CR_LOWER        =           133;
parameter       CR_UPPER        =           173;
 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        face_data               <=          8'd0; 
    else if(ycbcr_data[15:8] > CB_LOWER && ycbcr_data[15:8] < CB_UPPER && ycbcr_data[7:0] > CR_LOWER && ycbcr_data[7:0] < CR_UPPER)
        face_data               <=          8'd255;
    else
        face_data               <=          8'd0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        face_flag               <=          1'b0;
    else 
        face_flag               <=          ycbcr_flag;

endmodule

肤色检测结果

我们会在最后给出最终工程的代码,这里为了简洁性不再给出部分代码。整体的实验结果图如下:
在这里插入图片描述

腐蚀图像

从上面的肤色检测图中,我们可以看出肤色检测之后有许多噪点,那么我们便使用腐蚀操作将上面的噪点腐蚀掉。其实最好的操作是先腐蚀再膨胀,这样可以将图像定位的更准确,但是我们因为简洁行的原因没有使用膨胀操作。其次这里我们使用的矩阵式1313的矩阵,并没有使用33的矩阵,因为矩阵太小没办法腐蚀掉全部的噪点。

腐蚀图像代码

这里我们直接给出相应的代码:
13*13矩阵模块代码,mat_13x13模块:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : mat_13x13.v
// Create Time  : 2020-04-11 22:13:48
// Editor       : sublime text3, tab size (2)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module mat_13x13(
    //System Interfaces
    input                   sclk            ,
    input                   rst_n           ,
    //Communication Interfaces
    input           [ 7:0]  rx_data         ,
    input                   pi_flag         ,
    output  wire    [ 7:0]  mat_row1        ,
    output  wire    [ 7:0]  mat_row2        ,
    output  wire    [ 7:0]  mat_row3        ,
	  output  wire    [ 7:0]  mat_row4        ,
    output  wire    [ 7:0]  mat_row5        ,
    output  wire    [ 7:0]  mat_row6        ,
	  output  wire    [ 7:0]  mat_row7        ,
    output  wire    [ 7:0]  mat_row8        ,
    output  wire    [ 7:0]  mat_row9        ,
	  output  wire    [ 7:0]  mat_row10       ,
    output  wire    [ 7:0]  mat_row11       ,
    output  wire    [ 7:0]  mat_row12       ,
	  output  wire    [ 7:0]  mat_row13       ,
    output  wire            mat_flag 

);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
parameter           COL_NUM     =   1024    ;
parameter           ROW_NUM     =   768     ;

reg                 [10:0]  col_cnt         ;
reg                 [10:0]  row_cnt         ;
wire 						            wr_en1 			    ;
wire                        wr_en2          ;
wire                        wr_en3          ;
wire 						            wr_en4 			    ;
wire 						            wr_en5 			    ;
wire 						            wr_en6 			    ;
wire 						            wr_en7 			    ;
wire 						            wr_en8 			    ;
wire 						            wr_en9 			    ;
wire 						            wr_en10			    ;
wire 						            wr_en11			    ;
wire 						            wr_en12			    ;
wire 						            wr_en13			    ;
wire                        rd_en1          ;
wire                        rd_en2          ;
wire						            rd_en3 			    ;
wire						            rd_en4 			    ;
wire						            rd_en5 			    ;
wire						            rd_en6 			    ;
wire						            rd_en7 			    ;
wire						            rd_en8 			    ;
wire						            rd_en9 			    ;
wire						            rd_en10			    ;
wire						            rd_en11			    ;
wire						            rd_en12			    ;
wire						            rd_en13			    ;
wire                [ 7:0]  fifo1_rd_data   ;
wire                [ 7:0]  fifo2_rd_data   ;
wire                [ 7:0]  fifo3_rd_data   ;
wire                [ 7:0]  fifo4_rd_data   ;
wire                [ 7:0]  fifo5_rd_data   ;
wire                [ 7:0]  fifo6_rd_data   ;
wire                [ 7:0]  fifo7_rd_data   ;
wire                [ 7:0]  fifo8_rd_data   ;
wire                [ 7:0]  fifo9_rd_data   ;
wire                [ 7:0]  fifo10_rd_data  ;
wire                [ 7:0]  fifo11_rd_data  ;
wire                [ 7:0]  fifo12_rd_data  ;
wire                [ 7:0]  fifo13_rd_data  ;



//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign 		wr_en1 			= 		pi_flag;
assign      wr_en2          =       row_cnt >= 11'd1 ? pi_flag : 1'b0;
assign      wr_en3          =       row_cnt >= 11'd2 ? pi_flag : 1'b0;
assign      wr_en4          =       row_cnt >= 11'd3 ? pi_flag : 1'b0;
assign      wr_en5          =       row_cnt >= 11'd4 ? pi_flag : 1'b0;
assign      wr_en6          =       row_cnt >= 11'd5 ? pi_flag : 1'b0;
assign      wr_en7          =       row_cnt >= 11'd6 ? pi_flag : 1'b0;
assign      wr_en8          =       row_cnt >= 11'd7 ? pi_flag : 1'b0;
assign      wr_en9          =       row_cnt >= 11'd8 ? pi_flag : 1'b0;
assign      wr_en10         =       row_cnt >= 11'd9 ? pi_flag : 1'b0;
assign      wr_en11         =       row_cnt >= 11'd10 ? pi_flag : 1'b0;
assign      wr_en12         =       row_cnt >= 11'd11 ? pi_flag : 1'b0;
assign      wr_en13         =       row_cnt >= 11'd12 ? pi_flag : 1'b0;

assign      rd_en1          =       wr_en2;
assign      rd_en2          =       wr_en3;
assign      rd_en3          =       wr_en4;
assign      rd_en4          =       wr_en5;
assign      rd_en5          =       wr_en6;
assign      rd_en6          =       wr_en7;
assign      rd_en7          =       wr_en8;
assign      rd_en8          =       wr_en9;
assign      rd_en9          =       wr_en10;
assign      rd_en10         =       wr_en11;
assign      rd_en11         =       wr_en12;
assign      rd_en12         =       wr_en13;
assign      rd_en13         =       mat_flag;

assign      mat_flag        =       row_cnt >= 11'd13 ? pi_flag : 1'b0;
assign      mat_row1        =       fifo1_rd_data;
assign      mat_row2        =       fifo2_rd_data;
assign      mat_row3        =       fifo3_rd_data;
assign      mat_row4        =       fifo4_rd_data;
assign      mat_row5        =       fifo5_rd_data;
assign      mat_row6        =       fifo6_rd_data;
assign      mat_row7        =       fifo7_rd_data;
assign      mat_row8        =       fifo8_rd_data;
assign      mat_row9        =       fifo9_rd_data;
assign      mat_row10       =       fifo10_rd_data;
assign      mat_row11       =       fifo11_rd_data;
assign      mat_row12       =       fifo12_rd_data;
assign      mat_row13       =       fifo13_rd_data;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        col_cnt             <=          11'd0;
    else if(col_cnt == COL_NUM-1 && pi_flag == 1'b1)
        col_cnt             <=          11'd0;
    else if(pi_flag == 1'b1)
        col_cnt             <=          col_cnt + 1'b1;
    else
        col_cnt             <=          col_cnt;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        row_cnt             <=          11'd0;
    else if(row_cnt == ROW_NUM-1 && col_cnt == COL_NUM-1 && pi_flag == 1'b1)
        row_cnt             <=          11'd0;
    else if(col_cnt == COL_NUM-1 && pi_flag == 1'b1) 
        row_cnt             <=          row_cnt + 1'b1;


fifo_generator_4 mat_fifo1 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (rx_data                    ),      // input wire [7 : 0] din
  .wr_en            (wr_en1                     ),  // input wire wr_en
  .rd_en            (rd_en1                     ),  // input wire rd_en
  .dout             (fifo1_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);
        
fifo_generator_4 mat_fifo2 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo1_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en2                     ),  // input wire wr_en
  .rd_en            (rd_en2                     ),  // input wire rd_en
  .dout             (fifo2_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);
    
fifo_generator_4 mat_fifo3 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo2_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en3                     ),  // input wire wr_en
  .rd_en            (rd_en3                     ),  // input wire rd_en
  .dout             (fifo3_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);
    
fifo_generator_4 mat_fifo4 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo3_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en4                     ),  // input wire wr_en
  .rd_en            (rd_en4                     ),  // input wire rd_en
  .dout             (fifo4_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo5 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo4_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en5                     ),  // input wire wr_en
  .rd_en            (rd_en5                     ),  // input wire rd_en
  .dout             (fifo5_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo6 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo5_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en6                     ),  // input wire wr_en
  .rd_en            (rd_en6                     ),  // input wire rd_en
  .dout             (fifo6_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo7 
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值