⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minutia.c

📁 指纹识别 C代码
💻 C
字号:
/*############################################################################# * 文件名:minutia.c * 功能:  细节点的一些函数接口 * modified by  PRTsinghua@hotmail.com#############################################################################*/#include <string.h>#include <stdlib.h>#include <math.h>#include "minutia.h"typedef struct iFvsMinutiaSet_t{    FvsInt_t     nbminutia;     FvsInt_t     tablesize;    FvsMinutia_t ptable[1]; } iFvsMinutiaSet_t;/******************************************************************************  * 功能:创建一个细节点集合  * 参数:size  集合的大小  * 返回:若失败,返回空;否则返回新的对象句柄******************************************************************************/FvsMinutiaSet_t MinutiaSetCreate(const FvsInt_t size){    iFvsMinutiaSet_t* p = NULL;    p = (iFvsMinutiaSet_t*)malloc(sizeof(iFvsMinutiaSet_t)    				+size*sizeof(FvsMinutia_t));    if (p!=NULL)    {       	/* 表中无细节点 */        p->nbminutia = 0;        p->tablesize = size;    }        return (FvsMinutiaSet_t)p;}/******************************************************************************  * 功能:销毁细节点集合。  *       一旦销毁,该对象不再可以为任何函数所用,直到重新申请。  * 参数:minutia      细节点集合  * 返回:无******************************************************************************/void MinutiaSetDestroy(FvsMinutiaSet_t minutia){    iFvsMinutiaSet_t* p = NULL;    if (minutia==NULL)        return;    p = minutia;    free(p);}/******************************************************************************  * 功能:获得细节点集合的大小  * 参数:minutia      细节点集合  * 返回:细节点集合大小******************************************************************************/FvsInt_t MinutiaSetGetSize(const FvsMinutiaSet_t min){    const iFvsMinutiaSet_t* minutia = (iFvsMinutiaSet_t*)min;    FvsInt_t nret = 0;        if (minutia!=NULL)        nret = minutia->tablesize;    return nret;}/******************************************************************************  * 功能:细节点集合的实际元素个数  * 参数:minutia      细节点集合  * 返回:元素个数******************************************************************************/FvsInt_t MinutiaSetGetCount(const FvsMinutiaSet_t min){    const iFvsMinutiaSet_t* minutia = (iFvsMinutiaSet_t*)min;    FvsInt_t nret = 0;        if (minutia!=NULL)        nret = minutia->nbminutia;    return nret;}/******************************************************************************  * 功能:返回细节点集合的数据缓冲区指针  * 参数:minutia      细节点集合  * 返回:指针******************************************************************************/FvsMinutia_t* MinutiaSetGetBuffer(FvsMinutiaSet_t min){    iFvsMinutiaSet_t* minutia = (iFvsMinutiaSet_t*)min;    FvsMinutia_t* pret = NULL;    if (minutia!=NULL)        pret = minutia->ptable;    return pret;}/******************************************************************************  * 功能:清空细节点集合  * 参数:minutia      细节点集合  * 返回:错误编号******************************************************************************/FvsError_t MinutiaSetEmpty(FvsMinutiaSet_t min){    iFvsMinutiaSet_t* minutia = (iFvsMinutiaSet_t*)min;    FvsError_t nRet = FvsOK;    if (minutia!=NULL)        minutia->nbminutia = 0;    else        nRet = FvsMemory;    return nRet;}/******************************************************************************  * 功能:在集合中添加一个细节点,如果满了,返回一个错误  * 参数:minutia      细节点集合  *       x            细节点的X坐标  *       y            细节点的Y坐标  *       type         细节点类型  *       angle        角度  * 返回:错误编号******************************************************************************/FvsError_t MinutiaSetAdd(FvsMinutiaSet_t min,       const FvsFloat_t x, const FvsFloat_t y,       const FvsMinutiaType_t type, const FvsFloat_t angle){    iFvsMinutiaSet_t* minutia = (iFvsMinutiaSet_t*)min;    FvsError_t nRet = FvsOK;    if (minutia->nbminutia < minutia->tablesize)    {        minutia->ptable[minutia->nbminutia].x       = x;        minutia->ptable[minutia->nbminutia].y       = y;        minutia->ptable[minutia->nbminutia].type    = type;        minutia->ptable[minutia->nbminutia].angle   = angle;        minutia->nbminutia++;    }    else        /* 表中无空间 */        nRet = FvsMemory;    return nRet;}static FvsError_t MinutiaSetCheckClean(FvsMinutiaSet_t min){    iFvsMinutiaSet_t* minutia = (iFvsMinutiaSet_t*)min;    FvsError_t    nRet = FvsOK;    FvsFloat_t    tx, ty, ta;    FvsInt_t      i, j;    FvsMinutia_t* mi, *mj;    tx = 4.0;    ty = 4.0;    ta = 0.5;    if (minutia!=NULL && minutia->nbminutia > 1)    {        /* 检验表中是否已有该细节点 */        for (j = 0;   j < minutia->nbminutia; j++)        for (i = j+1; i < minutia->nbminutia; i++)        {            mi = minutia->ptable + i;            mj = minutia->ptable + j;            /* 比较细节点i,j */            /* 规则 1: 相似的细节点彼此靠近 -> 删除一个 */            if ( (fabs(mi->x     - mj->x    ) < tx) &&                 (fabs(mi->y     - mj->y    ) < ty) &&                 (fabs(mi->angle - mj->angle) < ta)               )            {                minutia->nbminutia--;                *mi = minutia->ptable[minutia->nbminutia];            }            /* 规则 2: 方向相反,距离靠近 -> 同时删除 */        }    }    else        /* 表中无空间 */        nRet = FvsMemory;    return nRet;}#define P(x,y)      p[(x)+(y)*pitch]/******************************************************************************  * 功能:在图像中画出细节点,不改变背景  * 参数:minutia      细节点集合  *       image        指纹图像  * 返回:错误编号******************************************************************************/FvsError_t MinutiaSetDraw(const FvsMinutiaSet_t min, FvsImage_t image){    FvsInt_t w       = ImageGetWidth(image);    FvsInt_t h       = ImageGetHeight(image);    FvsInt_t pitch   = ImageGetPitch(image);    FvsByte_t* p     = ImageGetBuffer(image);    FvsInt_t n, x, y;    FvsFloat_t fx, fy;    FvsMinutia_t* minutia = MinutiaSetGetBuffer(min);    FvsInt_t nbminutia    = MinutiaSetGetCount(min);    if (minutia==NULL || p==NULL)        return FvsMemory;    /* 画出每个细节点 */    for (n = 0; n < nbminutia; n++)    {        x = (FvsInt_t)minutia[n].x;        y = (FvsInt_t)minutia[n].y;        if (x<w-5 && x>4)        {            if (y<h-5 && y>4)            {                switch (minutia[n].type)                {                case FvsMinutiaTypeEnding:                    P(x,y)    = 0xFF;                    P(x-1, y) = 0xA0;                    P(x+1, y) = 0xA0;                    P(x, y-1) = 0xA0;                    P(x, y+1) = 0xA0;                    break;                case FvsMinutiaTypeBranching:                    P(x,y)    = 0xFF;                    P(x-1, y-1) = 0xA0;                    P(x+1, y-1) = 0xA0;                    P(x-1, y+1) = 0xA0;                    P(x+1, y+1) = 0xA0;                    break;                default:                    continue;                }                fx = sin(minutia[n].angle);                fy = -cos(minutia[n].angle);                P(x+(int32_t)(fx)    ,y+(int32_t)(fy)    ) = 0xFF;                P(x+(int32_t)(fx*2.0),y+(int32_t)(fy*2.0)) = 0xFF;                P(x+(int32_t)(fx*3.0),y+(int32_t)(fy*3.0)) = 0xFF;                P(x+(int32_t)(fx*4.0),y+(int32_t)(fy*4.0)) = 0xFF;                P(x+(int32_t)(fx*5.0),y+(int32_t)(fy*5.0)) = 0xFF;            }        }    }    return FvsOK;}/* 宏定义 */#define P1  P(x  ,y-1)#define P2  P(x+1,y-1)#define P3  P(x+1,y  )#define P4  P(x+1,y+1)#define P5  P(x  ,y+1)#define P6  P(x-1,y+1)#define P7  P(x-1,y  )#define P8  P(x-1,y-1)/******************************************************************************  * 功能:从细化图像中提取细节点,并储存到集合中。  *       申请的细节点集合必须足够大,如果太小了,满了后会停止搜索细节点。  * 参数:minutia      细节点集合,用来保存细节点  *       image        细化后的图像  *       direction    用来计算方向用  *       mask         用来表示有效的指纹区域  * 返回:错误编号******************************************************************************/FvsError_t MinutiaSetExtract    (    FvsMinutiaSet_t       minutia,    const FvsImage_t      image,    const FvsFloatField_t direction,    const FvsImage_t      mask    ){    FvsInt_t w      = ImageGetWidth(image);    FvsInt_t h      = ImageGetHeight(image);    FvsInt_t pitch  = ImageGetPitch(image);    FvsInt_t pitchm = ImageGetPitch(mask);    FvsByte_t* p    = ImageGetBuffer(image);    FvsByte_t* m    = ImageGetBuffer(mask);    FvsInt_t   x, y;    FvsFloat_t angle = 0.0;    FvsInt_t   whitecount;    if (m==NULL || p==NULL)        return FvsMemory;    (void)MinutiaSetEmpty(minutia);    /* 遍历图像,提取细节点 */    for (y = 1; y < h-1; y++)    for (x = 1; x < w-1; x++)    {        if (m[x+y*pitchm]==0)             continue;        if (P(x,y)==0xFF)        {            whitecount = 0;            if (P1!=0) whitecount++;            if (P2!=0) whitecount++;            if (P3!=0) whitecount++;            if (P4!=0) whitecount++;            if (P5!=0) whitecount++;            if (P6!=0) whitecount++;            if (P7!=0) whitecount++;            if (P8!=0) whitecount++;            switch(whitecount)            {            case 0:                /* 孤立点,忽略 */                break;            case 1:                /* 检测角度 */  	            angle = FloatFieldGetValue(direction, x, y);                (void)MinutiaSetAdd(minutia, (FvsFloat_t)x, (FvsFloat_t)y,                              FvsMinutiaTypeEnding, (FvsFloat_t)angle);                break;            case 2:                break;            default:                {     	            angle = FloatFieldGetValue(direction, x, y);                    (void)MinutiaSetAdd(minutia, (FvsFloat_t)x, (FvsFloat_t)y,                                  FvsMinutiaTypeBranching, (FvsFloat_t)angle);                }                break;            }        }    }    (void)MinutiaSetCheckClean(minutia);        return FvsOK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -