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

📄 imagemanip.c

📁 指纹识别 C代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        FvsInt_t peak_pos[BLOCK_L];		/* 顶点			*/        FvsInt_t peak_cnt;				/* 顶点数目		*/        FvsFloat_t peak_freq;			/* 顶点频率		*/        FvsFloat_t Xsig[BLOCK_L];		/* x signature	*/        FvsFloat_t pmin, pmax;        memset(out,  0, size);        memset(freq, 0, size);        /* 1 - 图像分块  BLOCK_W x BLOCK_W - (16 x 16) */        for (y = BLOCK_L2; y < h-BLOCK_L2; y++)        for (x = BLOCK_L2; x < w-BLOCK_L2; x++)        {            /* 2 - 脊线方向的窗口 l x w (32 x 16) */            dir = orientation[(x+BLOCK_W2) + (y+BLOCK_W2)*w];            cosdir = -sin(dir);             sindir = cos(dir);            /* 3 - 计算 x-signature X[0], X[1], ... X[l-1] */            for (k = 0; k < BLOCK_L; k++)            {                Xsig[k] = 0.0;                for (d = 0; d < BLOCK_W; d++)                {                    u = (FvsInt_t)(x + (d-BLOCK_W2)*cosdir + (k-BLOCK_L2)*sindir);                    v = (FvsInt_t)(y + (d-BLOCK_W2)*sindir - (k-BLOCK_L2)*cosdir);                    /* clipping */                    if (u<0) u = 0; else if (u>w-1) u = w-1;                    if (v<0) v = 0; else if (v>h-1) v = h-1;                    Xsig[k] += p[u + (v*pitchi)];                }                Xsig[k] /= BLOCK_W;            }            /* 计算 T(i,j) */            /* 寻找 x signature 中的顶点 */            peak_cnt = 0;              pmax = pmin = Xsig[0];            for (k = 1; k < BLOCK_L; k++)            {                if (pmin>Xsig[k]) pmin = Xsig[k];                if (pmax<Xsig[k]) pmax = Xsig[k];            }            if ((pmax - pmin)>64.0)            {                for (k = 1; k < BLOCK_L-1; k++)                if ((Xsig[k-1] < Xsig[k]) && (Xsig[k] >= Xsig[k+1]))                {                    peak_pos[peak_cnt++] = k;                }            }            /* 计算均值 */            peak_freq = 0.0;            if (peak_cnt>=2)            {                for (k = 0; k < peak_cnt-1; k++)                    peak_freq += peak_pos[k+1]-peak_pos[k];                peak_freq /= peak_cnt-1;            }            /* 4 - 验证频率范围 [1/25-1/3] */            /*     可以扩大到 [1/30-1/2]   */            if (peak_freq > 30.0)                out[x+y*w] = 0.0;            else if (peak_freq < 2.0)                out[x+y*w] = 0.0;            else                out[x+y*w] = 1.0/peak_freq;        }        /* 5 - 未知点 */        for (y = BLOCK_L2; y < h-BLOCK_L2; y++)        for (x = BLOCK_L2; x < w-BLOCK_L2; x++)        {            if (out[x+y*w]<EPSILON)            {                if (out[x+(y-1)*w]>EPSILON)                {                    out[x+(y*w)] = out[x+(y-1)*w];                }                else                {                    if (out[x-1+(y*w)]>EPSILON)                        out[x+(y*w)] = out[x-1+(y*w)];                }            }        }        /* 6 - 频率插值 */        for (y = BLOCK_L2; y < h-BLOCK_L2; y++)        for (x = BLOCK_L2; x < w-BLOCK_L2; x++)        {            k = x + y*w;            peak_freq = 0.0;            for ( v = -LPSIZE; v <= LPSIZE; v++)            for ( u = -LPSIZE; u <= LPSIZE; u++)                peak_freq += out[(x+u)+(y+v)*w];            freq[k] = peak_freq*LPFACTOR;        }        free(out);    }    return nRet;}/******************************************************************************  * 功能:获取指纹图像的有效区域,以进行进一步的处理。  *       如果某个区域不可用用,则掩码置为0,包括如下区域:  *       边界,背景点,图像质量很差的区域。  *       有效区域的掩码置为255。  * 参数:image        指纹图像  *       direction    脊线方向  *       frequency    脊线频率  *       mask         输出的掩码  * 返回:错误编号******************************************************************************/FvsError_t FingerprintGetMask(const FvsImage_t image, 					const FvsFloatField_t direction,					const FvsFloatField_t frequency, FvsImage_t mask){    FvsError_t nRet = FvsOK;    FvsFloat_t freqmin = 1.0 / 25;    FvsFloat_t freqmax = 1.0 / 3;    /* 输入图像的宽度高度 */    FvsInt_t w      = ImageGetWidth (image);    FvsInt_t h      = ImageGetHeight(image);    FvsByte_t* out;    FvsInt_t pitchout;    FvsInt_t pos, posout, x, y;    FvsFloat_t* freq = FloatFieldGetBuffer(frequency);    if (freq==NULL)        return FvsMemory;    /* 需要做改进:检查 */    nRet = ImageSetSize(mask, w, h);    if (nRet==FvsOK)        nRet = ImageClear(mask);    out = ImageGetBuffer(mask);    if (out==NULL)        return FvsMemory;    if (nRet==FvsOK)    {    pitchout = ImageGetPitch(mask);    for (y = 0; y < h; y++)        for (x = 0; x < w; x++)        {            pos    = x + y * w;            posout = x + y * pitchout;            out[posout] = 0;            if (freq[pos] >= freqmin && freq[pos] <= freqmax)            {                out[posout] = 255;            }        }    /* 补洞 */    for (y = 0; y < 4; y++)        (void)ImageDilate(mask);    /* 去除边界 */    for (y = 0; y < 12; y++)        (void)ImageErode(mask);    }    return nRet;}/* 细化算法 */#undef P#define P(x,y)      ((x)+(y)*pitch)#define REMOVE_P    { p[P(x,y)]=0x80; changed = FvsTrue; }/******************************************************************************** 邻域点定义如下:**     9 2 3**     8 1 4**     7 5 6******************************************************************************//* 宏定义 */#define P1  p[P(x  ,y  )]#define P2  p[P(x  ,y-1)]#define P3  p[P(x+1,y-1)]#define P4  p[P(x+1,y  )]#define P5  p[P(x+1,y+1)]#define P6  p[P(x  ,y+1)]#define P7  p[P(x-1,y+1)]#define P8  p[P(x-1,y  )]#define P9  p[P(x-1,y-1)]FvsError_t ImageRemoveSpurs(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 x, y, n, t, c;    c = 0;        do     {	n = 0;    	for (y=1; y<h-1; y++)        for (x=1; x<w-1; x++)        {            if( p[P(x,y)]==0xFF)            {                t=0;                if (P3==0 && P2!=0 && P4==0) t++;                if (P5==0 && P4!=0 && P6==0) t++;                if (P7==0 && P6!=0 && P8==0) t++;                if (P9==0 && P8!=0 && P2==0) t++;                if (P3!=0 && P4==0) t++;                if (P5!=0 && P6==0) t++;                if (P7!=0 && P8==0) t++;                if (P9!=0 && P2==0) t++;                if (t==1)				{                    p[P(x,y)] = 0x80;		    		n++;	    				}            }        }		for (y=1; y<h-1; y++)        	for (x=1; x<w-1; x++)        	{            	if( p[P(x,y)]==0x80)	        	p[P(x,y)] = 0;			}       } while (n>0 && ++c < 5);            return FvsOK;}/* a) 验证其有2-6个邻点 */#define STEP_A  n = 0; /* 邻点个数 */ \                if (P2!=0) n++; if (P3!=0) n++; if (P4!=0) n++; if (P5!=0) n++; \                if (P6!=0) n++; if (P7!=0) n++; if (P8!=0) n++; if (P9!=0) n++; \                if (n>=2 && n<=6)/* b) 统计由0变1的个数 */#define STEP_B  t = 0; /* 变化的数目 */ \                if (P9==0 && P2!=0) t++; if (P2==0 && P3!=0) t++; \                if (P3==0 && P4!=0) t++; if (P4==0 && P5!=0) t++; \                if (P5==0 && P6!=0) t++; if (P6==0 && P7!=0) t++; \                if (P7==0 && P8!=0) t++; if (P8==0 && P9!=0) t++; \                if (t==1)/******************************************************************************  * 功能:细化指纹图像  *       图像必须是二值化过的(只包含0x00或oxFF)  *       该算法基于领域的判断,决定某个象素该移去还是保留  * 参数:image   指纹图像  * 返回:错误编号******************************************************************************/ FvsError_t ImageThinConnectivity(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 x, y, n, t;    FvsBool_t changed = FvsTrue;    if (p==NULL)        return FvsMemory;    if (ImageGetFlag(image)!=FvsImageBinarized)        return FvsBadParameter;    while (changed==FvsTrue)    {        changed = FvsFalse;        for (y=1; y<h-1; y++)        for (x=1; x<w-1; x++)        {            if (p[P(x,y)]==0xFF)            {                STEP_A                {                    STEP_B                    {                        /*                        c) 2*4*6=0  (2,4 ,or 6 为0)                        d) 4*6*8=0                        */                        if (P2*P4*P6==0 && P4*P6*P8==0)                            REMOVE_P;                    }                }            }        }        for (y=1; y<h-1; y++)        for (x=1; x<w-1; x++)            if (p[P(x,y)]==0x80)                p[P(x,y)] = 0;        for (y=1; y<h-1; y++)        for (x=1; x<w-1; x++)        {            if (p[P(x,y)]==0xFF)            {                STEP_A                {                    STEP_B                    {                        /*                        c) 2*6*8=0                        d) 2*4*8=0                        */                        if (P2*P6*P8==0 && P2*P4*P8==0)                            REMOVE_P;                    }                }            }        }        for (y=1; y<h-1; y++)        for (x=1; x<w-1; x++)            if (p[P(x,y)]==0x80)                p[P(x,y)] = 0;    }    ImageRemoveSpurs(image);        return ImageSetFlag(image, FvsImageThinned);} 	/* 重新定义 REMOVE_P */#undef REMOVE_P#define REMOVE_P    { p[P(x,y)]=0x00; changed = FvsTrue; }/******************************************************************************  * 功能:细化指纹图像,使用“Hit and Miss”结构元素。  *       图像必须是二值化过的(只包含0x00或oxFF)  *       该算法的缺点是产生很多伪造的线条(伪特征),  *       必须由另外的算法来消除,后处理非常必要。  * 参数:image   指纹图像  * 返回:错误编号******************************************************************************/FvsError_t ImageThinHitMiss(FvsImage_t image){    FvsInt_t w      = ImageGetWidth(image);    FvsInt_t h      = ImageGetHeight(image);    FvsInt_t pitch  = ImageGetPitch(image);    FvsByte_t* p    = ImageGetBuffer(image);    /*     //     // 0 0 0      0 0     //   1      1 1 0    // 1 1 1      1    //    */    FvsInt_t x,y, t;    FvsBool_t changed = FvsTrue;    if (p==NULL)        return FvsMemory;    if (ImageGetFlag(image)!=FvsImageBinarized)        return FvsBadParameter;    while (changed==FvsTrue)    {        changed = FvsFalse;        for (y=1; y<h-1; y++)        for (x=1; x<w-1; x++)        {            if (p[P(x,y)]==0xFF)            {                /*                // 0 0 0  0   1  1 1 1  1   0                //   1    0 1 1    1    1 1 0                // 1 1 1  0   1  0 0 0  1   0                */                if (p[P(x-1,y-1)]==0 && p[P(x,y-1)]==0 && p[P(x+1,y-1)]==0 &&                    p[P(x-1,y+1)]!=0 && p[P(x,y+1)]!=0 && p[P(x+1,y+1)]!=0)                    REMOVE_P;                if (p[P(x-1,y-1)]!=0 && p[P(x,y-1)]!=0 && p[P(x+1,y-1)]!=0 &&                    p[P(x-1,y+1)]==0 && p[P(x,y+1)]==0 && p[P(x+1,y+1)]==0)                    REMOVE_P;                if (p[P(x-1,y-1)]==0 && p[P(x-1,y)]==0 && p[P(x-1,y+1)]==0 &&                    p[P(x+1,y-1)]!=0 && p[P(x+1,y)]!=0 && p[P(x+1,y+1)]!=0)                    REMOVE_P;                if (p[P(x-1,y-1)]!=0 && p[P(x-1,y)]!=0 && p[P(x-1,y+1)]!=0 &&                    p[P(x+1,y-1)]==0 && p[P(x+1,y)]==0 && p[P(x+1,y+1)]==0)                    REMOVE_P;                /*                //   0 0  0 0      1      1                  // 1 1 0  0 1 1  0 1 1  1 1 0                //   1      1    0 0      0 0                */                                if (p[P(x,y-1)]==0 && p[P(x+1,y-1)]==0 && p[P(x+1,y)]==0 &&                    p[P(x-1,y)]!=0 && p[P(x,y+1)]!=0)                    REMOVE_P;                if (p[P(x-1,y-1)]==0 && p[P(x,y-1)]==0 && p[P(x-1,y)]==0 &&                    p[P(x+1,y)]!=0 && p[P(x,y+1)]!=0)                    REMOVE_P;                if (p[P(x-1,y+1)]==0 && p[P(x-1,y)]==0 && p[P(x,y+1)]==0 &&                    p[P(x+1,y)]!=0 && p[P(x,y-1)]!=0)                    REMOVE_P;                if (p[P(x+1,y+1)]==0 && p[P(x+1,y)]==0 && p[P(x,y+1)]==0 &&                    p[P(x-1,y)]!=0 && p[P(x,y-1)]!=0)                    REMOVE_P;                            }        }    }        ImageRemoveSpurs(image);    return ImageSetFlag(image, FvsImageThinned);}

⌨️ 快捷键说明

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