1.软件版本

MATLAB2013b,vivado2019.2

2.本算法理论知识

指纹识别技术是指使用取像设备读取指纹图像,通过识别软件提取出指纹图像中的特征数据,然后根据匹配算法得到的结果鉴别指纹所有人身份的生物特征识别技术。指纹识别系统主要涉及三大步骤:指纹图像预处理、特征提取、特征匹配三个部分,其中预处理部分又可分为归一化、图像滤波增强、二值化和细化等几个步骤。系统流程框图如图1-1所示。下面对这三个个部分做一下简单的介绍。

  1. 指纹的基本特征

指纹其实是比较复杂的。与人工处理不同,许多生物识别技术公司并不直接存储指纹的图象。多年来在各个公司及其研究机构产生了许多数字化的算法(美国有关法律认为,指纹图象属于个人隐私,因此不能直接存储指纹图象)。但指纹识别算法最终都归结为在指纹图象上找到并比对指纹的特征。

指纹识别系统中,通常采用全局和局部两种层次的结构特征。两枚指纹可能具有相同的全局特征,但局部特征却不可能完全相同。

  1. 全局特征

全局特征是指那些用人眼直接就可以观察到的特征,包括:基本纹路图案环型(loop),弓型(arch),螺旋型(whorl)如图2-1所示。其他的指纹图案都基于这三种基本图案。仅仅依靠图案类型来分辨指纹是远远不够的,这只是一个粗略的分类,但通过分类使得在大数据库中搜寻指纹更为方便。

模式区是指指纹上包括了总体特征的区域,即从模式区就能够分辨出指纹是属于那一种类型的。有的指纹识别算法只使用模式区的数据。Secure Touch的指纹识别算法使用了所取得的完整指纹而不仅仅是模式区进行分析和识别,如图2所示。

图2模式区

核心点位于指纹纹路的渐进中心,它在读取指纹和比对指纹时作为参考点。许多算法是基于核心点的,既只能处理和识别具有核心点的指纹。核心点对于Secure Touch的指纹识别算法很重要,但没有核心点的指纹它仍然能够处理,如图3所示。

图3核心点

三角点位于从核心点开始的第一个分叉点或者断点、或者两条纹路会聚处、孤立点、折转处,或者指向这些奇异点。三角点提供了指纹纹路的计数跟踪的开始之处,如图4所示。

指模式区内指纹纹路的数量。在计算指纹的纹数时,一般先在连接核心点和三角点,这条连线与指纹纹路相交的数量即可认为是指纹的纹数,如图2-5所示。

细节特征提取的方法分为两种:一种是从灰度图像中提取特征,另一种是从细化二值图像中提取特征。直接从灰度图像中提取特征的算法一般是对灰度指纹纹线进行跟踪,根据跟踪结果寻找特征的位置和判断特征的类型。这种方法省去了复杂的指纹图像预处理过程,但是特征提取的算法却十分复杂,而且由于噪声等因素影响,特征信息(位置、方向等)也不够准确。目前大多数系统采用第二种方法,从细化二值图像中提取特征,该方法比较简单,在得到可靠的细化二值图像后,只需要一个3×3的模板就可以将端点和分叉点提取出来。

特征点提取的好坏将直接影响匹配的结果。现实中,指纹输入时,由于汗渍、干燥、按压力度不同等影响,得到的指纹图像大都含有断纹、褶皱、模糊、灰度不均匀等质量问题,虽然经过预处理,图像质量会有所改观,但预处理算法对各个指纹的适应性和有效性也会不同,并且会引入新的噪声,因此得到的细化二值图像往往含有大量的伪特征点。伪特征点不仅会影响匹配的速度,严重的会影响整个识别的正确率。所以提取特征点后要进行去伪处理,尽可能滤除伪特征点、保留真特征点。实践中发现,伪特征点的数量一般占总特征数量的一半以上,所以去伪是必不可少的过程。去伪过程可以在两个阶段进行:一是在特征提取之前对细化二值图像进行平滑、去除毛刺、连接断纹等操作,然后提取特征作为真特征;另一种是在特征提取之后,根据特征之间的相互关系,尽可能准确的识别伪特征点并滤除它们。前者直接对图像进行修补,操作比较复杂,容易引入新的伪特征;后者对特征提取后的数据进行判断,识别比较麻烦,但是速度较快本文采用第二种方法,即从已提取的特征点中滤除伪特征,保留真特征。

3.部分核心代码

`timescale 1ns / 1ps
//
// Company:
// Engineer:       ThinkSpark(CJY)
//
// Create Date:    10:46:32 08/21/2009
// Design Name:
// Module Name:    spisensor
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//`define effectvalue   1module spisensor(//Outputcmd2tx_din_w,rd_data_cmd_w,send_rd_spidata_cmd_n_w,clk180,        //spi transfer enableSCK_CPOL_0,               //clk for slavesend_n_w,               tx_rd_en_w,tx_wr_en_w,rx_wr_en_w,locked_out0,clk_24MHz,div10_cnt_w,sck_cnt8_w,//Inputrx_full_n,rx_first_n,rx_empty_n,clk,                //system clockrst);output [7:0]     cmd2tx_din_w;
output [7:0]     rd_data_cmd_w;
output           SCK_CPOL_0;
output           clk180;
output           send_n_w;
output           tx_wr_en_w;
output           tx_rd_en_w;
output           rx_wr_en_w;
output           locked_out0;
output           clk_24MHz;
output [3:0]     div10_cnt_w;
output [2:0]     sck_cnt8_w;
output           send_rd_spidata_cmd_n_w;input            clk;
input            rst;input            rx_full_n;
input            rx_empty_n;
input            rx_first_n;reg   [7:0]      cmdpad[31:0];    //filled with commands to be sent to slave after initialization
reg   [7:0]      rd_data_cmd_pad[1:0];
reg   [7:0]      cmd2tx_din;
reg   [7:0]      rd_data_cmd;
reg   [3:0]      div10_cnt;      //the time while div10_cnt=0 and div10_cnt=0- equals to an SCK period
reg   [2:0]      sck_cnt8;       //sck_cnt8=7 indicates that 8bits have been transferredreg   [3:0]      dcm_rst_delaycnt;
reg   [1:0]      rd_spidata_cmd_cnt;
reg              rd_spidata_cmd_cnt_en;
reg              send_rd_spidata_cmd_n;
reg              rd_data_cmd_rd_en;reg   [15:0]     bytecnt;
reg   [5:0]      incr;
reg              tx_wr_en;
reg              tx_rd_en;
reg              rx_wr_en;
reg              transmision_done;
reg              addr;reg              delaycnt_ctrl_n;
reg              transfer_n;    //data transfer enable bit,active low
reg              send_n;        //data send enable bit,active low
reg              recv_n;        //data receive enable bit,active lowreg    [7:0]     pre_state;
reg    [7:0]     nx_state;wire             clk0_out0;
wire             locked_out0;
wire             clk0_out1;
wire             locked_out1;wire             clk_24MHz;
wire             clk180;
wire             SCK_CPOL_0;
wire             SCK_CPOL_1;
wire             send_n_w;
//wire             transfer_n_w;
wire             tx_rd_en_w;
wire             tx_wr_en_w;
wire             rx_wr_en_w;
wire  [7:0]      cmd2tx_din_w;
wire  [3:0]      div10_cnt_w;
wire  [2:0]      sck_cnt8_w;
wire             send_rd_spidata_cmd_n_w;       parameter        idle                     = 8'b00000000,cmd2fifo                 = 8'b00000001,sensor_initial           = 8'b00000010,rd_sensor                = 8'b00000100,rd_spistat               = 8'b00001000,rd_spidata               = 8'b00010000,send_data2uart           = 8'b00100000,last_data2uart           = 8'b01000000,spi_stop                 = 8'b10000000;dcm0 mydcm0 (.CLKIN_IN(clk), .RST_IN(transfer_n), .CLKFX_OUT(SCK_CPOL_1), .CLKFX180_OUT(SCK_CPOL_0),    .CLK0_OUT(), .LOCKED_OUT(locked_out0));    dcm1 mydcm1 (.CLKIN_IN(clk), .CLKFX_OUT(clk_24MHz),    .CLK0_OUT(), .CLK180_OUT(clk180), .LOCKED_OUT(locked_out1));
//assign transfer_n_w =transfer_n; assign tx_wr_en_w=tx_wr_en;
assign tx_rd_en_w=tx_rd_en;
assign rx_wr_en_w=rx_wr_en;
assign send_n_w  =send_n;
assign cmd2tx_din_w=cmd2tx_din;
assign rd_data_cmd_w = rd_data_cmd;assign div10_cnt_w = div10_cnt;
assign sck_cnt8_w  = sck_cnt8;
assign send_rd_spidata_cmd_n_w = send_rd_spidata_cmd_n;//initialize cmdpad and transfer data in pad to Tx_fifo
always @(posedge clk)
beginif(rst == `effectvalue)begincmdpad[0] <= 8'h75;cmdpad[1] <= 8'h7F;cmdpad[2] <= 8'h76;cmdpad[3] <= 8'h02;cmdpad[4] <= 8'h77;cmdpad[5] <= 8'h01;cmdpad[6] <= 8'h11;cmdpad[7] <= 8'h00;cmdpad[8] <= 8'h21;cmdpad[9] <= 8'h00;cmdpad[10] <= 8'h20;cmdpad[11] <= 8'h00;cmdpad[12] <= 8'h50;   cmdpad[13] <= 8'h00;cmdpad[14] <= 8'h00;cmdpad[15] <= 8'h00;endend     always @(posedge clk)
beginif(rst == `effectvalue)beginrd_data_cmd_pad[0] <= 8'h20;rd_data_cmd_pad[1] <= 8'h00;end
endalways @(posedge clk)
beginif(rst == `effectvalue)cmd2tx_din <= 8'b0;else        cmd2tx_din <= cmdpad[incr];
end//address point to data be wrote to Tx_fifo
always @(posedge clk)
beginif(rst == `effectvalue)incr <= 6'b0;   else if(incr == 31)  incr <= 31 ;else   incr <= incr + 1;
end//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//transfer_n-\________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//clk        |--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|
//div10_cnt   [  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ]
//SCK       XXXXXXX________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/
//sck_cnt8         [00000000000000000000000000000000000000000000000000000][1111111111111111111111111111111111111111111111111111111111][2222222222222222222222222222222222222222222222222222222222][3333333333333333333333333333333333333333333333333333333333][4444444444444444444444444444444444444444444444444444444444][5555555555555555555555555555555555555555555555555555555555][6666666666666666666666666666666666666666666666666666666666][7777777777777777777777777777777777777777777777777777777777][0000000000000000000000000000000000000000000000000000000000][11111111111111111111111111111111111111]
//tx_rd_en      ------|_____|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\_____/----------------------------------------------------------------------------------
//tx_shifterOOOOOOOOOOOOOOOOOOO[            d7 d6 d5 d4 d3 d2 d1 d0      ][         d6 d5 d4 d3 d2 d1 d0 0                           ][                  d5 d4 d3 d2 d1 d0 0 0                   ][                  d4 d3 d2 d1 d0 0 0 0                    ][                    d3 d2 d1 d0 0 0 0 0                   ][                        d2 d1 d0 0 0 0 0 0                ][                  d1  d0  0  0  0  0  0  0                ][                      d0  0  0  0  0  0  0  0                               ][     d7 d6 d5 d4 d3 d2 d1 d0            ][           d6 d5 d4 d3 d2 d1 d0 0 ]
//MOSI     OOOOOOOOOOOOOO000000000000000000[----------------------------d7----------------------------][----------------------------d6----------------------------][----------------------------d5----------------------------][----------------------------d4----------------------------][----------------------------d3----------------------------][----------------------------d2----------------------------][----------------------------d1----------------------------][----------------------------d0----------------------------][----------------------------d7----------------------------][--d6--]
//MISO  XXXXX[----------------------------D7-----------------------------][----------------------------D6----------------------------][----------------------------D5----------------------------][----------------------------D4----------------------------][----------------------------D3----------------------------][----------------------------D2----------------------------][----------------------------D1----------------------------][----------------------------D0----------------------------][----------------------------D7----------------------------][----------------------------D7--------
//rx_shifter0000000000000000000000000000000[                        0 0 0 0 0 0 0 D7                  ][                        0 0 0 0 0 0 D7 D6                 ][                       0 0 0 0 0 D7 D6 D5                 ][                        0 0 0 0 D7 D6 D5 D4               ][                      0 0 0 D7 D6 D5 D4 D3                ][                    0 0 D7 D6 D5 D4 D3 D2                 ][                       0 D7 D6 D5 D4 D3 D2 D1             ][                     D7 D6 D5 D4 D3 D2 D1 D0              ][                        0 0 0 0 0 0 0 D7                  ]
//rx_wr_en------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\_____/-----------------------------------------------------------------
//----------------------------------------------------------------------------------------//----------------------------------------------------------------------------------------
//the time while div10_cnt=0 and div10_cnt=0- equals to an SCK period
always @(posedge clk)
beginif( (rst == `effectvalue) || (transfer_n == 1'b1) )div10_cnt <= 4'b0;else if(div10_cnt == 9)div10_cnt <= 4'b0;else if(locked_out0 == 1'b1)div10_cnt <= div10_cnt + 1;
end//----------------------------------------------------------------------------------------
//3bits counter for SCK cycles, one counting cycle indicates one Byte transmission done
always @ (posedge clk)
beginif( (rst == `effectvalue) || (transfer_n == 1'b1) )sck_cnt8 <= 3'b0;else if( (div10_cnt == 9) && (locked_out0 == 1'b1) )          //?????????????????????sck_cnt8 <= sck_cnt8 + 1;end//--------------------------------------------------------------------------------------------------
//------------control reading from tx_fifo and writing to rx_fifo----------------------------------
//---------------------------------begin-----------------------------------------------------------
always @(posedge clk180)                      //---- @posedge clk180 will work more precisely-----
beginif( (rst == `effectvalue) || (send_n == 1'b1) )        //not to read data from tx_fifo when send_n=1tx_rd_en <= 1'b1;else if( (locked_out0 == 1'b1) && (sck_cnt8 == 0) &&(div10_cnt == 0) )tx_rd_en <= 1'b0;elsetx_rd_en <= 1'b1;
endalways @(posedge clk180)
beginif( (rst == `effectvalue) || (send_rd_spidata_cmd_n == 1'b1) )rd_data_cmd_rd_en <= 1'b1;else if( (locked_out0 == 1'b1) && (sck_cnt8 == 0) &&(div10_cnt == 0) )rd_data_cmd_rd_en <= 1'b0;elserd_data_cmd_rd_en <= 1'b1;
endalways @(posedge clk)
beginif(rst == `effectvalue)rd_data_cmd <= 8'b0;else if(rd_data_cmd_rd_en == 1'b0)rd_data_cmd <= rd_data_cmd_pad[addr];
endalways @(posedge clk)
beginif(rst == `effectvalue)addr <= 1'b0;else if (rd_data_cmd_rd_en == 1'b0) addr <= ~addr;
endalways @(posedge clk)
beginif( (rst == `effectvalue) || (rx_full_n == 1'b0) )rd_spidata_cmd_cnt <= 2'b0;else if(rd_spidata_cmd_cnt == 2)rd_spidata_cmd_cnt <= 2;else if( (rd_spidata_cmd_cnt_en == 1'b0) && ( sck_cnt8 == 7 ) &&(div10_cnt == 9) )rd_spidata_cmd_cnt <= rd_spidata_cmd_cnt + 1;
end
///always @(posedge clk180)                                 //---- @posedge clk180 will work more precisely-----
beginif( (rst == `effectvalue) || (recv_n == 1'b1) )       //not to write to rx_fifo when recv_n=1rx_wr_en <= 1'b1;else if( (locked_out0 == 1'b1) && (sck_cnt8 == 7) &&(div10_cnt == 6)  )                          //rx_wr_en be active while div10_cnt=6 and sck_cnt8=7 can rx_wr_en <= 1'b0;                                  //leave some time space for bytecntelserx_wr_en <= 1'b1;
end//------------control reading from tx_fifo and writing to rx_fifo----------------------------------
//---------------------------------end-----------------------------------------------------------always @(posedge clk)
beginif( (rst == `effectvalue) || ( (transfer_n == 1'b1) && (transmision_done == 1'b1) ) )bytecnt <= 16'b0;   else if( (sck_cnt8 == 7) && ( div10_cnt == 7 ) )            // one more byte has been sent and received the momentbytecnt <= bytecnt + 1;                                   //sck_cnt8=7 and div10_cnt=7(as the wave showed following)else bytecnt <= bytecnt;
end always @(posedge clk)
beginif( rst == `effectvalue )transmision_done <= 1'b0;else if( (transmision_done == 1'b1) && (div10_cnt == 0) )transmision_done <= 1'b0;else if( (pre_state == sensor_initial) && (bytecnt == 6) )transmision_done <= 1'b1;else if( (pre_state == rd_sensor) && (bytecnt == 370) )transmision_done <= 1'b1;else if( (pre_state == rd_spistat) && (bytecnt == 3) )transmision_done <= 1'b1;//else if( (pre_state == rd_regs) && (bytecnt == 18) )//transmision_done <= 1'b1;else if( (pre_state == rd_spidata) && (bytecnt == 31352) )transmision_done <= 1'b1;endalways @( posedge clk )
beginif( (rst == `effectvalue) || (transmision_done == 1'b1) || (rx_full_n == 1'b0) )dcm_rst_delaycnt <= 4'b0;else if( dcm_rst_delaycnt == 9 )dcm_rst_delaycnt <= 9;else if( delaycnt_ctrl_n == 1'b0 )dcm_rst_delaycnt <= dcm_rst_delaycnt + 1;
end//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//transfer_n-\________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
//clk        |--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|--|__|
//div10_cnt   [  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ][  6 ][  7 ][  8 ][  9 ][  0 ][  1 ][  2 ][  3 ][  4 ][  5 ]
//SCK       XXXXXXX________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/-----------------------------\_____________________________/
//sck_cnt8         [00000000000000000000000000000000000000000000000000000][1111111111111111111111111111111111111111111111111111111111][2222222222222222222222222222222222222222222222222222222222][3333333333333333333333333333333333333333333333333333333333][4444444444444444444444444444444444444444444444444444444444][5555555555555555555555555555555555555555555555555555555555][6666666666666666666666666666666666666666666666666666666666][7777777777777777777777777777777777777777777777777777777777][0000000000000000000000000000000000000000000000000000000000][11111111111111111111111111111111111111]
//tx_rd_en      ------\_____/-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\_____/----------------------------------------------------------------------------------
//tx_shifterOOOOOOOOOOOOOOOOOOO[            d7 d6 d5 d4 d3 d2 d1 d0      ][         d6 d5 d4 d3 d2 d1 d0 0                           ][                  d5 d4 d3 d2 d1 d0 0 0                   ][                  d4 d3 d2 d1 d0 0 0 0                    ][                    d3 d2 d1 d0 0 0 0 0                   ][                        d2 d1 d0 0 0 0 0 0                ][                  d1  d0  0  0  0  0  0  0                ][                      d0  0  0  0  0  0  0  0                               ][     d7 d6 d5 d4 d3 d2 d1 d0            ][           d6 d5 d4 d3 d2 d1 d0 0 ]
//MOSI     OOOOOOOOOOOOOO000000000000000000[----------------------------d7----------------------------][----------------------------d6----------------------------][----------------------------d5----------------------------][----------------------------d4----------------------------][----------------------------d3----------------------------][----------------------------d2----------------------------][----------------------------d1----------------------------][----------------------------d0----------------------------][----------------------------d7----------------------------][--d6--]
//MISO  XXXXX[----------------------------D7-----------------------------][----------------------------D6----------------------------][----------------------------D5----------------------------][----------------------------D4----------------------------][----------------------------D3----------------------------][----------------------------D2----------------------------][----------------------------D1----------------------------][----------------------------D0----------------------------][----------------------------D7----------------------------][----------------------------D7--------
//rx_shifter0000000000000000000000000000000[                        0 0 0 0 0 0 0 D7                  ][                        0 0 0 0 0 0 D7 D6                 ][                       0 0 0 0 0 D7 D6 D5                 ][                        0 0 0 0 D7 D6 D5 D4               ][                      0 0 0 D7 D6 D5 D4 D3                ][                    0 0 D7 D6 D5 D4 D3 D2                 ][                       0 D7 D6 D5 D4 D3 D2 D1             ][                     D7 D6 D5 D4 D3 D2 D1 D0              ][                        0 0 0 0 0 0 0 D7                  ]
//rx_wr_en------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\_____/-------------------------------------------------------------
//----------------------------------------------------------------------------------------//-------------------------------------------------------------------------------
//-------------------------------FSM---------------------------------------------
always @(posedge clk)
beginif(rst == `effectvalue)pre_state <= idle;elsepre_state <= nx_state;
end//-----------------------------------------------------------------------
//FSM state transform---------------------------------------------------
always @(pre_state or div10_cnt or incr or transmision_done or rx_empty_n or rx_full_n)
begincase(pre_state)idle          : nx_state = cmd2fifo;cmd2fifo      : beginif( incr == 31)                      //all 16 commands in cmdpad were wrote to Tx_fifo when incr=15nx_state = sensor_initial;elsenx_state = cmd2fifo;                         endsensor_initial: beginif( (transmision_done == 1'b1) && (div10_cnt == 0))nx_state = rd_sensor;elsenx_state = sensor_initial;                       endrd_sensor      :beginif( (transmision_done == 1'b1) && (div10_cnt == 0))nx_state = rd_spistat;elsenx_state = rd_sensor;endrd_spistat     :beginif( (transmision_done == 1'b1) && (div10_cnt == 0))nx_state = rd_spidata;elsenx_state = rd_spistat;endrd_spidata     :beginif( (transmision_done == 1'b1) && (div10_cnt == 0))nx_state = last_data2uart;else if(rx_full_n == 1'b0)                             //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!               nx_state = send_data2uart;elsenx_state = rd_spidata;endsend_data2uart:beginif(rx_empty_n == 1'b0)nx_state = rd_spidata;elsenx_state = send_data2uart;endlast_data2uart:beginif(rx_empty_n == 1'b0)nx_state = spi_stop;elsenx_state = last_data2uart;endspi_stop       :   nx_state = spi_stop; default        :   nx_state = idle;endcase
end
//---------FSM state transform-----------------------------------------------
//-----------------------------------------------------------------------------//-------------------------------------------
//FSM control signals output
always @(pre_state  or rx_full_n or div10_cnt orincr  or bytecnt or dcm_rst_delaycnt orrd_spidata_cmd_cnt or rx_empty_n or rx_first_n )
begincase(pre_state)idle            :begintx_wr_en    = 1'b1;transfer_n  = 1'b1;send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endcmd2fifo        :beginif( (incr == 0) && (incr == 31) )begintx_wr_en    = 1'b1;transfer_n  = 1'b1;send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelsebegin       tx_wr_en    = 1'b0;transfer_n  = 1'b1;send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;end                             endsensor_initial  :beginif( (bytecnt == 6) && ( div10_cnt == 9) )begintx_wr_en    = 1'b1;transfer_n  = 1'b1;            // this will reset bytecnt when div10_cnt=9 send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;                             endelse if( dcm_rst_delaycnt <= 8)begintx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b0;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;                           endelse if(dcm_rst_delaycnt == 9)begintx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b0;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelse begintx_wr_en    = 1'b1;transfer_n  = 1'b1;            // this will reset bytecnt when div10_cnt=9 send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endendrd_sensor       :beginif( dcm_rst_delaycnt <= 8)begintx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b0;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelse if( (bytecnt < 2 ) && (dcm_rst_delaycnt == 9) )begin tx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b0;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelse if( (bytecnt >=2) && (bytecnt <=370) && (dcm_rst_delaycnt == 9))begintx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelsebegintx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endendrd_spistat      :beginif( dcm_rst_delaycnt <= 8)begintx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b0;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelse if( (bytecnt < 2) && (dcm_rst_delaycnt == 9) )begin tx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b0;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelse if( (bytecnt >= 2) && (dcm_rst_delaycnt == 9) )begin                            tx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b1;recv_n      = 1'b0;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelsebegin                              tx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endendrd_spidata      :beginif( dcm_rst_delaycnt <= 8)begintx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b0;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelse if( (bytecnt > 10) && (rx_first_n == 1'b1) &&(rx_empty_n == 1'b0) && ( rd_spidata_cmd_cnt < 2 ) )begin   tx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b0;rd_spidata_cmd_cnt_en = 1'b0;endelse if( (bytecnt > 10) && (rd_spidata_cmd_cnt == 2) )begintx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b1;recv_n      = 1'b0;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelse if( (bytecnt < 2) && (dcm_rst_delaycnt == 9)  )  begin tx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b0;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelse if( (bytecnt >= 2) && (rx_full_n == 1'b1) )begin                            tx_wr_en    = 1'b1;transfer_n  = 1'b0;                   send_n      = 1'b1;recv_n      = 1'b0;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endelsebegin                              tx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endendsend_data2uart,last_data2uart, spi_stop        :begintx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;enddefault         : begintx_wr_en    = 1'b1;transfer_n  = 1'b1;                   send_n      = 1'b1;recv_n      = 1'b1;delaycnt_ctrl_n = 1'b1;send_rd_spidata_cmd_n = 1'b1;rd_spidata_cmd_cnt_en = 1'b1;endendcase
end
//FSM control signals output
//--------------------------------------------endmodule
%ProcessOfFingerPrint.m
clc;
clear;
clear all;
%--------------加载指纹文本文件-----------------------
fid=fopen('1x1.txt','r');
dd=fscanf(fid,'%x');
fclose(fid);
array=dd';
for i=0:199OriginFingerPrint(i+1,1:152)=array(i*152+1:i*152+152);
end
figure('name','OriginFingerPrint');
imshow(uint8(OriginFingerPrint));
%---------------灰度图像取反--------------------------
ReverseFingerPrint=255-OriginFingerPrint;
figure('name','ReverseFingerPrint');
imshow(uint8(ReverseFingerPrint));
%---------------进行二维适应性去噪过滤处理------------
FrontFilt=wiener2(ReverseFingerPrint,[3 3]);
figure('name','FrontFilt');
imshow(uint8(FrontFilt));
%---------------扩大图像的像素至400x304---------------
EnhanceFingerPrint=enhance_finger(FrontFilt);
%---------------取图像的中心点------------------------
[XofCenter,YofCenter] = centralizing(EnhanceFingerPrint);
figure('name','EnhanceFingerPrint');
imshow(uint8(EnhanceFingerPrint));
hold on;
plot(XofCenter,YofCenter,'or');
hold off;
%---------------二值化图像-----------------------------
[BinarizationFingerPrint,theta]=orientation(EnhanceFingerPrint);
figure('name','BinarizationFingerPrint');
imshow(uint8(BinarizationFingerPrint));
%----------------进行中值滤波处理----------------------
AfterFilt=median_filter(BinarizationFingerPrint);
figure('name','AfterFilt');
imshow(uint8(AfterFilt));
%----------------二值化图像细化处理--------------------
ThinFingerPrint=thinning(AfterFilt);
figure('name','ThinFingerPrint');
imshow(uint8(ThinFingerPrint));
%----------------找寻细化图像的特征点------------------
[Dpx,Dpy,Dpcount,Fpx,Fpy,Fpcount]=characterpoint(ThinFingerPrint);
hold on;
plot(Dpy,Dpx,'o');%特征端点用'o'标注
plot(Fpy,Fpx,'+');%特征分叉点用'+'标注
plot(XofCenter,YofCenter,'*r');%中心点用红色'*'标注
hold off;
%-----------------生成各特征点相对中心点的距离向量---------------
Dpcount=size(Dpx,2);
Fpcount=size(Fpx,2);
for i=1:DpcountDpdistant(i)=sqrt((Dpx(i)-YofCenter)^2+(Dpy(i)-XofCenter)^2);
end
for j=1:FpcountFpdistant(j)=sqrt((Fpx(j)-YofCenter)^2+(Fpy(j)-XofCenter)^2);
end
%------------------特征模板建立----------------------------------------------
for i=1:DpcountPointOfModel(i,1)=1;%特征端点分类为1PointOfModel(i,2)=Dpdistant(i);%特征端点相对中心点的距离向量PointOfModel(i,3)=theta(Dpx(i),Dpy(i))-theta(YofCenter,XofCenter);%特征端点相对中心点的方向向量
end
for i=Dpcount+1:Dpcount+FpcountPointOfModel(i,1)=2;%特征分叉点分类为2PointOfModel(i,2)=Fpdistant(i-Dpcount);%特征分叉点相对中心点的距离向量PointOfModel(i,3)=theta(Fpx(i-Dpcount),Fpy(i-Dpcount))-theta(YofCenter,XofCenter);%特征分叉点相对中心点的方向向量
end
%--------------------------------------------------------

4.操作步骤与仿真结论

  1. FSM模块:其主要的功能是在系统复位后初始化Tx FIFO(发送FIFO),即把随后要发送给SPI传感器的命令写入Tx FIFO内,然后在满足SPI传感器时序的前提下,FSM模块通过控制Tx_rd_en信号读出Tx FIFO里的命令并传送到SPI模块;在Rx FIFO接收指纹数据时,当数满标志位Rx_full_n有效后说明接收FIFO里的数据已满,这时FSM就会通过相关信号来控制SPI停止接收数据,当检测到Rx_empty_n有效后(接收FIFO已空),FSM就会发出相应的信号启动SPI继续接收数据,直到指纹数据全部接收完毕。
  2. Tx FIFO模块:主要功能是在初始化的时候装载待发命令,然后在Tx_rd_en信号的控制下把命令发送出去,因为总的命令数不超过FIFO的深度,所以无须空满标志位。
  3. SPI模块:其主要功能是在与外部传感器通信的时候向传感器提供时钟信号SCK,以及片选信号SS,其中SCK和SS信号最初由FSM产生并由FSM进行控制;当需要向传感器发送命令时,FSM会启动SCK和SS信号,同时SPI接受从Tx FIFO读出的命令并暂存到一个8bit移位寄存器tx_shifter[7:0]中,每过一个SCK周期发送一位到至MOSI,发送完1Byte后tx_shifter会重新装载新命令继续发送直到命令发送完毕;当SPI从传感器接收数据时,FSM会启动SCK和SS信号,SPI中移位寄存器rx_shifter[7:0]会在SCK的上升沿采集输入端口MISO的数据并移一位,每8个SCK时钟周期rx_shifter中的数据就会在FSM的控制下写入Rx FIFO,直到数据接收完毕。
  4. Rx FIFO模块:此模块的主要功能是对已接收到的指纹数据进行缓存,避免指纹的数据丢失,因为此系统中SPI串口的工作频率为5MHz,而UART串口的工作频率为38400Hz,UART从Rx FIFO取数据的速度远小于SPI往Rx FIFO中写数据的速度。Rx FIFO可以向UART和FSM提供数空和数满标志位rx_empty_n,和rx_full_n,因此SPI和UART可以协调工作。
  5. UART模块:些模块主要功能是和计算机进行通信,把接收到的指纹数据通过计算机的终端显示出来。当UART检测到rx_full_n有效后,就会发出读信号Rx_rd_en读出FIFO中的数据发送给计算机,当检测到rx_empty_n有效后停止。

5.参考文献

[1]赵锦明, 钱磊, 吴东. 一种基于FPGA指纹识别加速结构的设计与实现[J]. 网络空间安全, 2016, 7(005):59-64.

D234

6.完整源码获得方式

方式1:微信或者QQ联系博主

方式2:订阅MATLAB/FPGA教程,免费获得教程案例以及任意2份完整源码

【指纹识别】基于MATLAB/FPGA的指纹识别算法仿真实现相关推荐

  1. matlab指纹图像采集,基于MATLAB实现的指纹图像预处理

    西南民族大学学报·自然科学版第 34 卷第 4 期 Journal of Southwest University for Nationalities⋅Natural Science Edition ...

  2. matlab幼苗识别,基于MATLAB的植物幼苗识别

    基于MATLAB的植物幼苗识别(论文11000字,外文翻译) 摘要:杂草种类繁多,严重影响了农作物的生产与产量,使用图像处理技术识别区分杂草和作物幼苗已成为一种最科学最有效的方法.通过提取植物图像的有 ...

  3. 基于matlab的双音多频信号识别,基于MATLAB的双音多频信号识别

    年 第 期 计 算 机 系 统 应 用基于 丁 的双音多频信号识别 ① 刘艳芳 窦育强 张爱丽 河南师范大学 计算机与信息技术学院 河南 新乡 摘 要 关健 词 本文主要运用 对录制的双音多频信号进行 ...

  4. 基于matlab的信号能量检测算法仿真

    能量检测方法,即将接收到的模拟信号变为数字信号后,通过FFT变换,然后再进行,在现有的通信系统中,通常为ASK.PSK.FSK.QAM等,它们都由数字基带脉冲对周期性载波的参数进行调制.采样频率fs ...

  5. 基于matlab的立体图像编码解码算法仿真与分析

    欢迎订阅<FPGA学习入门100例教程>.<MATLAB学习入门100例教程> 目录 一.理论基础 二.核心程序 2.1 获得左右两个图像

  6. 基于MATLAB的LTEA载波聚合算法仿真

    目录 一.理论基础 二.案例背景 1.问题描述 2.思路流程 三.部分MATLAB仿真 四.仿真结论分析 五.参考文献 一.理论基础 在非连续载波聚合( 高频+低频) 场景下,载波衰减特性不同,聚合的 ...

  7. 基于matlab的GPS信号相关检测算法仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 全球定位系统(Global Positioning System,GPS),是一种以人造地球卫星为基 ...

  8. 基于matlab的自适应PSO优化算法仿真

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 粒子群优化算法(PSO),粒子群中的每一个粒子都代表一个问题的可能解, 通过粒子个体的简单行为,群体 ...

  9. 基于matlab的图像HOG特征提取算法仿真

    目录 1.算法概述 2.仿真效果 3.MATLAB仿真源码 1.算法概述 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来 ...

  10. 【中继功率分配】基于MATLAB的中继功率分配算法仿真

    1.软件版本 matlab2013b 2.本算法理论知识

最新文章

  1. 四款 5G 版 iPhone 12 齐发,支持北斗系统,你准备好了吗?
  2. Pet Shop4解密配置文件
  3. Transaction中的SQL死锁
  4. Java实现从Html文本中提取纯文本
  5. es文件浏览器怎么用_es文件浏览器电视版下载-es文件浏览器电视tv版下载v4.2.3.4 安卓最新版...
  6. 【转】SMIL基础教程(1)
  7. CSS居中对齐的各种方式
  8. Beyond Accuracy:Behavioral Testing of NLP Models with Checklist 论文阅读
  9. Centos7 搭建 Svn+ReviewBoard
  10. Linux多开微信,在Deepin V20/15.11系统下实现微信多开的方法
  11. mysql使用什么语句为指定_在MySQL中,可以使用_____语句来为指定数据库添加用户。...
  12. Word自动编号,掌握这几招,再也不用手动敲编号!
  13. linux 安装/卸载WPS
  14. 移动通信平台的搭建(可语音可视屏可收发短信)
  15. Hadoop运行模式
  16. snap处理哨兵2数据时报错dataType out of range!
  17. 智能投顾发展及相关信息
  18. python自动发弹幕_一个直播弹幕机器人诞生过程,Python制作自动发送弹幕小程序...
  19. python自学课堂_3D图示Python标准自学教程入门篇
  20. 舍弗勒牵头德国氢能项目,助力制氢技术产业化发展

热门文章

  1. Mac OS 使用asio库
  2. 中文手写输入法闪退问题
  3. 0基础学SQL(二)
  4. java项目ppt介绍_Java课设项目介绍及分析.ppt
  5. 当驾校学员遇上微信小程序
  6. weka安装需要java不_如何下载安装Weka机器学习工作平台
  7. 项目管理软件: 禅道、JIRA
  8. python rect用法,功能
  9. 趣味程序设计_打印日历
  10. 每个人都应该了解的金融小知识 -- 利率计算