基于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        : nnzhang1996@foxmail.com
// 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        : nnzhang1996@foxmail.com
// 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 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo6_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en7                     ),  // input wire wr_en
  .rd_en            (rd_en7                     ),  // input wire rd_en
  .dout             (fifo7_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo8 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo7_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en8                     ),  // input wire wr_en
  .rd_en            (rd_en8                     ),  // input wire rd_en
  .dout             (fifo8_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo9 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo8_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en9                     ),  // input wire wr_en
  .rd_en            (rd_en9                     ),  // input wire rd_en
  .dout             (fifo9_rd_data              ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo10 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo9_rd_data              ),      // input wire [7 : 0] din
  .wr_en            (wr_en10                    ),  // input wire wr_en
  .rd_en            (rd_en10                    ),  // input wire rd_en
  .dout             (fifo10_rd_data             ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo11 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo10_rd_data             ),      // input wire [7 : 0] din
  .wr_en            (wr_en11                    ),  // input wire wr_en
  .rd_en            (rd_en11                    ),  // input wire rd_en
  .dout             (fifo11_rd_data             ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo12 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo11_rd_data             ),      // input wire [7 : 0] din
  .wr_en            (wr_en12                    ),  // input wire wr_en
  .rd_en            (rd_en12                    ),  // input wire rd_en
  .dout             (fifo12_rd_data             ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

fifo_generator_4 mat_fifo13 (
  .clk              (sclk                       ),      // input wire clk
  .srst             (~rst_n                     ),    // input wire srst
  .din              (fifo12_rd_data             ),      // input wire [7 : 0] din
  .wr_en            (wr_en13                    ),  // input wire wr_en
  .rd_en            (rd_en13                    ),  // input wire rd_en
  .dout             (fifo13_rd_data             ),    // output wire [7 : 0] dout
  .full             (                           ),    // output wire full
  .empty            (                           )  // output wire empty
);

endmodule

腐蚀模块代码:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : nnzhang1996@foxmail.com
// Website      : 
// Module Name  : erode.v
// Create Time  : 2020-04-11 22:40:12
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module erode(
    //System Interfaces
    input                   sclk            ,
    input                   rst_n           ,
    //Communication Interfaces
    input           [ 7:0]  rx_data         ,
    input                   pi_flag         ,
    output  reg     [ 7:0]  tx_data         ,
    output  wire            po_flag       
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
wire                [ 7:0]  mat_row1                ;
wire                [ 7:0]  mat_row2                ;
wire                [ 7:0]  mat_row3                ;
wire                [ 7:0]  mat_row4                ;
wire                [ 7:0]  mat_row5                ;
wire                [ 7:0]  mat_row6                ;
wire                [ 7:0]  mat_row7                ;
wire                [ 7:0]  mat_row8                ;
wire                [ 7:0]  mat_row9                ;
wire                [ 7:0]  mat_row10               ;
wire                [ 7:0]  mat_row11               ;
wire                [ 7:0]  mat_row12               ;
wire                [ 7:0]  mat_row13               ;

reg                 [ 7:0]  mat_row1_r[12:0]        ;
reg                 [ 7:0]  mat_row2_r[12:0]        ;
reg                 [ 7:0]  mat_row3_r[12:0]        ;
reg                 [ 7:0]  mat_row4_r[12:0]        ;
reg                 [ 7:0]  mat_row5_r[12:0]        ;
reg                 [ 7:0]  mat_row6_r[12:0]        ;
reg                 [ 7:0]  mat_row7_r[12:0]        ;
reg                 [ 7:0]  mat_row8_r[12:0]        ;
reg                 [ 7:0]  mat_row9_r[12:0]        ;
reg                 [ 7:0]  mat_row10_r[12:0]       ;
reg                 [ 7:0]  mat_row11_r[12:0]       ;
reg                 [ 7:0]  mat_row12_r[12:0]       ;
reg                 [ 7:0]  mat_row13_r[12:0]       ;
wire                        mat_flag                ; 
reg                         mat_flag_r1             ;
reg                         mat_flag_r2             ;
reg                         mat_flag_r3             ;
reg                         mat_flag_r4             ;
reg                         mat_flag_r5             ;
reg                         mat_flag_r6             ;
reg                         mat_flag_r7             ;
reg                         mat_flag_r8             ;
reg                         mat_flag_r9             ;
reg                         mat_flag_r10            ;
reg                         mat_flag_r11            ;
reg                         mat_flag_r12            ;
reg                         mat_flag_r13            ;
reg                         mat_flag_r14            ;
reg                         mat_flag_r15            ;
reg                         mat_flag_r16            ;
reg                         erode_flag1             ;
reg                         erode_flag2             ; 
reg                         erode_flag3             ;
reg                         erode_flag4             ;
reg                         erode_flag5             ;
reg                         erode_flag6             ;
reg                         erode_flag7             ;
reg                         erode_flag8             ;
reg                         erode_flag9             ;
reg                         erode_flag10            ;
reg                         erode_flag11            ;
reg                         erode_flag12            ;
reg                         erode_flag13            ;  
 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign      po_flag             =           mat_flag_r16 && mat_flag_r3;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)begin
        mat_row1_r[0]           <=          8'd0;
        mat_row2_r[0]           <=          8'd0;
        mat_row3_r[0]           <=          8'd0;
        mat_row4_r[0]           <=          8'd0;
        mat_row5_r[0]           <=          8'd0;
        mat_row6_r[0]           <=          8'd0;
        mat_row7_r[0]           <=          8'd0;
        mat_row8_r[0]           <=          8'd0;
        mat_row9_r[0]           <=          8'd0;
        mat_row10_r[0]          <=          8'd0;
        mat_row11_r[0]          <=          8'd0;
        mat_row12_r[0]          <=          8'd0;
        mat_row13_r[0]          <=          8'd0;
    end else begin
        mat_row1_r[0]           <=          mat_row1;
        mat_row2_r[0]           <=          mat_row2;
        mat_row3_r[0]           <=          mat_row3;
        mat_row4_r[0]           <=          mat_row4;
        mat_row5_r[0]           <=          mat_row5;
        mat_row6_r[0]           <=          mat_row6;
        mat_row7_r[0]           <=          mat_row7;
        mat_row8_r[0]           <=          mat_row8;
        mat_row9_r[0]           <=          mat_row9;
        mat_row10_r[0]          <=          mat_row10;
        mat_row11_r[0]          <=          mat_row11;
        mat_row12_r[0]          <=          mat_row12;
        mat_row13_r[0]          <=          mat_row13;
    end 

genvar i;
    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row1_r[i]       <=      8'd0;   
                else 
                    mat_row1_r[i]       <=      mat_row1_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row2_r[i]       <=      8'd0;   
                else 
                    mat_row2_r[i]       <=      mat_row2_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row3_r[i]       <=      8'd0;   
                else 
                    mat_row3_r[i]       <=      mat_row3_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row4_r[i]       <=      8'd0;   
                else 
                    mat_row4_r[i]       <=      mat_row4_r[i-1]; 
    endgenerate
    
    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row5_r[i]       <=      8'd0;   
                else 
                    mat_row5_r[i]       <=      mat_row5_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row6_r[i]       <=      8'd0;   
                else 
                    mat_row6_r[i]       <=      mat_row6_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row7_r[i]       <=      8'd0;   
                else 
                    mat_row7_r[i]       <=      mat_row7_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row8_r[i]       <=      8'd0;   
                else 
                    mat_row8_r[i]       <=      mat_row8_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row9_r[i]       <=      8'd0;   
                else 
                    mat_row9_r[i]       <=      mat_row9_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row10_r[i]      <=      8'd0;   
                else 
                    mat_row10_r[i]      <=      mat_row10_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row11_r[i]      <=      8'd0;   
                else 
                    mat_row11_r[i]      <=      mat_row11_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row12_r[i]      <=      8'd0;   
                else 
                    mat_row12_r[i]      <=      mat_row12_r[i-1]; 
    endgenerate

    generate
      for (i=1; i < 13; i=i+1)
          always @(posedge sclk or negedge rst_n)
                if(rst_n == 1'b0)
                    mat_row13_r[i]      <=      8'd0;   
                else 
                    mat_row13_r[i]      <=      mat_row13_r[i-1]; 
    endgenerate

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag1             <=          1'b0;
    else if(mat_row1_r[12] == 255 && mat_row1_r[11] == 255 && mat_row1_r[10] == 255 && mat_row1_r[9] == 255 && mat_row1_r[8] == 255 && mat_row1_r[7] == 255 &&
             mat_row1_r[6] == 255 && mat_row1_r[5] == 255 && mat_row1_r[4] == 255 && mat_row1_r[3] == 255 && mat_row1_r[2] == 255 && mat_row1_r[1] == 255 && mat_row1_r[0] == 255) 
        erode_flag1             <=          1'b1;
    else
        erode_flag1             <=          1'b0;
        
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag2             <=          1'b0;
    else if(mat_row2_r[12] == 255 && mat_row2_r[11] == 255 && mat_row2_r[10] == 255 && mat_row2_r[9] == 255 && mat_row2_r[8] == 255 && mat_row2_r[7] == 255 &&
             mat_row2_r[6] == 255 && mat_row2_r[5] == 255 && mat_row2_r[4] == 255 && mat_row2_r[3] == 255 && mat_row2_r[2] == 255 && mat_row2_r[1] == 255 && mat_row2_r[0] == 255) 
        erode_flag2             <=          1'b1;
    else
        erode_flag2             <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag3             <=          1'b0;
    else if(mat_row3_r[12] == 255 && mat_row3_r[11] == 255 && mat_row3_r[10] == 255 && mat_row3_r[9] == 255 && mat_row3_r[8] == 255 && mat_row3_r[7] == 255 &&
             mat_row3_r[6] == 255 && mat_row3_r[5] == 255 && mat_row3_r[4] == 255 && mat_row3_r[3] == 255 && mat_row3_r[2] == 255 && mat_row3_r[1] == 255 && mat_row3_r[0] == 255) 
        erode_flag3             <=          1'b1;
    else
        erode_flag3             <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag4             <=          1'b0;
    else if(mat_row4_r[12] == 255 && mat_row4_r[11] == 255 && mat_row4_r[10] == 255 && mat_row4_r[9] == 255 && mat_row4_r[8] == 255 && mat_row4_r[7] == 255 &&
             mat_row4_r[6] == 255 && mat_row4_r[5] == 255 && mat_row4_r[4] == 255 && mat_row4_r[3] == 255 && mat_row4_r[2] == 255 && mat_row4_r[1] == 255 && mat_row4_r[0] == 255) 
        erode_flag4             <=          1'b1;
    else
        erode_flag4             <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag5             <=          1'b0;
    else if(mat_row5_r[12] == 255 && mat_row5_r[11] == 255 && mat_row5_r[10] == 255 && mat_row5_r[9] == 255 && mat_row5_r[8] == 255 && mat_row5_r[7] == 255 &&
             mat_row5_r[6] == 255 && mat_row5_r[5] == 255 && mat_row5_r[4] == 255 && mat_row5_r[3] == 255 && mat_row5_r[2] == 255 && mat_row5_r[1] == 255 && mat_row5_r[0] == 255) 
        erode_flag5             <=          1'b1;
    else
        erode_flag5             <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag6             <=          1'b0;
    else if(mat_row6_r[12] == 255 && mat_row6_r[11] == 255 && mat_row6_r[10] == 255 && mat_row6_r[9] == 255 && mat_row6_r[8] == 255 && mat_row6_r[7] == 255 &&
             mat_row6_r[6] == 255 && mat_row6_r[5] == 255 && mat_row6_r[4] == 255 && mat_row6_r[3] == 255 && mat_row6_r[2] == 255 && mat_row6_r[1] == 255 && mat_row6_r[0] == 255) 
        erode_flag6             <=          1'b1;
    else
        erode_flag6             <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag7             <=          1'b0;
    else if(mat_row7_r[12] == 255 && mat_row7_r[11] == 255 && mat_row7_r[10] == 255 && mat_row7_r[9] == 255 && mat_row7_r[8] == 255 && mat_row7_r[7] == 255 &&
             mat_row7_r[6] == 255 && mat_row7_r[5] == 255 && mat_row7_r[4] == 255 && mat_row7_r[3] == 255 && mat_row7_r[2] == 255 && mat_row7_r[1] == 255 && mat_row7_r[0] == 255) 
        erode_flag7             <=          1'b1;
    else
        erode_flag7             <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag8             <=          1'b0;
    else if(mat_row8_r[12] == 255 && mat_row8_r[11] == 255 && mat_row8_r[10] == 255 && mat_row8_r[9] == 255 && mat_row8_r[8] == 255 && mat_row8_r[7] == 255 &&
             mat_row8_r[6] == 255 && mat_row8_r[5] == 255 && mat_row8_r[4] == 255 && mat_row8_r[3] == 255 && mat_row8_r[2] == 255 && mat_row8_r[1] == 255 && mat_row8_r[0] == 255) 
        erode_flag8             <=          1'b1;
    else
        erode_flag8             <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag9             <=          1'b0;
    else if(mat_row9_r[12] == 255 && mat_row9_r[11] == 255 && mat_row9_r[10] == 255 && mat_row9_r[9] == 255 && mat_row9_r[8] == 255 && mat_row9_r[7] == 255 &&
             mat_row9_r[6] == 255 && mat_row9_r[5] == 255 && mat_row9_r[4] == 255 && mat_row9_r[3] == 255 && mat_row9_r[2] == 255 && mat_row9_r[1] == 255 && mat_row9_r[0] == 255) 
        erode_flag9             <=          1'b1;
    else
        erode_flag9             <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag10            <=          1'b0;
    else if(mat_row10_r[12] == 255 && mat_row10_r[11] == 255 && mat_row10_r[10] == 255 && mat_row10_r[9] == 255 && mat_row10_r[8] == 255 && mat_row10_r[7] == 255 &&
             mat_row10_r[6] == 255 && mat_row10_r[5] == 255 && mat_row10_r[4] == 255 && mat_row10_r[3] == 255 && mat_row10_r[2] == 255 && mat_row10_r[1] == 255 && mat_row10_r[0] == 255) 
        erode_flag10            <=          1'b1;
    else
        erode_flag10            <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag11            <=          1'b0;
    else if(mat_row11_r[12] == 255 && mat_row11_r[11] == 255 && mat_row11_r[10] == 255 && mat_row11_r[9] == 255 && mat_row11_r[8] == 255 && mat_row11_r[7] == 255 &&
             mat_row11_r[6] == 255 && mat_row11_r[5] == 255 && mat_row11_r[4] == 255 && mat_row11_r[3] == 255 && mat_row11_r[2] == 255 && mat_row11_r[1] == 255 && mat_row11_r[0] == 255) 
        erode_flag11            <=          1'b1;
    else
        erode_flag11            <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag12            <=          1'b0;
    else if(mat_row12_r[12] == 255 && mat_row12_r[11] == 255 && mat_row12_r[10] == 255 && mat_row12_r[9] == 255 && mat_row12_r[8] == 255 && mat_row12_r[7] == 255 &&
             mat_row12_r[6] == 255 && mat_row12_r[5] == 255 && mat_row12_r[4] == 255 && mat_row12_r[3] == 255 && mat_row12_r[2] == 255 && mat_row12_r[1] == 255 && mat_row12_r[0] == 255) 
        erode_flag12            <=          1'b1;
    else
        erode_flag12            <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        erode_flag13            <=          1'b0;
    else if(mat_row13_r[12] == 255 && mat_row13_r[11] == 255 && mat_row13_r[10] == 255 && mat_row13_r[9] == 255 && mat_row13_r[8] == 255 && mat_row13_r[7] == 255 &&
             mat_row13_r[6] == 255 && mat_row13_r[5] == 255 && mat_row13_r[4] == 255 && mat_row13_r[3] == 255 && mat_row13_r[2] == 255 && mat_row13_r[1] == 255 && mat_row13_r[0] == 255) 
        erode_flag13            <=          1'b1;
    else
        erode_flag13            <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        tx_data                 <=          8'd0;
    else if(erode_flag12 == 1'b1 && erode_flag11 == 1'b1 && erode_flag10 == 1'b1 && erode_flag9 == 1'b1 && erode_flag8 == 1'b1 && erode_flag7 == 1'b1 && erode_flag6 == 1'b1 &&
            erode_flag5 == 1'b1  && erode_flag4 == 1'b1 && erode_flag3 == 1'b1 && erode_flag2 == 1'b1 && erode_flag1 == 1'b1 && erode_flag13 == 1'b1) 
        tx_data                 <=          8'd255;
    else
        tx_data                 <=          8'd0;
        
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)begin
        mat_flag_r1             <=          1'b0;         
        mat_flag_r2             <=          1'b0;             
        mat_flag_r3             <=          1'b0;             
        mat_flag_r4             <=          1'b0;             
        mat_flag_r5             <=          1'b0;             
        mat_flag_r6             <=          1'b0;             
        mat_flag_r7             <=          1'b0;             
        mat_flag_r8             <=          1'b0;             
        mat_flag_r9             <=          1'b0;             
        mat_flag_r10            <=          1'b0;
        mat_flag_r11            <=          1'b0;   
        mat_flag_r12            <=          1'b0;                        
        mat_flag_r13            <=          1'b0;                        
        mat_flag_r14            <=          1'b0;                        
        mat_flag_r15            <=          1'b0;                        
        mat_flag_r16            <=          1'b0;                                   
    end else begin
        mat_flag_r1             <=          mat_flag;             
        mat_flag_r2             <=          mat_flag_r1;              
        mat_flag_r3             <=          mat_flag_r2;              
        mat_flag_r4             <=          mat_flag_r3;              
        mat_flag_r5             <=          mat_flag_r4;              
        mat_flag_r6             <=          mat_flag_r5;              
        mat_flag_r7             <=          mat_flag_r6;              
        mat_flag_r8             <=          mat_flag_r7;              
        mat_flag_r9             <=          mat_flag_r8;              
        mat_flag_r10            <=          mat_flag_r9;
        mat_flag_r11            <=          mat_flag_r10;
        mat_flag_r12            <=          mat_flag_r11;
        mat_flag_r13            <=          mat_flag_r12;
        mat_flag_r14            <=          mat_flag_r13;
        mat_flag_r15            <=          mat_flag_r14;
        mat_flag_r16            <=          mat_flag_r15;       
    end 
    

mat_13x13 mat_13x13_inst(
    //System Interfaces
    .sclk                   (sclk                   ),
    .rst_n                  (rst_n                  ),
    //Communication Interfaces
    .rx_data                (rx_data                ),
    .pi_flag                (pi_flag                ),
    .mat_row1               (mat_row1               ),
    .mat_row2               (mat_row2               ),
    .mat_row3               (mat_row3               ),
    .mat_row4               (mat_row4               ),
    .mat_row5               (mat_row5               ),
    .mat_row6               (mat_row6               ),
    .mat_row7               (mat_row7               ),
    .mat_row8               (mat_row8               ),
    .mat_row9               (mat_row9               ),
    .mat_row10              (mat_row10              ),
    .mat_row11              (mat_row11              ),
    .mat_row12              (mat_row12              ),
    .mat_row13              (mat_row13              ),
    .mat_flag               (mat_flag               )

);
endmodule

上面的代码写的很简洁有技巧,很值得大家借鉴,因为13*13的矩阵涉及了太多的元素。

腐蚀之后的图像

腐蚀之后的图像:
在这里插入图片描述

图像定位

图像定位与画框的逻辑流程和MATLAB代码中的完全相同,我们这里不在多加赘述。

图像定位代码

图像定位的代码如下,face_seek模块:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : nnzhang1996@foxmail.com
// Website      : 
// Module Name  : face_seek.v
// Create Time  : 2020-04-13 22:47:21
// 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_seek(
    //System Interfaces
    input                   sclk            ,
    input                   rst_n           ,
    //Communication Interfaces
    input           [ 7:0]  rx_data         ,
    input                   pi_flag         ,
    output  reg     [10:0]  x_min           ,
    output  reg     [10:0]  x_max           ,
    output  reg     [10:0]  y_min           ,
    output  reg     [10:0]  y_max           ,
    output  reg             po_flag         
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
parameter           ROW_NUM     =   768-13  ;
parameter           COL_NUM     =   1024    ; 

reg                 [10:0]  row_cnt         ;
reg                 [10:0]  col_cnt         ;

//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
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;
    else
        row_cnt             <=              row_cnt;

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

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        x_min               <=              11'd1023;
    else if(po_flag == 1'b1)
        x_min               <=              11'd1023;
    else if(rx_data > 0 && pi_flag == 1'b1 && x_min > col_cnt)
        x_min               <=              col_cnt;
    else
        x_min               <=              x_min;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        x_max               <=              11'd0;
    else if(po_flag == 1'b1)
        x_max               <=              11'd0;
    else if(rx_data > 0 && pi_flag == 1'b1 && x_max < col_cnt)
        x_max               <=              col_cnt;
    else
        x_max               <=              x_max;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        y_min               <=              11'd755;          
    else if(po_flag == 1'b1)
        y_min               <=              11'd755;
    else if(rx_data > 0 && pi_flag == 1'b1 && y_min > row_cnt)
        y_min               <=              row_cnt;
    else
        y_min               <=              y_min;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        y_max               <=              11'd0;
    else if(po_flag == 1'b1)
        y_max               <=              11'd0;
    else if(rx_data > 0 && pi_flag == 1'b1 && y_max < row_cnt)
        y_max               <=              row_cnt;
    else
        y_max               <=              y_max;


endmodule

画框的代码在输出图像的部分进行操作,usb3_drive模块代码如下:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : nnzhang1996@foxmail.com
// Website      : 
// Module Name  : usb3_drive.v
// Create Time  : 2020-03-03 10:36:21
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************
module usb3_drive(
    input                       rst_n               ,
    output  wire                USBSS_EN            ,
    input                       sclk                ,
    inout           [15:0]      data                ,
    inout           [ 1:0]      be                  ,
    input                       rxf_n               ,
    input                       txf_n               ,
    output  reg                 oe_n                ,
    output  reg                 wr_n                ,
    output  wire                siwu_n              ,
    output  reg                 rd_n                ,
    output  wire                wakeup              ,
    output  wire    [ 1:0]      gpio                ,
    //Communication Interfaces
    input           [15:0]      data_in             ,
    output  wire                data_req            ,
    input           [10:0]      x_min               ,        
    input           [10:0]      x_max               ,        
    input           [10:0]      y_min               ,        
    input           [10:0]      y_max               ,        
    input                       po_flag                     
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
parameter   COL_NUM     =       1024*2              ;
parameter   ROW_NUM     =       768                 ;


parameter   IDLE        =       4'b0001             ;
parameter   JUDGE       =       4'b0010             ;
parameter   READ        =       4'b0100             ;
parameter   WRITE       =       4'b1000             ;

reg                 [ 3:0]      state               ;
wire                            fifo_wr             ;
wire                [15:0]      data_wr             ;

reg                 [12:0]      col_cnt             ;
reg                 [12:0]      row_cnt             ;

reg                 [10:0]      x_min_r             ;        
reg                 [10:0]      x_max_r             ;        
reg                 [10:0]      y_min_r             ;        
reg                 [10:0]      y_max_r             ;  
reg                 [15:0]      data_o              ;           


 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign      USBSS_EN    =       1'b1;
assign      wakeup      =       1'b1;
assign      siwu_n      =       1'b0;
assign      gpio        =       2'b00;    
assign      fifo_wr     =       (rd_n == 1'b0) && (rxf_n == 1'b0);
assign      data_wr     =       (state == READ) ? data : 16'hzzzz;
assign      data_req    =       ~((wr_n == 1'b0) && (txf_n == 1'b0));
assign      data        =       (data_req == 1'b0) ? data_o : 16'hzzzz;
assign      be          =       (state == WRITE) ? 2'b11 : 2'bzz;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        state       <=          IDLE;
    else case(state)
        IDLE    :   state       <=          JUDGE;
        JUDGE   :   if(rxf_n == 1'b0)
                        state       <=          READ;
                    else if(txf_n == 1'b0)
                        state       <=          WRITE;
                    else
                        state       <=          JUDGE;                        
        WRITE   :   if(txf_n == 1'b1)
                        state       <=          JUDGE;
                    else
                        state       <=          WRITE;                        
        READ    :   if(rxf_n == 1'b1)
                        state       <=          JUDGE;
                    else
                        state       <=          READ;
        default :   state       <=          IDLE;
    endcase

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        oe_n        <=          1'b1;     
    else if(state == READ && rxf_n == 1'b1)
        oe_n        <=          1'b1;
    else if(state == READ)
        oe_n        <=          1'b0;
    else
        oe_n        <=          oe_n;
        
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        rd_n        <=          1'b1;
    else if(state == READ && rxf_n == 1'b1)
        rd_n        <=          1'b1;
    else if(state == READ && oe_n == 1'b0)
        rd_n        <=          1'b0;
    else
        rd_n        <=          rd_n;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        wr_n        <=          1'b1;
    else if(state == WRITE && txf_n == 1'b1)
        wr_n        <=          1'b1;
    else if(state == WRITE)
        wr_n        <=          1'b0;
    else
        wr_n        <=          wr_n;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        col_cnt     <=          13'd0;
    else if(data_req == 1'b0 && col_cnt == COL_NUM-1)
        col_cnt     <=          13'd0;
    else if(data_req == 1'b0)
        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     <=          13'd0;
    else if(row_cnt == ROW_NUM-1 && data_req == 1'b0 && col_cnt == COL_NUM-1)
        row_cnt     <=          13'd0;
    else if(data_req == 1'b0 && col_cnt == COL_NUM-1)
        row_cnt     <=          row_cnt + 1'b1;
    else
        row_cnt     <=          row_cnt;
        
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        x_min_r     <=          COL_NUM - 1'b1;
    else if(po_flag == 1'b1)
        x_min_r     <=          x_min;
    else
        x_min_r     <=          x_min_r;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        x_max_r     <=          0;
    else if(po_flag == 1'b1)
        x_max_r     <=          x_max;
    else
        x_max_r     <=          x_max_r;          
    
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        y_min_r     <=          ROW_NUM - 1'b1;
    else if(po_flag == 1'b1)
        y_min_r     <=          y_min;
    else
        y_min_r     <=          y_min_r;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        y_max_r     <=          0;
    else if(po_flag == 1'b1)
        y_max_r     <=          y_max;
    else
        y_max_r     <=          y_max_r; 
          
always @(*)
    if(row_cnt == y_min_r && col_cnt >= x_min_r*2 && col_cnt < x_max_r*2)
        data_o      <=          16'hffff;
    else if(row_cnt == y_max_r && col_cnt >= x_min_r*2 && col_cnt < x_max_r*2)      
        data_o      <=          16'hffff;
    else if((col_cnt >= x_min_r*2 && col_cnt < (x_min_r+1)*2) && row_cnt >= y_min_r && row_cnt < y_max_r) 
        data_o      <=          16'hffff; 
    else if((col_cnt >= x_max_r*2 && col_cnt < (x_max_r+1)*2) && row_cnt >= y_min_r && row_cnt < y_max_r)
        data_o      <=          16'hffff;
    else if(row_cnt == y_min_r && col_cnt >= x_min_r*2 && col_cnt < x_max_r*2)
        data_o      <=          16'hffff;
    else if(row_cnt == y_max_r && col_cnt >= x_min_r*2 && col_cnt < x_max_r*2)      
        data_o      <=          16'hffff;
    else  
        data_o      <=          data_in;

//========================================================================================\
//*******************************     Debug    **********************************
//========================================================================================/
ila_0 ila_0_inst (
    .clk                    (sclk                       ), // input wire clk


    .probe0                 (x_min_r                    ), // input wire [10:0]  probe0  
    .probe1                 (x_max_r                    ), // input wire [10:0]  probe1 
    .probe2                 (y_min_r                    ), // input wire [10:0]  probe2 
    .probe3                 (y_max_r                    ), // input wire [10:0]  probe3 
    .probe4                 (po_flag                    ), // input wire [0:0]  probe4 
    .probe5                 (row_cnt                    ), // input wire [12:0]  probe5 
    .probe6                 (col_cnt                    ), // input wire [12:0]  probe6 
    .probe7                 (data_o                     ) // input wire [15:0]  probe7
);


endmodule

最终图像结果

我们最终实验的结果如下:
在这里插入图片描述
从上面的图像可以看出我们成功的实现了图像定位。

这里因为CSDN博客字数的限制,工程源码我们将在第二篇博客中给出。需要的同学可以自取。

总结

创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。原工程在群中,需要的同学可以进群自取。或者对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
在这里插入图片描述

基于FPGA的肤色人脸检测是一种通过使用FPGA芯片实现的人脸识别技术。这种技术主要包括以下几个步骤。 首先,进行滤波处理。在人脸图像中,可能存在一些黑点或者误检测的区域,这些都会导致识别失败。为了解决这个问题,可以使用中值滤波以及腐蚀和膨胀等处理方法对图像进行预处理,以去除噪声和不必要的区域。 其次,利用肤色检测模型进行人脸肤色识别。在肤色检测模型中,使用了一些特定的算法和技术,通过分析图像中的颜色信息来确定人脸的位置和区域。FPGA通过实时并行处理的能力,可以高效地对图像进行肤色检测,并快速准确地定位人脸区域。 最后,根据定位结果进行图像处理和最终的人脸识别。在人脸定位之后,可以根据具体的需求对人脸图像进行进一步的处理,例如人脸特征提取和比对等操作。这些处理步骤都可以在FPGA上进行实现,以提高处理速度和效率。 综上所述,基于FPGA的肤色人脸检测通过滤波处理和肤色检测模型等步骤,可以实现对人脸图像的快速识别和定位。该技术具有高效、实时性和可靠性的特点,适用于各种人脸识别应用场景。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [FPGA图像处理学习——基于肤色的人脸识别](https://blog.csdn.net/H19981118/article/details/125762837)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [基于FPGA人脸检测(1)](https://blog.csdn.net/zhangningning1996/article/details/105653305)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值