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

📄 imagemanip.c

📁 用VISUAL C++编程实现指纹图像的特征提取以及对指纹图像的识别
💻 C
📖 第 1 页 / 共 2 页
字号:
    {        FvsFloat_t dir = 0.0;        FvsFloat_t cosdir = 0.0;        FvsFloat_t sindir = 0.0;        FvsInt_t peak_pos[BLOCK_L]; /* peak positions */        FvsInt_t peak_cnt;          /* peak count     */        FvsFloat_t peak_freq;         /* peak frequence */        FvsFloat_t Xsig[BLOCK_L];     /* x signature    */        FvsFloat_t pmin, pmax;        memset(out,  0, size);        memset(freq, 0, size);        /* 1 - Divide G into blocks of 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 - oriented window of size l x w (32 x 16) in the ridge dir */            dir = orientation[(x+BLOCK_W2) + (y+BLOCK_W2)*w];            cosdir = -sin(dir);  /* ever > 0 */            sindir = cos(dir);   /* -1 ... 1 */            /* 3 - compute the 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;            }            /* Let T(i,j) be the avg number of pixels between 2 peaks */            /* find peaks in the x signature */            peak_cnt = 0;            /* test if the max - min or peak to peak value too small is,            then we ignore this point */            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;                }            }            /* compute mean value */            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 - must lie in a certain range [1/25-1/3] */            /*     changed to range [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 - interpolated ridge period for the unknown points */        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 - Inter-ridges distance change slowly in a local neighbourhood */        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;}/* }}} *//* {{{ Fingerprint mask */FvsError_t FingerprintGetMask(const FvsImage_t image, /*@unused@*/ 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;    /* width & height of the input image */    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;    /* TODO: add sanity checks for the direction and mask */    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] = (uint8_t)(10.0/freq[pos]);*/                out[posout] = 255;            }        }    /* fill in the holes */    for (y = 0; y < 4; y++)        (void)ImageDilate(mask);    /* remove borders */    for (y = 0; y < 12; y++)        (void)ImageErode(mask);    }    return nRet;}/* }}} *//* {{{ Thinning algorithms *//* {{{ -> Thin: Using connectivity */#undef P#define P(x,y)      ((x)+(y)*pitch)#define REMOVE_P    { p[P(x,y)]=0x80; changed = FvsTrue; }/*From     : Nadeem Ahmed (umahmed@cc.umanitoba.ca)Subject  : Thinning AlgorithmNewsgroup: borland.public.cppbuilder.graphicsDate :1998/02/23 Here is that thinning algorithm:                            9 2 3                            8 1 4                            7 5 6For each pixel(#1, above), we have 8 neighbors (#'s 2-8).Step 1:a) Make sure pixel 1, has 2 to 6 (inclusive) neighborsb) starting from 2, go clockwise until 9, and count the   number of 0 to 1 transitions.  This should be equal to 1.c) 2*4*6=0  (ie either 2,4 ,or 6 is off)d) 4*6*8=0if these conditions hold, remove pixel 1.Do this for the entire image.Step 2a) same as aboveb) same as abovec) 2*6*8=0d) 2*4*8=0if these hold remove pixel 1.*//* defines to facilitate reading */#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;    /* Thanks to Tony Xu for contributing this section that improves the quality     of the binarized image by getting rid of the extra pixels (spurs)    jdh: improvment by using 2 steps, the previous algorithm had the bad    habbit to remove completely some lines oriented in a special way... */    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) Make sure it has 2 to 6 neighbours */#define STEP_A  n = 0; /* number of neighbours */ \                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) count number 0 to 1 transsitions */#define STEP_B  t = 0; /* number of transitions */ \                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) 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  (ie either 2,4 ,or 6 is off)                        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);} 	/* redefine REMOVE_P */#undef REMOVE_P/* }}} *//* {{{ -> Thin: Hit and miss */#define REMOVE_P    { p[P(x,y)]=0x00; changed = FvsTrue; }/*// jdh: Second thinning algorithm based on a Hit and Miss transformation*/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);    /*    // Hit and Miss structuring elements for thinning    //    // this algo has the disadvantage to produce spurious lines resulting    // from the skeletonization. These may be eliminated by another algorithm.    // postprocessing is then still needed afterwards.    //     // 0 0 0      0 0     //   1      1 1 0    // 1 1 1      1    //    */    FvsInt_t x,y;    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 + -