zoukankan      html  css  js  c++  java
  • 基于MFC开发的指纹识别系统.

    MFC-FingerPrint

    基于MFC开发的指纹识别系统.


    效果图如下:

    1

    在第12步特征入库中,会对当前指纹的mdl数据与databases中所有的mdl进行对比,然后返回识别结果.

    一.载入图像

    在点击之后,选择需要识别的图片. 图片路径为beginfilename.

    void CFingerDlg::OnBnClickedOk1()
    {
    	CFileDialog    dlgFile(TRUE, NULL, NULL, OFN_HIDEREADONLY, _T("Describe Files (*.bmp)|*.bmp|All Files (*.*)|*.*||"), NULL);
    
    	if (dlgFile.DoModal())
    	{
    		strFile = dlgFile.GetPathName();
    	}
    	char *info = "";
    
    	USES_CONVERSION;
    	char * beginfilename = T2A(strFile);
    	Step1_LoadBmpImage(beginfilename,info);
    
    	ShowImageInCtrl(m_picCtrl1, beginfilename);
    
    	// TODO: 在此添加控件通知处理程序代码
    }
    

    Step1_LoadBmpImage中就是获取初始图片的RGB信息.

    int Step1_LoadBmpImage(char *beginfilename,char* info) {
    	char *filename = beginfilename;
    	CopyFile(ToWideChar(filename), ToWideChar(STEP_TXT_1), false);
    
    	int iWidth, iHeight, iDepth;
    	int flag = ReadBMPImgFilePara(filename, iWidth, iHeight, iDepth);
    	if (flag != 0) {
    		//sprintf(info,"图像加载失败");
    		::MessageBox(NULL, _T("图像加载失败"), _T("error"), MB_OK);
    		return -1;
    	}
    	unsigned char *data = new unsigned char[iWidth*iHeight];
    	flag = ReadBMPImgFileData(filename, data);
    	if (flag != 0) {
    		//sprintf(info, "图像数据读取失败");
    		::MessageBox(NULL, _T("图像数据读取失败"), _T("error"), MB_OK);
    		delete[] data;
    		return -2;
    	}
    	flag = SaveDataToTextFile(STEP_TXT_1, data, iWidth, iHeight);
    	if (flag != 0) {
    		//sprintf(info,"数据保存失败");
    		::MessageBox(NULL, _T("数据保存失败"), _T("error"), MB_OK);
    		delete[] data;
    		return -3;
    	}
    	//sprintf(info, "源图[%s],宽度[%d],高度[%d],深度[%d b]",filename,iWidth,iHeight,iDepth);
    	delete[] data;
    	return 0;
    }
    

    其中具体的Txt与BMP转换参考具体源代码.


    二.中值滤波

    中值滤波实现算法,ucImg由第一步得来.

    int MidFilter(unsigned char *ucImg, unsigned char *ucDstImg, int iWidth, int iHeight) {
    	memset(ucDstImg, 0, iWidth*iHeight);
    	unsigned char *pUp, *pDown, *pImg;
    	unsigned char x[9];
    	for (int i = 1; i < iHeight - 1; i++) {
    		pUp = ucImg + (i - 1)*iWidth;
    		pImg = ucImg + i * iWidth;
    		pDown = ucImg + (i + 1)*iWidth;
    		int j;
    		for (j = 1; j < iWidth - 1; j++) {
    			pUp++;
    			pImg++;
    			pDown++;
    			x[0] = *(pUp - 1);
    			x[1] = *(pImg - 1);
    			x[2] = *(pDown - 1);
    			x[3] = *pUp;
    			x[4] = *pImg;
    			x[5] = *pDown;
    			x[6] = *(pUp + 1);
    			x[7] = *(pImg + 1);
    			x[8] = *(pDown + 1);
    
    			Sort(x, 9);
    			*(ucDstImg + i * iWidth + j) = x[4];
    		}
    	}
    	int j;
    	pDown = ucImg + iWidth;
    	for (j = 1; j < iWidth - 1; j++) {
    		x[0] = *(ucImg + j - 1);
    		x[1] = *(ucImg + j);
    		x[2] = *(ucImg + j + 1);
    		x[3] = *(pDown + j - 1);
    		x[4] = *(pDown + j);
    		x[5] = *(pDown + j + 1);
    		Sort(x, 6);
    		*(ucDstImg + j) = x[3];
    	}
    	pUp = ucImg + iWidth * (iHeight - 2);
    	pDown = ucImg + iWidth * (iHeight - 1);
    	for (j = 1; j < iWidth - 1; j++) {
    		x[0] = *(pDown + j - 1);
    		x[1] = *(pDown + j);
    		x[2] = *(pDown + j + 1);
    		x[3] = *(pUp + j - 1);
    		x[4] = *(pUp + j);
    		x[5] = *(pUp + j + 1);
    		Sort(x, 6);
    		*(ucDstImg + iWidth * (iHeight - 1) + j) = x[3];
    	}
    	x[0] = *(ucImg);
    	x[1] = *(ucImg + 1);
    	x[2] = *(ucImg + iWidth);
    	x[3] = *(ucImg + iWidth + 1);
    	Sort(x, 4);
    	*(ucDstImg) = x[2];
    
    	x[0] = *(ucImg + iWidth - 1);
    	x[1] = *(ucImg + iWidth - 2);
    	x[2] = *(ucImg + 2 * iWidth - 1);
    	x[3] = *(ucImg + 2 * iWidth - 2);
    
    	Sort(x, 4);
    	*(ucDstImg + iWidth - 1) = x[2];
    
    	x[0] = *(ucImg + iWidth * (iHeight - 1));
    	x[1] = *(ucImg + iWidth * (iHeight - 2));
    	x[2] = *(ucImg + iWidth * (iHeight - 1) + 1);
    	x[3] = *(ucImg + iWidth * (iHeight - 2) + 1);
    	Sort(x, 4);
    	*(ucDstImg + (iHeight - 1)*iWidth) = x[2];
    	x[0] = *(ucImg + iWidth * (iHeight - 0) - 1);
    	x[1] = *(ucImg + iWidth * (iHeight - 1) - 1);
    	x[2] = *(ucImg + iWidth * (iHeight - 0) - 2);
    	x[3] = *(ucImg + iWidth * (iHeight - 1) - 2);
    	Sort(x, 4);
    
    	*(ucDstImg + (iHeight - 0)*iWidth - 1) = x[2];
    
    	return 0;
    }
    

    2


    三.均值化

    int HistoNormalize(unsigned char* ucImg,unsigned char* ucNormImg, int iWidth,int iHeight) {
    	unsigned int Histogram[256];
    
    	memset(Histogram, 0, 256 * sizeof(int));
    	for (int i = 0; i < iHeight; i++) {
    		for (int j = 0; j < iWidth; j++) {
    			Histogram[ucImg[i*iWidth + j]]++;
    		}
    	}
    	double dMean = 0;
    	for (int i = 1; i < 255; i++) {
    		dMean += i * Histogram[i];
    	}
    	dMean = int(dMean/(iWidth*iHeight));
    	double dSigma = 0;
    	for (int i = 0; i < 255; i++) {
    		dSigma += Histogram[i] * (i - dMean)*(i-dMean);
    	}
    	dSigma /= (iWidth*iHeight);
    	dSigma = sqrt(dSigma);
    
    	double dMean0 = 128, dSigma0 = 128;
    	double dCoeff = dSigma0 / dSigma;
    	for (int i = 0; i < iHeight; i++) {
    		for(int j=0;j<iWidth;j++){
    			double dVal = ucImg[i*iWidth + j];
    			dVal = dMean0 + dCoeff * (dVal-dMean0);
    			if (dVal < 0) {
    				dVal = 0;
    			}
    			else if (dVal > 255) {
    				dVal = 255;
    			}
    			ucNormImg[i*iWidth + j] = (unsigned char)dVal;
    		}
    	}
    	return 0;
    }
    

    3


    四.方向计算

    int ImgDirection(unsigned char* ucImg,float* fDirc,int iWidth,int iHeight) {
    	const int SEMISIZ = 7;
    	int dx[SEMISIZ * 2 + 1][SEMISIZ * 2 + 1];
    	int dy[SEMISIZ * 2 + 1][SEMISIZ * 2 + 1];
    	float fx, fy;
    	memset(fDirc, 0, iWidth*iHeight * sizeof(float));
    	for (int y = SEMISIZ + 1; y < iHeight - SEMISIZ - 1; y++) {
    		for (int x = SEMISIZ + 1; x < iWidth - SEMISIZ - 1; x++) {
    			for (int j = 0; j < SEMISIZ * 2 + 1; j++) {
    				for (int i = 0; i < SEMISIZ * 2 + 1; i++) {
    					int index1 = (y + j - SEMISIZ)*iWidth + x + i - SEMISIZ;
    					int index2 = (y + j - SEMISIZ)*iWidth + x + i - SEMISIZ - 1;
    					int index3 = (y + j - SEMISIZ - 1)*iWidth + x + i - SEMISIZ;
    					dx[i][j] = int(ucImg[index1] - ucImg[index2]);
    					dy[i][j] = int(ucImg[index1] - ucImg[index3]);
    				}
    			}
    			fx = 0.0;
    			fy = 0.0;
    			for (int j = 0; j < SEMISIZ * 2 + 1; j++) {
    				for (int i = 0; i < SEMISIZ * 2 + 1; i++) {
    					fx += 2 * dx[i][j] * dy[i][j];
    					fy += (dx[i][j] * dx[i][j] - dy[i][j] * dy[i][j]);
    				}
    			}
    			fDirc[y*iWidth + x] = atan2(fx,fy);
    		}
    	}
    	return 0;
    }
    

    4


    五.频率计算

    int DircLowPass(float *fDirc,float* fFitDirc,int iWidth,int iHeight) {
    	const int DIR_FILTER_SIZE = 2;
    	int blocksize = 2 * DIR_FILTER_SIZE + 1;
    	int imgsize = iWidth * iHeight;
    	float *filter = new float[blocksize*blocksize];
    	float *phix = new float[imgsize];
    	float *phiy = new float[imgsize];
    	float *phi2x = new float[imgsize];
    	float *phi2y = new float[imgsize];
    	memset(fFitDirc,0,sizeof(float)*iWidth*iHeight);
    	float tempSum = 0.0;
    	for (int y = 0; y < blocksize; y++) {
    		for (int x = 0; x < blocksize; x++) {
    			filter[y*blocksize + x] = (float)(blocksize - (abs(DIR_FILTER_SIZE - x) + abs(DIR_FILTER_SIZE - y)));
    			tempSum += filter[y*blocksize + x];
    		}
    	}
    	for (int y = 0; y < blocksize; y++) {
    		for (int x = 0; x < blocksize; x++) {
    			filter[y*blocksize + x] /= tempSum;
    		}
    	}
    	for(int y=0;y<iHeight;y++){
    		for (int x = 0; x < iWidth; x++) {
    			phix[y*iWidth + x] = cos(fDirc[y*iWidth + x]);
    			phiy[y*iWidth + x] = sin(fDirc[y*iWidth + x]);
    		}
    	}
    	memset(phi2x, 0, sizeof(float)*imgsize);
    	memset(phi2y, 0, sizeof(float)*imgsize);
    	float nx, ny;
    	int val;
    	for (int y = 0; y < iHeight - blocksize; y++) {
    		for (int x = 0; x < iWidth - blocksize; x++) {
    			nx = 0.0;
    			ny = 0.0;
    			for (int j = 0; j < blocksize; j++) {
    				for (int i = 0; i < blocksize; i++) {
    					val = (x + i) + (j + y)*iWidth;
    					nx += filter[j*blocksize + i] * phix[val];
    					ny += filter[j*blocksize + i] * phiy[val];
    				}
    			}
    			val = x + y * iWidth;
    			phi2x[val] = nx;
    			phi2y[val] = ny;
    		}
    	}
    
    	for (int y = 0; y < iHeight - blocksize; y++) {
    		for (int x = 0; x < iWidth - blocksize; x++) {
    			val = x + y * iWidth;
    			fFitDirc[val] = atan2(phi2y[val],phi2x[val])*0.5;
    		}
    	}
    	delete[] phi2y;
    	delete[] phi2x;
    	delete[] phiy;
    	delete[] phix;
    
    	return 0;
    }
    

    5


    六.掩码计算

    int GetMask(unsigned char* ucImg,float *fDirection,float *fFrequency,unsigned char *ucMask,int iWidth,int iHeight) {
    	float freqMin = 1.0 / 25.0;
    	float freqMax = 1.0 / 3.0;
    	int x, y, k;
    	int pos, posout;
    	memset(ucMask,0,iWidth*iHeight);
    	for (y = 0; y < iHeight; y++) {
    		for (x = 0; x < iWidth; x++) {
    			pos = x + y * iWidth;
    			posout = x + y * iWidth;
    			ucMask[posout] = 0;
    			if (fFrequency[pos] >= freqMin && fFrequency[pos] <= freqMax) {
    				ucMask[posout] = 255;
    			}
    		}
    	}
    	for (k = 0; k < 4; k++) {
    		for (y = 1; y < iHeight - 1; y++) {
    			for (x = 1; x < iWidth - 1; x++) {
    				if (ucMask[x + y * iWidth] == 0xFF) {
    					ucMask[x - 1 + y * iWidth] |= 0x80;
    					ucMask[x + 1 + y * iWidth] |= 0x80;
    					ucMask[x + (y-1) * iWidth] |= 0x80;
    					ucMask[x + (y+1) * iWidth] |= 0x80;
    				}
    			}
    		}
    		for (y = 1; y < iHeight - 1; y++) {
    			for (x = 1; x < iWidth - 1; x++) {
    				if (ucMask[x + y * iWidth]) {
    					ucMask[x + y * iWidth] = 0xFF;
    				}
    			}
    		}
    	}
    	for (k = 0; k < 12; k++) {
    		for (y = 1; y < iHeight - 1; y++) {
    			for (x = 1; x < iWidth - 1; x++) {
    				if (ucMask[x + y * iWidth] == 0x0) {
    					ucMask[x - 1 + y * iWidth] &= 0x80;
    					ucMask[x + 1 + y * iWidth] &= 0x80;
    					ucMask[x + (y - 1) * iWidth] &= 0x80;
    					ucMask[x + (y + 1) * iWidth] &= 0x80;
    				}
    			}
    		}
    		for (y = 1; y < iHeight - 1; y++) {
    			for (x = 1; x < iWidth - 1; x++) {
    				if (ucMask[x + y * iWidth] != 0xFF) {
    					ucMask[x + y * iWidth] = 0x0;
    				}
    			}
    		}
    	}
    	return 0;
    }
    

    6


    七.Gabor增强

    int GaborEnhance(unsigned char* ucImg, float* fDirection, float* fFrequency, unsigned char* ucMask, unsigned char* ucImgEnhanced, int iWidth, int iHeight) {
    	const float PI = 3.141592654;
    	int i, j, u, v;
    	int wg2 = 5;
    	float sum, f, g;
    	float x2, y2;
    	float dx2 = 1.0 / (4.0*4.0);
    	float dy2 = 1.0 / (4.0*4.0);
    	memset(ucImgEnhanced,0,iWidth*iHeight);
    	for (j = wg2; j < iHeight - wg2; j++) {
    		for (i = wg2; i < iWidth - wg2; i++) {
    			if (ucMask[i + j * iWidth] == 0) {
    				continue;
    			}
    			g = fDirection[i+j*iWidth];
    			f = fFrequency[i+j*iWidth];
    			g += PI / 2;
    			sum = 0.0;
    			for (v = -wg2; v <= wg2; v++) {
    				for (u = -wg2; u <= wg2; u++) {
    					x2 = -u * sin(g) + v * cos(g);
    					y2 = u * cos(g) + v * sin(g);
    					sum += exp(-0.5*(x2*x2*dx2 + y2 * y2*dy2))*cos(2 * PI*x2*f)*ucImg[(i - u) + (j - v)*iWidth];
    				}
    			}
    			if (sum > 255.0) {
    				sum = 255.0;
    			}
    			if (sum < 0.0) {
    				sum = 0.0;
    			}
    			ucImgEnhanced[i + j * iWidth] = (unsigned char)sum;
    		}
    	}
    	return 0;
    }
    

    7


    八.二值化

    
    int BinaryImg(unsigned char* ucImage,unsigned char* ucBinImage,int iWidth,int iHeight,unsigned char uThreshold) {
    	unsigned char *pStart = ucImage, *pEnd = ucImage + iWidth * iHeight;
    	unsigned char *pDest = ucBinImage;
    	while (pStart < pEnd) {
    		*pDest = *pStart > uThreshold ? 1 : 0;
    		pStart++;
    		pDest++;
    	}
    	return 0;
    }
    
    int BinaryToGray(unsigned char *ucBinImg,unsigned char *ucGrayImg,int iWidth,int iHeight) {
    	unsigned char *pStart = ucBinImg, *pEnd = ucBinImg + iWidth * iHeight;
    	unsigned char *pDest = ucGrayImg;
    
    	while (pStart<pEnd) {
    		*pDest = (*pStart) > 0 ? 255 : 0;
    		pStart++;
    		pDest++;
    	}
    	return 0;
    }
    

    8


    九.细化

    int Thinning(unsigned char *ucBinedImg,unsigned char *ucThinnedImage,int iWidth,int iHeight,int iIterativeLimit) {
    	unsigned char x1, x2, x3, x4, x5, x6, x7, x8, xp;
    	unsigned char g1, g2, g3, g4;
    	unsigned char b1, b2, b3, b4;
    	unsigned char np1, np2, npm;
    	unsigned char *pUp, *pDown, *pImg;
    	int iDeletePoints = 0;
    
    	memcpy(ucThinnedImage,ucBinedImg,iWidth*iHeight);
    	for (int it = 0; it < iIterativeLimit; it++) {
    		iDeletePoints = 0;
    		for (int i = 1; i < iHeight - 1; i++) {
    			pUp = ucBinedImg + (i - 1)*iWidth;
    			pImg = ucBinedImg + i * iWidth;
    			pDown = ucBinedImg + (i + 1)*iWidth;
    			for (int j = 1; j < iWidth - 1; j++) {
    				pUp++;
    				pImg++;
    				pDown++;
    				if (!*pImg) {
    					continue;
    				}
    				x6 = *(pUp - 1);
    				x5 = *(pImg - 1);
    				x4 = *(pDown - 1);
    				x7 = *pUp;
    				xp = *pImg;
    				x3 = *pDown;
    				x8 = *(pUp + 1);
    				x1 = *(pImg+1);
    				x2 = *(pDown+1);
    
    
    				b1 = !x1 && (x2 == 1 || x3 == 1);
    				b2 = !x3 && (x4 == 1 || x5 == 1);
    				b3 = !x5 && (x6 == 1 || x7 == 1);
    				b4 = !x7 && (x8 == 1 || x1 == 1);
    
    				g1 = (b1 + b2 + b3 + b4) == 1;
    
    				np1 = x1 || x2;
    				np1 += x3 || x4;
    				np1 += x5 || x6;
    				np1 += x7 || x8;
    				np2  = x2 || x3;
    				np2 += x4 || x5;
    				np2 += x6 || x7;
    				np2 += x8 || x1;
    
    				npm = np1 > np2 ? np2 : np1;
    				g2 = npm >= 2 && npm <= 3;
    				g3 = (x1 && (x2 || x3 || !x8)) == 0;
    				g4 = (x5 && (x6 || x7 || !x4)) == 0;
    
    				if (g1&&g2&&g3) {
    					ucThinnedImage[iWidth*i + j] = 0;
    					++iDeletePoints;
    				}
    			}
    		}
    		memcpy(ucBinedImg,ucThinnedImage,iWidth*iHeight);
    		for (int i = 1; i < iHeight - 1;i++) {
    			pUp = ucBinedImg + (i - 1)*iWidth;
    			pImg = ucBinedImg + i * iWidth;
    			pDown = ucBinedImg + (i+1) * iWidth;
    			for (int j = 1; j < iWidth - 1; j++) {
    				pUp++;
    				pImg++;
    				pDown++;
    				if (!*pImg) {
    					continue;
    				}
    				x6 = *(pUp - 1);
    				x5 = *(pImg - 1);
    				x4 = *(pDown - 1);
    
    				x7 = *pUp;
    				xp = *pImg;
    				x3 = *pDown;
    
    				x8 = *(pUp + 1);
    				x1 = *(pImg + 1);
    				x2 = *(pDown + 1);
    
    				b1 = !x1 && (x2 == 1 || x3 == 1);
    				b2 = !x3 && (x4 == 1 || x5 == 1);
    				b3 = !x5 && (x6 == 1 || x7 == 1);
    				b4 = !x7 && (x8 == 1 || x1 == 1);
    
    				g1 = (b1 + b2 + b3 + b4) == 1;
    
    				np1 = x1 || x2;
    				np1 += x3 || x4;
    				np1 += x5 || x6;
    				np1 += x7 || x8;
    
    				np2 = x2 || x3;
    				np2 += x4 || x5;
    				np2 += x6 || x7;
    				np2 += x8 || x1;
    
    				npm = np1 > np2 ? np2 : np1;
    				g2 = npm >= 2 && npm <= 3;
    
    				g3 = (x1 && (x2 || x3 || !x8)) == 0;
    				g4 = (x5 && (x6 || x7 || !x4)) == 0;
    
    				if (g1&&g2&&g4) {
    					ucThinnedImage[iWidth*i+j] = 0;
    					++iDeletePoints;
    				}
     			}
    		}
    
    		memcpy(ucBinedImg,ucThinnedImage,iWidth*iHeight);
    
    		if (iDeletePoints == 0) {
    			break;
    		}
    	}
    
    	for (int i = 0; i < iHeight; i++) {
    		for (int j = 0; j < iWidth; j++) {
    			if (i < 16) {
    				ucThinnedImage[i*iWidth + j] = 0;
    			}
    			else if (i >= iHeight - 16) {
    				ucThinnedImage[i*iWidth + j] = 0;
    			}
    			else if (j < 16) {
    				ucThinnedImage[i*iWidth + j] = 0;
    			}
    			else if (j >= iWidth - 16) {
    				ucThinnedImage[i*iWidth + j] = 0;
    			}
    		}
    	}
    	return 0;
    }
    

    9


    十.特征提取

    int CutEdge(MINUTIAE* minutiaes,int count,unsigned char*ucImg,int iWidth,int iHeight) {
    	int minuCount = count;
    	int x, y, type;
    	bool del;
    	int *pFlag = new int[minuCount];
    	memset(pFlag,0,sizeof(int)*minuCount);
    	for (int i = 0; i < minuCount; i++) {
    		y = minutiaes[i].y - 1;
    		x = minutiaes[i].x - 1;
    		type = minutiaes[i].type ;
    		del = true;
    		if (x < iWidth / 2) {
    			if (abs(iWidth / 2 - x) > abs(iHeight / 2 - y)) {
    				while (--x >= 0) {
    					if (ucImg[x + y * iWidth] > 0) {
    						del = false;
    						break;
    					}
    				}
    			}
    			else {
    				if (y > iHeight / 2) {
    					while (++y < iHeight) {
    						if (ucImg[x + y * iWidth] > 0) {
    							del = false;
    							break;
    						}
    					}
    				}
    				else {
    					while (--y == 0) {
    						if (ucImg[x + y * iWidth] > 0) {
    							del = false;
    							break;
    						}
    					}
    				}
    			}
    		}
    		else {
    			if (abs(iWidth / 2 - x) > abs(iHeight / 2 - y)) {
    				while (++x < iWidth) {
    					if (ucImg[x + y * iWidth] > 0) {
    						del = false;
    						break;
    					}
    				}
    			}
    			else {
    				if (y > iHeight / 2) {
    					while (++y < iHeight) {
    						if (ucImg[x + y * iWidth] > 0) {
    							del = false;
    							break;
    						}
    					}
    				}
    				else {
    					while (--y >= 0) {
    						if (ucImg[x + y * iWidth] > 0) {
    							del = false;
    							break;
    						}
    					}
    				}
    			}
    		}
    		if (del) {
    			pFlag[i] = 1;
    			continue;
    		}
    	}
    	int newCount = 0;
    	for (int i = 0; i < minuCount; i++) {
    		if (pFlag[i] == 0) {
    			memcpy(&minutiaes[newCount],&minutiaes[i],sizeof(MINUTIAE));
    			newCount++;
    		}
    	}
    	delete[] pFlag;
    	pFlag = NULL;
    	return newCount;
    }
    

    10


    十一.特征过滤

    int MinuFilter(unsigned char *minuData,unsigned char *thinData,MINUTIAE *minutiaes,int &minuCount,int iWidth,int iHeight) {
    	float *dir = new float[iWidth*iHeight];
    	memset(dir,0,iWidth*iHeight*sizeof(float));
    	ImgDirection(thinData,dir,iWidth,iHeight);
    	unsigned char* pImg;
    	unsigned char val;
    	int temp = 0;
    	for (int i = 1; i < iHeight - 1; i++) {
    		pImg = minuData + i * iWidth;
    		for (int j = 1; j < iWidth - 1; j++) {
    			++pImg;
    			val = *pImg;
    			if(val>0){
    				minutiaes[temp].x = j + 1;
    				minutiaes[temp].y = i + 1;
    				minutiaes[temp].theta = dir[i*iWidth+j];
    				minutiaes[temp].type = int(val);
    				++temp;
    			}
    		}
    	}
    	delete[] dir;
    	minuCount = CutEdge(minutiaes,minuCount,thinData,iWidth,iHeight);
    	int *pFlag = new int[minuCount];
    	memset(pFlag,0,sizeof(int)*minuCount);
    	int x1, x2, y1, y2, type1, type2;
    	for (int i = 0; i < minuCount; i++) {
    		x1 = minutiaes[i].x;
    		y1 = minutiaes[i].y;
    		type1 = minutiaes[i].type;
    		for (int j = i + 1; j < minuCount; j++) {
    			if (pFlag[i] == 1) {
    				continue;
    			}
    			x2 = minutiaes[j].x;
    			y2 = minutiaes[j].y;
    			type2 = minutiaes[j].type;
    
    			int r = (int)sqrt(float((y1-y2)*(y1-y2)+(x1-x2)*(x1-x2)));
    
    			if (r <= 4) {
    				if (type1 == type2) {
    					if (type1 == 1) {
    						pFlag[i] = pFlag[j] = 1;
    					}
    					else {
    						pFlag[j] = 1;
    					}
    				}
    				else if (type1 == 1) {
    					pFlag[i] = 1;
    				}
    				else {
    					pFlag[j] = 1;
    				}
    			}
    		}
    
    	}
    	int newCount = 0;
    	for (int i = 0; i < minuCount; i++) {
    		if (pFlag[i] == 0) {
    			memcpy(&minutiaes[newCount],&minutiaes[i],sizeof(MINUTIAE));
    			newCount++;
    		}
    	}
    	delete[] pFlag;
    	minuCount = newCount;
    	return 0;
    }
    

    11

  • 相关阅读:
    [ Algorithm ] N次方算法 N Square 动态规划解决
    [ Algorithm ] LCS 算法 动态规划解决
    sql server全文索引使用中的小坑
    关于join时显示no join predicate的那点事
    使用scvmm 2012的动态优化管理群集资源
    附加数据库后无法创建发布,error 2812 解决
    浅谈Virtual Machine Manager(SCVMM 2012) cluster 过载状态检测算法
    windows 2012 r2下安装sharepoint 2013错误解决
    sql server 2012 数据引擎任务调度算法解析(下)
    sql server 2012 数据引擎任务调度算法解析(上)
  • 原文地址:https://www.cnblogs.com/LexMoon/p/fingerprint.html
Copyright © 2011-2022 走看看