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

📄 imagemanip.c

📁 c代码
💻 C
📖 第 1 页 / 共 3 页
字号:
            {                /*                // 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);}
/* modified
*/
FvsError_t FingerprintGetFrequency1(const FvsImage_t image, const FvsFloatField_t direction,
           FvsFloatField_t frequency)
{
    /* 输入图像的宽度和高度 */
    FvsError_t nRet = FvsOK;
    FvsInt_t w      = ImageGetWidth (image);
    FvsInt_t h      = ImageGetHeight(image);
    FvsInt_t pitchi = ImageGetPitch (image);
    FvsByte_t* p    = ImageGetBuffer(image);
    FvsFloat_t* out;
    FvsFloat_t* freq;
    FvsFloat_t* orientation = FloatFieldGetBuffer(direction);
    FvsFloat_t dir,dir1,dir2;
    FvsFloat_t cosdir,sindir,cosdir1,sindir1,cosdir2,sindir2;
  

    FvsInt_t x, y, u, v, d, k;
    size_t size;

    if (p==NULL)
        return FvsMemory;

    /* 输出图像的内存申请 */
    nRet = FloatFieldSetSize(frequency, w, h);
    if (nRet!=FvsOK) return nRet;
    (void)FloatFieldClear(frequency);
    freq = FloatFieldGetBuffer(frequency);
    if (freq==NULL)
        return FvsMemory;

    /* 输出的内存申请 */
    size = w*h*sizeof(FvsFloat_t);
    out  = (FvsFloat_t*)malloc(size);
    if (out!=NULL)
    {
        FvsInt_t peak_pos[BLOCK_L];		/* 顶点			*/
        FvsInt_t peak_cnt;				/* 顶点数目		*/
        FvsFloat_t peak_freq,save[50];			/* 顶点频率		*/
        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+y*w];
            cosdir = cos(dir); 
            sindir = sin(dir);

			u=(FvsInt_t)(-sindir*BLOCK_L2/2)+x;
			v=(FvsInt_t)(cosdir*BLOCK_L2/2)+y;
			dir1= orientation[u+v*w];
            cosdir1 = cos(dir1); 
            sindir1 = sin(dir1);

			u=(FvsInt_t)(sindir*BLOCK_L2/2)+x;
			v=(FvsInt_t)(-cosdir*BLOCK_L2/2)+y;
			dir2= orientation[u+v*w];
            cosdir2 = cos(dir2); 
            sindir2 = sin(dir2);

            /* 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++)
                {
                    if(d-BLOCK_W2>0)
					{
					u = (FvsInt_t)(x + (k-BLOCK_L2)*cosdir1-(d-BLOCK_W2)*sindir1);
                    v = (FvsInt_t)(y + (k-BLOCK_L2)*sindir1+(d-BLOCK_W2)*cosdir1);
					}
					else
					{
					u = (FvsInt_t)(x + (k-BLOCK_L2)*cosdir2-(d-BLOCK_W2)*sindir2);
                    v = (FvsInt_t)(y + (k-BLOCK_L2)*sindir2+(d-BLOCK_W2)*cosdir2);
					}
                    /* 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 > 25.0 && peak_freq < 3.0)
                peak_freq = 0.0;
			if (peak_freq == 0.0)
                out[x+y*w] = 0.0;
            else
                out[x+y*w] = 1.0/peak_freq;

 			if(x<230 && x>220 && y==46)
				x=x;
		}
        /* 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++)
			{
                save[(v+LPSIZE)*(LPSIZE*2+1)+u+LPSIZE]= out[(x+u)+(y+v)*w];
				peak_freq += out[(x+u)+(y+v)*w];
			}
            freq[k] = peak_freq*LPFACTOR;
 			if(x<230 && x>220 && y==46)
				x=x;
        }
        free(out);
    }
	return nRet;
}
/* modified
*/
struct mycomplex{
	FvsFloat_t real;
	FvsFloat_t imag;
};


static fft(FvsFloat_t data[32])
{
	FvsInt_t i,j,k,bfsize,p,count,r=5;
	FvsFloat_t	angle;
	struct mycomplex *w,*x1,*x2,*x;
	count=1<<r;
	w=(struct mycomplex*)malloc(sizeof(struct complex)*count/2);
	x1=(struct mycomplex*)malloc(sizeof(struct complex)*count);
	x2=(struct mycomplex*)malloc(sizeof(struct complex)*count);
	for(i=0;i<count/2;i++)
	{
		angle=-i*M_PI*2/count;
		w[i].real=cos(angle);
		w[i].imag=sin(angle);
	}

	for(j=0;j<count;j++)
	{
		p=0;
		for(i=0;i<r;i++)
		{
			if(j&(1<<i))
			{
				p+=1<<(r-i-1);
			}
		}
		x1[p].real=data[j];
		x1[p].imag=0;
	}
	
	for(k=0;k<r;k++)
	{
		bfsize=1<<(k+1);
		for(j=0;j<1<<(r-k-1);j++)
		{
			for(i=0;i<bfsize/2;i++)
			{
				p=j*bfsize;
				x2[i+p].real=x1[i+p].real+x1[i+p+bfsize/2].real*w[i*1<<(r-k-1)].real \
							-x1[i+p+bfsize/2].imag*w[i*1<<(r-k-1)].imag;
				x2[i+p].imag=x1[i+p].imag+x1[i+p+bfsize/2].imag*w[i*1<<(r-k-1)].real \
							+x1[i+p+bfsize/2].real*w[i*1<<(r-k-1)].imag;
				x2[i+p+bfsize/2].real=x1[i+p].real-x1[i+p+bfsize/2].real*w[i*1<<(r-k-1)].real \
							+x1[i+p+bfsize/2].imag*w[i*1<<(r-k-1)].imag;
				x2[i+p+bfsize/2].imag=x1[i+p].imag-x1[i+p+bfsize/2].imag*w[i*1<<(r-k-1)].real \
							-x1[i+p+bfsize/2].real*w[i*1<<(r-k-1)].imag;
			}
		}
		x=x1;
		x1=x2;
		x2=x;
	}
	for(j=0;j<count;j++)
	{
		data[j]=sqrt(x1[j].real*x1[j].real+x1[j].imag*x1[j].imag)/10;
	}
	free(w);
	free(x1);
	free(x2);

}

FvsError_t FingerprintGetFrequency2(const FvsImage_t image, const FvsFloatField_t direction,
           FvsFloatField_t frequency)
{
    /* 输入图像的宽度和高度 */
    FvsError_t nRet = FvsOK;
    FvsInt_t w      = ImageGetWidth (image);
    FvsInt_t h      = ImageGetHeight(image);
    FvsInt_t pitchi = ImageGetPitch (image);
    FvsByte_t* p    = ImageGetBuffer(image);
    FvsFloat_t* out;
    FvsFloat_t* freq;
    FvsFloat_t* orientation = FloatFieldGetBuffer(direction);

    FvsInt_t x, y, u, v, d, k;
    size_t size;

    if (p==NULL)
        return FvsMemory;

    /* 输出图像的内存申请 */
    nRet = FloatFieldSetSize(frequency, w, h);
    if (nRet!=FvsOK) return nRet;
    (void)FloatFieldClear(frequency);
    freq = FloatFieldGetBuffer(frequency);
    if (freq==NULL)
        return FvsMemory;

    /* 输出的内存申请 */
    size = w*h*sizeof(FvsFloat_t);
    out  = (FvsFloat_t*)malloc(size);
    if (out!=NULL)
    {
        FvsFloat_t dir = 0.0;
        FvsFloat_t cosdir = 0.0;
        FvsFloat_t sindir = 0.0;

        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];
			dir = orientation[(x) + (y)*w];
            cosdir = cos(dir); 
            sindir = sin(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 + (k-BLOCK_L2)*cosdir-(d-BLOCK_W2)*sindir);
                    v = (FvsInt_t)(y + (k-BLOCK_L2)*sindir+(d-BLOCK_W2)*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;
            }

			if(x==130 && y==100)
				x=x;

//			for(k=0;k<32;k++)
//				Xsig[k]=cos(2*M_PI*7*k/32)+cos(2*M_PI*3*k/32);
			fft(Xsig);

            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;
}

⌨️ 快捷键说明

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