用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

人脸识别

2014-07-05 作者: 筱yu尚举报

[java]代码库

		
import com.googlecode.javacpp.FloatPointer;
import com.googlecode.javacpp.Pointer;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import static com.googlecode.javacv.cpp.opencv_highgui.cvWaitKey;
import static com.googlecode.javacv.cpp.opencv_highgui.cvShowImage;
import static com.googlecode.javacv.cpp.opencv_highgui.cvSaveImage;
import static com.googlecode.javacv.cpp.opencv_highgui.cvDestroyWindow;
import static com.googlecode.javacv.cpp.opencv_highgui.CV_LOAD_IMAGE_GRAYSCALE;
import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.FrameGrabber.Exception;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.VideoInputFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.CvFont;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvPoint;
import com.googlecode.javacv.cpp.opencv_core.CvRect;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import static com.googlecode.javacv.cpp.opencv_legacy.*;
import static com.googlecode.javacv.cpp.opencv_objdetect.CV_HAAR_DO_CANNY_PRUNING;
import static com.googlecode.javacv.cpp.opencv_objdetect.CV_HAAR_FIND_BIGGEST_OBJECT;
import static com.googlecode.javacv.cpp.opencv_objdetect.CV_HAAR_DO_ROUGH_SEARCH;
import static com.googlecode.javacv.cpp.opencv_objdetect.cvHaarDetectObjects;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_BGR2GRAY; 
import static com.googlecode.javacv.cpp.opencv_imgproc.cvEqualizeHist;
import com.googlecode.javacv.cpp.opencv_objdetect.CvHaarClassifierCascade;	
import static com.googlecode.javacv.cpp.opencv_core.CvMat;
import static com.googlecode.javacv.cpp.opencv_core.cvReleaseImage;
import static com.googlecode.javacv.cpp.opencv_core.cvLoad;
import static com.googlecode.javacv.cpp.opencv_core.CV_FONT_HERSHEY_COMPLEX_SMALL;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSize;
import static com.googlecode.javacv.cpp.opencv_core.CV_32FC1;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateMat;
import static com.googlecode.javacv.cpp.opencv_core.cvCloneImage;
import static com.googlecode.javacv.cpp.opencv_core.IPL_DEPTH_8U;
import static com.googlecode.javacv.cpp.opencv_core.cvCreateImage;
import static com.googlecode.javacv.cpp.opencv_core.CvSize;
import static com.googlecode.javacv.cpp.opencv_core.cvResetImageROI;
import static com.googlecode.javacv.cpp.opencv_core.cvClearMemStorage;
import static com.googlecode.javacv.cpp.opencv_core.cvSize;
import static com.googlecode.javacv.cpp.opencv_core.cvCopy;
import static com.googlecode.javacv.cpp.opencv_core.cvSetImageROI;
import static com.googlecode.javacv.cpp.opencv_core.CV_AA;
import static com.googlecode.javacv.cpp.opencv_core.cvPoint;
import static com.googlecode.javacv.cpp.opencv_core.cvInitFont;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSeqElem;
import static com.googlecode.javacv.cpp.opencv_core.cvRectangle;
import static com.googlecode.javacv.cpp.opencv_core.cvPutText;
import static com.googlecode.javacv.cpp.opencv_core.CV_32SC1;
import static com.googlecode.javacv.cpp.opencv_core.CvTermCriteria;
import static com.googlecode.javacv.cpp.opencv_core.IPL_DEPTH_32F;
import static com.googlecode.javacv.cpp.opencv_core.CV_L1;
import static com.googlecode.javacv.cpp.opencv_core.CV_TERMCRIT_ITER;
import static com.googlecode.javacv.cpp.opencv_core.cvNormalize;
import static com.googlecode.javacv.cpp.opencv_core.CvFileStorage;
import static com.googlecode.javacv.cpp.opencv_core.cvWriteInt;
import static com.googlecode.javacv.cpp.opencv_core.cvTermCriteria;
import static com.googlecode.javacv.cpp.opencv_core.CV_STORAGE_WRITE;
import static com.googlecode.javacv.cpp.opencv_core.cvOpenFileStorage;
import static com.googlecode.javacv.cpp.opencv_core.cvWrite;
import static com.googlecode.javacv.cpp.opencv_core.cvWriteString;
import static com.googlecode.javacv.cpp.opencv_core.cvReleaseFileStorage;
import static com.googlecode.javacv.cpp.opencv_core.CV_STORAGE_READ;
import static com.googlecode.javacv.cpp.opencv_core.cvReadIntByName;
import static com.googlecode.javacv.cpp.opencv_core.cvReadStringByName;
import static com.googlecode.javacv.cpp.opencv_core.cvReadByName;
import static com.googlecode.javacv.cpp.opencv_core.cvRect;
import static com.googlecode.javacv.cpp.opencv_core.cvConvertScale;
import static com.googlecode.javacv.cpp.opencv_core.cvMinMaxLoc;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_INTER_LINEAR;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_INTER_AREA;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvResize;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvCvtColor;

	
import java.io.*;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
	
	public class FaceRecognizer{
	
	  private static final Logger LOGGER = Logger.getLogger(FaceRecognizer.class.getName());
	  private int nTrainFaces = 0;
	  private int nPersons=0;
	  private int nEigens = 0;
	  private int countSavedFace=1;
	  private CvMat personNumTruthMat;
	  private  CvMat eigenValMat;
	  private CvMat projectedTrainFaceMat;
	  private CvMat trainPersonNumMat=null; 
	  final static List<String> personNames = new ArrayList<String>();
	  private CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(cvLoad("data\\haarcascade_frontalface_alt2.xml"));
	  private static final int newWidth=50;
	  private static final int newHeight=50;
	  
	  IplImage[] eigenVectArr;
	  IplImage[] trainingFaceImgArr;
	  IplImage[] testFaceImgArr;
	  IplImage pAvgTrainImg;
	 
	  
	  public static String personName;
	  private static String textName="unknow";
	  
	  public static double g_confidence=0;  
	  
	  
	  public FaceRecognizer() {
		  trainPersonNumMat = loadTrainingData();
	  }
	  
	  
	  private void learn(final String trainingFileName) {
	    int i;
	
	    // load training data
	    LOGGER.info("===========================================");
	    LOGGER.info("Loading the training images in " + trainingFileName);
	    trainingFaceImgArr = loadFaceImgArray(trainingFileName);
	    nTrainFaces = trainingFaceImgArr.length;
	    LOGGER.info("Got " + nTrainFaces + " training images");
	    if (nTrainFaces < 3) {
	      LOGGER.severe("Need 3 or more training faces\n"
	              + "Input file contains only " + nTrainFaces);
	      return;
	    }
	
	    // do Principal Component Analysis on the training faces
	    doPCA();
	
	    LOGGER.info("projecting the training images onto the PCA subspace");
	    // project the training images onto the PCA subspace
	    projectedTrainFaceMat = cvCreateMat(
	            nTrainFaces, // rows
	            nEigens, // cols
	            CV_32FC1); // type, 32-bit float, 1 channel
	
	    // initialize the training face matrix - for ease of debugging
	    for (int i1 = 0; i1 < nTrainFaces; i1++) {
	      for (int j1 = 0; j1 < nEigens; j1++) {
	        projectedTrainFaceMat.put(i1, j1, 0.0);
	      }
	    }
	
	    LOGGER.info("created projectedTrainFaceMat with " + nTrainFaces + " (nTrainFaces) rows and " + nEigens + " (nEigens) columns");
	    if (nTrainFaces < 5) {
	      LOGGER.info("projectedTrainFaceMat contents:\n" + oneChannelCvMatToString(projectedTrainFaceMat));
	    }
	
	    final FloatPointer floatPointer = new FloatPointer(nEigens);
	    for (i = 0; i < nTrainFaces; i++) {
	      cvEigenDecomposite(
	              trainingFaceImgArr[i], // obj
	              nEigens, // nEigObjs
	              eigenVectArr, // eigInput (Pointer)
	              0, // ioFlags
	              null, // userData (Pointer)
	              pAvgTrainImg, // avg
	              floatPointer); // coeffs (FloatPointer)
	
	      if (nTrainFaces < 5) {
	        LOGGER.info("floatPointer: " + floatPointerToString(floatPointer));
	      }
	      for (int j1 = 0; j1 < nEigens; j1++) {
	        projectedTrainFaceMat.put(i, j1, floatPointer.get(j1));
	      }
	    }
	    if (nTrainFaces < 5) {
	      LOGGER.info("projectedTrainFaceMat after cvEigenDecomposite:\n" + projectedTrainFaceMat);
	    }
	
	    // store the recognition data as an xml file
	    storeTrainingData();
	
	    // Save all the eigenvectors as images, so that they can be checked.
	    storeEigenfaceImages();
	  }

	
	private IplImage convertImageToGreyscale(IplImage imageSrc)
	  {
	  	IplImage imageGrey;
	  	// Either convert the image to greyscale, or make a copy of the existing greyscale image.
	  	// This is to make sure that the user can always call cvReleaseImage() on the output, whether it was greyscale or not.
	  	if (imageSrc.nChannels()==3) {
	  		imageGrey = cvCreateImage( cvGetSize(imageSrc), IPL_DEPTH_8U, 1 );
	  		cvCvtColor( imageSrc, imageGrey, CV_BGR2GRAY );
	  	}
	  	else {
	  		imageGrey = cvCloneImage(imageSrc);
	  	}
	  	return imageGrey;
	  }
	  
	  
	private IplImage resizeImage(IplImage origImg)
	  {
	  	IplImage outImg = null;
	  	int origWidth=0;
	  	int origHeight=0;
	  	if (origImg!=null) {
	  		origWidth = origImg.width();
	  		origHeight = origImg.height();
	  	}
	  	if (newWidth <= 0 || newHeight <= 0 || origImg == null || origWidth <= 0 || origHeight <= 0) {
	  		LOGGER.info("ERROR in resizeImage: Bad desired image size of");
	  		LOGGER.info(String.valueOf(newWidth)+","+String.valueOf(newHeight));
	  		System.exit(1);
	  	}
	
	  	// Scale the image to the new dimensions, even if the aspect ratio will be changed.
	  	outImg = cvCreateImage(cvSize(newWidth, newHeight), origImg.depth(), origImg.nChannels());
	  	if (newWidth > origImg.width() && newHeight > origImg.height()) {
	  		// Make the image larger
	  		cvResetImageROI((IplImage)origImg);
	  		cvResize(origImg, outImg, CV_INTER_LINEAR);	// CV_INTER_CUBIC or CV_INTER_LINEAR is good for enlarging
	  	}
	  	else {
	  		// Make the image smaller
	  		cvResetImageROI((IplImage)origImg);
	  		cvResize(origImg, outImg, CV_INTER_AREA);	// CV_INTER_AREA is good for shrinking / decimation, but bad at enlarging.
	  	}
	
	  	return outImg;
	  }
	
	
	
	 private IplImage cropImage(IplImage img, CvRect region)
	  {
		
	  	IplImage imageTmp;
	  	IplImage imageRGB;
	
	  //	size.height()=img.height();
	  //	size.width() = img.width();
	  	
	  	if (img.depth() != IPL_DEPTH_8U) {
	  		LOGGER.info("ERROR in cropImage: Unknown image depth of");
	  		LOGGER.info(String.valueOf(img.depth()));
	  		LOGGER.info(" given in cropImage() instead of 8 bits per pixel.");
	  		System.exit(1);
	  	}
	
	  	// First create a new (color or greyscale) IPL Image and copy contents of img into it.
	  	imageTmp = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, img.nChannels());
	  	cvCopy(img, imageTmp);
	  	
	  	// Create a new image of the detected region
	  	// Set region of interest to that surrounding the face
	  	cvSetImageROI(imageTmp, region);
	  	// Copy region of interest (i.e. face) into a new iplImage (imageRGB) and return it
	  	imageRGB = cvCreateImage(cvSize(region.width(),region.height()),  IPL_DEPTH_8U, img.nChannels());
	  	cvCopy(imageTmp, imageRGB);	// Copy just the region.
	
	      cvReleaseImage(imageTmp);
	      //region.setNull();
	  	return imageRGB;	
		}
	
	   
	 
	 public boolean recognizeFromCam() throws Exception
	  {
		 	OpenCVFrameGrabber  grabber = null;
		 	FileDialog fd;
		  	IplImage pFrame=null;
		  	int keypress = 0;
		  	if(LoginShell.video_flag)//如果被选,刚用视频
		  	{	
		  		fd=new FileDialog(LoginShell.sShell,SWT.OPEN);  
		  		fd.setFilterExtensions(new String[]{"*.avi","*.wmv","*.mp4","*.*"});
		  		fd.setFilterNames(new String[]{".avi",".wmv",".mp4"});
		  		String filename=fd.open();
		  		grabber = OpenCVFrameGrabber.createDefault(filename);
		  	}
		  	else
		  		grabber = OpenCVFrameGrabber.createDefault(0);
			grabber.start();
	        pFrame = grabber.grab();  
	        while( pFrame!=null ){
        		detectAndCropAndPre( pFrame,cascade,CV_HAAR_DO_CANNY_PRUNING | CV_HAAR_DO_ROUGH_SEARCH);			        
	        	cvShowImage("Press 'Esc' to Stop!",pFrame);
		  		pFrame = grabber.grab();
		  		keypress=cvWaitKey(24);
		  		System.out.println(g_confidence);
		  		if( keypress== 27){	
		  			grabber.release();
		  			cvDestroyWindow("Press 'Esc' to Stop!");
		  			break;
		  		}
	        }
	        cvWaitKey(1000);
	        cvReleaseImage(pFrame);
	        //cvDestroyWindow("BP_FaceRecognizer_FaceLogin");
	        grabber.release();
			return false;
	  }
	 
	 public void recongizeFormImage(String filePath){
		 	IplImage signleImage=null;
		 	System.out.println(filePath);
		 	signleImage=cvLoadImage(filePath);
		 	if(!signleImage.isNull());
		 		detectAndCropFromImg(signleImage,cascade,CV_HAAR_DO_CANNY_PRUNING | CV_HAAR_DO_ROUGH_SEARCH);			        
	        cvShowImage("Press 'Esc' to exit",signleImage);
		 	cvWaitKey(0);
		 	cvDestroyWindow("Press 'Esc' to exit");
	 }
	 
	 
	 
	
	 public boolean register(String name)throws Exception
	 {	 
		 	boolean flag=true;
		 	OpenCVFrameGrabber  grabber = null;
		 	FileDialog fd;
		 	IplImage pFrame=null;
		  	int keypress = 0;
		  	int countSecond=0;
		  	
			for(int i=0;i<personNames.size();i++){
				if(name.equals(personNames.get(i).toString()))
				{
					MessageBox messageBox = new MessageBox(RegisterShell.sShell, SWT.ICON_QUESTION |SWT.YES | SWT.NO);
					messageBox.setMessage("此用户已经被使用!!!连续按 “否” 返回");	
					messageBox.open();
					flag=false;
				}
			}
			  
		  	if(LoginShell.video_flag)//用视频文件进行注册
		  	{
		  		fd=new FileDialog(LoginShell.sShell,SWT.OPEN);  
		  		fd.setFilterExtensions(new String[]{"*.avi","*.wmv","*.mp4","*.*"});
		  		fd.setFilterNames(new String[]{".avi",".wmv",".mp4"});
		  		String filename=fd.open();
		  		grabber = OpenCVFrameGrabber.createDefault(filename);
		  	}
		  	else
		  		grabber = OpenCVFrameGrabber.createDefault(0);
	  		grabber.start();
	        pFrame = grabber.grab();		        	        
	        while( pFrame!=null )
	        {
	        	countSecond++;
	        	detectForRegister(pFrame,cascade,CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_DO_ROUGH_SEARCH,name);
	        	cvShowImage("Press 'Esc' to Stop",pFrame);
		  		pFrame = grabber.grab();
		  		keypress=cvWaitKey(24);
		  		if( keypress== 27 ||countSecond==100||countSavedFace==6)//||second==60
		  		{	
		  			cvReleaseImage(pFrame);
		  			grabber.release();
		  			break;  			
		  		}
	        }

	        personNames.add(name);
	        writeNameToTXT(name);
	        learn("data\\ForTraining.txt");
	        cvDestroyWindow("Press 'Esc' to Stop");
		 	return flag;
	 }
	 
 
	 
	 
	 private void detectForRegister(IplImage src,CvHaarClassifierCascade cascade,int flag,String name){

	 	IplImage greyImg=null;
	 	IplImage faceImg=null;
	 	IplImage sizedImg=null;
	 	IplImage equalizedImg=null;

	 	
	 	CvRect r ;
	 	CvFont font = new CvFont(CV_FONT_HERSHEY_COMPLEX_SMALL, 1, 1); 
		cvInitFont(font,CV_FONT_HERSHEY_COMPLEX_SMALL, 1.0, 0.8,1,1,CV_AA);
	 	greyImg = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 1 );	 	
		greyImg=convertImageToGreyscale(src);
		CvMemStorage storage = CvMemStorage.create();
		
		CvSeq sign = cvHaarDetectObjects(
				greyImg,
				cascade,
				storage,
				1.1,
				3,
				flag);
		cvClearMemStorage(storage);
		if(sign.total()==1)//只会有一个脸部
		{	
			r = new CvRect(cvGetSeqElem(sign, 0));
		  	faceImg = cropImage(greyImg, r);		
			sizedImg = resizeImage(faceImg);
			equalizedImg = cvCreateImage(cvGetSize(sizedImg), 8, 1);	
			cvEqualizeHist(sizedImg, equalizedImg);		
			cvRectangle (
							src,
							cvPoint(r.x(), r.y()),
							cvPoint(r.width() + r.x(), r.height() + r.y()),
							CvScalar.WHITE,
							1,
							CV_AA,
							0);
			cvPutText(src, "This is your No."+String.valueOf(countSavedFace)+" photos. " ,cvPoint(r.x()-30, r.y() + r.height() + 30), font, CvScalar.RED);				
			cvSaveImage("img\\"+name+countSavedFace+".jpg",equalizedImg);
			cvWaitKey(1000);
			countSavedFace++;	
			cvReleaseImage(greyImg);
		  	cvReleaseImage(faceImg);
		  	cvReleaseImage(sizedImg);
		  	cvReleaseImage(equalizedImg);	
		}
		
			
	
		
}
		
		  			 
	 
	 private  void writeNameToTXT(String name){
			String text=null;
			int temp;
			temp=personNames.size();
			if(temp==0)
				temp=temp+1;
				
			try {
			     File file = new File("data\\ForTraining.txt");
			     FileOutputStream fos = new FileOutputStream(file,true);
			     OutputStreamWriter osw = new OutputStreamWriter(fos);
			     BufferedWriter bw = new BufferedWriter(osw);
			    // if(personNames.size()==0)
			    	 
			     for(int i=1;i<6;i++){
				     text=temp+" "+name+" "+"img\\"+name+i+".jpg";
				     bw.write(text);
				     bw.newLine();
			     }
			     
			     bw.flush();
			     bw.close();
			     osw.close();
			     fos.close();

			}
			catch (FileNotFoundException e1) {
			     e1.printStackTrace();
			    } catch (IOException e2) {
			     e2.printStackTrace();
			    }
	 }
	 
	 
	 private void eigenDecomImg(IplImage src){
	  	//CvMat trainPersonNumMat=null; 
	  	float confidence = 0.0f;
	  	int  nearest=0;
	  	int iNearest=0;
		
		
	  	LOGGER.info("=====================================Waiting For the camera .....");
	  //	
	  	if( trainPersonNumMat==null) {
	  		LOGGER.info("ERROR in recognizeFromCam(): Couldn't load the training data!\n");
	  		System.exit(1);
	  	}
		float[] projectedTestFace = new float[nEigens];
			cvEigenDecomposite(
				src,
				nEigens,
				eigenVectArr,
				0,
				null,
				pAvgTrainImg,
				projectedTestFace);
	
	    final FloatPointer pConfidence = new FloatPointer(confidence);
	    iNearest = findNearestNeighbor(projectedTestFace, new FloatPointer(pConfidence));
	    confidence = pConfidence.get();
	    nearest = trainPersonNumMat.data_i().get(iNearest);
	    personName="";
		textName=personNames.get(nearest-1);
		personName=personNames.get(nearest-1);
	    g_confidence=confidence;
		
	}
		   
	 
	 private void detectAndCropAndPre(IplImage src,CvHaarClassifierCascade cascade,int flag)
	 {
		  	int nearest=0;
		 	IplImage greyImg=null;
		 	IplImage faceImg=null;
		 	IplImage sizedImg=null;
		 	IplImage equalizedImg=null;
		 	boolean faceIsTrue=false;
		 	CvRect r ;
		 	CvFont font = new CvFont(CV_FONT_HERSHEY_COMPLEX_SMALL, 1, 1); 
			cvInitFont(font,CV_FONT_HERSHEY_COMPLEX_SMALL, 1.0, 0.8,1,1,CV_AA);
		 	greyImg = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 1 );	 	
			greyImg=convertImageToGreyscale(src);
			CvMemStorage storage = CvMemStorage.create();
			
			CvSeq sign = cvHaarDetectObjects(
					greyImg,
					cascade,
					storage,
					1.1,
					3,
					flag);
			cvClearMemStorage(storage);
			if(sign.total()>0)
			{
				
				for(int i=0;i<sign.total();i++)
				{
					r = new CvRect(cvGetSeqElem(sign, i));
				  	faceImg = cropImage(greyImg, r);	
					sizedImg = resizeImage(faceImg);
					if(i==0)
						equalizedImg = cvCreateImage(cvGetSize(sizedImg), 8, 1);	
					cvEqualizeHist(sizedImg, equalizedImg);				
					cvRectangle (
									src,
									cvPoint(r.x(), r.y()),
									cvPoint(r.width() + r.x(), r.height() + r.y()),
									CvScalar.WHITE,
									1,
									CV_AA,
									0);
				
					eigenDecomImg(equalizedImg);
					if(g_confidence*100>50){
						cvPutText(src, textName,cvPoint(r.x()-10, r.y() + r.height() + 20), font, CvScalar.WHITE);
						cvPutText(src, " conf="+Integer.valueOf((int) (g_confidence*100))+"%",cvPoint(r.x()-10, r.y() + r.height() + 40), font, CvScalar.GREEN);
						textName="unknow";
					}
					else {
						cvPutText(src, "unknow",cvPoint(r.x()-10, r.y() + r.height() + 20), font, CvScalar.WHITE);
						cvPutText(src, " conf="+Integer.valueOf((int) (g_confidence*100))+"%",cvPoint(r.x()-10, r.y() + r.height() + 40), font, CvScalar.GREEN);
					}
				}
				cvReleaseImage(greyImg);
			  	cvReleaseImage(faceImg);
			  	cvReleaseImage(sizedImg);
			  	cvReleaseImage(equalizedImg);
			}	
				
	
		}

	 private void detectAndCropFromImg(IplImage src,CvHaarClassifierCascade cascade,int flag)
	 {
		 	IplImage greyImg=null;
		 	IplImage faceImg=null;
		 	IplImage sizedImg=null;
		 	IplImage equalizedImg=null;
		 	CvRect r ;
		 	CvFont font = new CvFont(CV_FONT_HERSHEY_COMPLEX_SMALL, 1, 1); 
			cvInitFont(font,CV_FONT_HERSHEY_COMPLEX_SMALL, 1.0, 0.8,1,1,CV_AA);
		 	greyImg = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 1 );	 	
			greyImg=convertImageToGreyscale(src);
			CvMemStorage storage = CvMemStorage.create();
			
			CvSeq sign = cvHaarDetectObjects(
					greyImg,
					cascade,
					storage,
					1.1,
					3,
					flag);
			cvClearMemStorage(storage);
			if(sign.total()>0)
			{
				
				for(int i=0;i<sign.total();i++)
				{
					r = new CvRect(cvGetSeqElem(sign, i));
				  	faceImg = cropImage(greyImg, r);	
					sizedImg = resizeImage(faceImg);
					if(i==0)
						equalizedImg = cvCreateImage(cvGetSize(sizedImg), 8, 1);	
					cvEqualizeHist(sizedImg, equalizedImg);				
					cvRectangle (
									src,
									cvPoint(r.x(), r.y()),
									cvPoint(r.width() + r.x(), r.height() + r.y()),
									CvScalar.WHITE,
									1,
									CV_AA,
									0);
				
					eigenDecomImg(equalizedImg);
					if(g_confidence*100>50){
						cvPutText(src, textName,cvPoint(r.x()-10, r.y() + r.height() + 20), font, CvScalar.WHITE);
						cvPutText(src, " conf="+Integer.valueOf((int) (g_confidence*100))+"%",cvPoint(r.x()-10, r.y() + r.height() + 40), font, CvScalar.GREEN);
						textName="unknow";
					}
					else{
						cvPutText(src, "Unknow",cvPoint(r.x()-10, r.y() + r.height() + 20), font, CvScalar.WHITE);
						cvPutText(src, " conf="+Integer.valueOf((int) (g_confidence*100))+"%",cvPoint(r.x()-10, r.y() + r.height() + 40), font, CvScalar.GREEN);
					}
				}
			}
			else
				cvPutText(src, "can't find any face!",cvPoint(src.width()/2, src.height()/2), font, CvScalar.GREEN);
			//cvReleaseImage(greyImg);
			//if(!faceImg.isNull())
			//	cvReleaseImage(faceImg);
		  	//cvReleaseImage(sizedImg);
		  	//cvReleaseImage(equalizedImg);
		}	

			

	 
	 private IplImage[] loadFaceImgArray(final String filename) {
	    IplImage[] faceImgArr;
	    BufferedReader imgListFile;
	    String imgFilename;
	    int iFace = 0;
	    int nFaces = 0;
	    int i;
	    try {
	      // open the input file
	      imgListFile = new BufferedReader(new FileReader(filename));
	
	      // count the number of faces
	      while (true) {
	        final String line = imgListFile.readLine();
	        if (line == null || line.isEmpty()) {
	          break;
	        }
	        nFaces++;
	      }
	      LOGGER.info("nFaces: " + nFaces);
	      imgListFile = new BufferedReader(new FileReader(filename));
	
	      // allocate the face-image array and person number matrix
	      faceImgArr = new IplImage[nFaces];
	      personNumTruthMat = cvCreateMat(
	              1, // rows
	              nFaces, // cols
	              CV_32SC1); // type, 32-bit unsigned, one channel
	
	      // initialize the person number matrix - for ease of debugging
	      for (int j1 = 0; j1 < nFaces; j1++) {
	        personNumTruthMat.put(0, j1, 0);
	      }
	
	      personNames.clear();        // Make sure it starts as empty.
	      nPersons = 0;
	
	      // store the face images in an array
	      for (iFace = 0; iFace < nFaces; iFace++) {
	        String personName;
	        String sPersonName;
	        int personNumber;
	
	        // read person number (beginning with 1), their name and the image filename.
	        final String line = imgListFile.readLine();
	        if (line.isEmpty()) {
	          break;
	        }
	        final String[] tokens = line.split(" ");
	        personNumber = Integer.parseInt(tokens[0]);
	        personName = tokens[1];
	        imgFilename = tokens[2];
	        sPersonName = personName;
	        LOGGER.info("Got " + iFace + " " + personNumber + " " + personName + " " + imgFilename);
	
	        // Check if a new person is being loaded.
	        if (personNumber > nPersons) {
	          // Allocate memory for the extra person (or possibly multiple), using this new person's name.
	          personNames.add(sPersonName);
	          nPersons = personNumber;
	          LOGGER.info("Got new person " + sPersonName + " -> nPersons = " + nPersons + " [" + personNames.size() + "]");
	        }
	
	        // Keep the data
	        personNumTruthMat.put(
	                0, // i
	                iFace, // j
	                personNumber); // v
	
	        // load the face image
	        faceImgArr[iFace] = cvLoadImage(
	                imgFilename, // filename
	                CV_LOAD_IMAGE_GRAYSCALE); // isColor
	
	        if (faceImgArr[iFace] == null) {
	          throw new RuntimeException("Can't load image from " + imgFilename);
	        }
	      }
	
	      imgListFile.close();
	
	    } catch (IOException ex) {
	      throw new RuntimeException(ex);
	    }
	
	    LOGGER.info("Data loaded from '" + filename + "': (" + nFaces + " images of " + nPersons + " people).");
	    final StringBuilder stringBuilder = new StringBuilder();
	    stringBuilder.append("People: ");
	    if (nPersons > 0) {
	      stringBuilder.append("<").append(personNames.get(0)).append(">");
	    }
	    for (i = 1; i < nPersons && i < personNames.size(); i++) {
	      stringBuilder.append(", <").append(personNames.get(i)).append(">");
	    }
	    LOGGER.info(stringBuilder.toString());
	
	    return faceImgArr;
	  }
	
	  
	  private void doPCA() {
	    int i;
	    CvTermCriteria calcLimit;
	    CvSize faceImgSize = new CvSize();
	
	    // set the number of eigenvalues to use
	    nEigens = nTrainFaces-1 ;
	
	    LOGGER.info("allocating images for principal component analysis, using " + nEigens + (nEigens == 1 ? " eigenvalue" : " eigenvalues"));
	
	    // allocate the eigenvector images
	    faceImgSize.width(trainingFaceImgArr[0].width());
	    faceImgSize.height(trainingFaceImgArr[0].height());
	    eigenVectArr = new IplImage[nEigens];
	    for (i = 0; i < nEigens; i++) {
	      eigenVectArr[i] = cvCreateImage(
	              faceImgSize, // size
	              IPL_DEPTH_32F, // depth
	              1); // channels
	    }
	
	    // allocate the eigenvalue array
	    eigenValMat = cvCreateMat(
	            1, // rows
	            nEigens, // cols
	            CV_32FC1); // type, 32-bit float, 1 channel
	
	    // allocate the averaged image
	    pAvgTrainImg = cvCreateImage(
	            faceImgSize, // size
	            IPL_DEPTH_32F, // depth
	            1); // channels
	
	    // set the PCA termination criterion
	    calcLimit = cvTermCriteria(
	            CV_TERMCRIT_ITER, // type
	            nEigens, // max_iter
	            1); // epsilon
	
	    LOGGER.info("computing average image, eigenvalues and eigenvectors");
	    // compute average image, eigenvalues, and eigenvectors
	    cvCalcEigenObjects(
	            nTrainFaces, // nObjects
	            trainingFaceImgArr, // input
	            eigenVectArr, // output
	            CV_EIGOBJ_NO_CALLBACK, // ioFlags
	            0, // ioBufSize
	            null, // userData
	            calcLimit,
	            pAvgTrainImg, // avg
	            eigenValMat.data_fl()); // eigVals
	
	    LOGGER.info("normalizing the eigenvectors");
	    cvNormalize(
	            eigenValMat, // src (CvArr)
	            eigenValMat, // dst (CvArr)
	            1, // a
	            0, // b
	            CV_L1, // norm_type
	            null); // mask
	  }
	
	 
	  private void storeTrainingData() {
	    CvFileStorage fileStorage;
	    int i;
	
	    LOGGER.info("writing data/facedata.xml");
	
	    // create a file-storage interface
	    fileStorage = cvOpenFileStorage(
	            "data\\facedata.xml", // filename
	            null, // memstorage
	            CV_STORAGE_WRITE, // flags
	            null); // encoding
	
	    // Store the person names. Added by Shervin.
	    cvWriteInt(
	            fileStorage, // fs
	            "nPersons", // name
	            nPersons); // value
	
	    for (i = 0; i < nPersons; i++) {
	      String varname = "personName_" + (i + 1);
	      cvWriteString(
	              fileStorage, // fs
	              varname, // name
	              personNames.get(i), // string
	              0); // quote
	    }
	
	    // store all the data
	    cvWriteInt(
	            fileStorage, // fs
	            "nEigens", // name
	            nEigens); // value
	
	    cvWriteInt(
	            fileStorage, // fs
	            "nTrainFaces", // name
	            nTrainFaces); // value
	
	    cvWrite(
	            fileStorage, // fs
	            "trainPersonNumMat", // name
	            personNumTruthMat); // value
	
	    cvWrite(
	            fileStorage, // fs
	            "eigenValMat", // name
	            eigenValMat); // value
	
	    cvWrite(
	            fileStorage, // fs
	            "projectedTrainFaceMat", // name
	            projectedTrainFaceMat);
	
	    cvWrite(fileStorage, // fs
	            "avgTrainImg", // name
	            pAvgTrainImg); // value
	
	    for (i = 0; i < nEigens; i++) {
	      String varname = "eigenVect_" + i;
	      cvWrite(
	              fileStorage, // fs
	              varname, // name
	              eigenVectArr[i]); // value
	    }
	
	    // release the file-storage interface
	    cvReleaseFileStorage(fileStorage);
	  }
	
	
	  private CvMat loadTrainingData() {
	    LOGGER.info("loading training data");
	    CvMat pTrainPersonNumMat = null; // the person numbers during training
	    CvFileStorage fileStorage;
	    int i;
	
	    // create a file-storage interface
	    fileStorage = cvOpenFileStorage(
	            "data\\facedata.xml", // filename
	            null, // memstorage
	            CV_STORAGE_READ, // flags
	            null); // encoding
	    if (fileStorage == null) {
	      LOGGER.severe("Can't open training database file 'data/facedata.xml'.");
	      return null;
	    }
	
	    // Load the person names.
	    personNames.clear();        // Make sure it starts as empty.
	    nPersons = cvReadIntByName(
	            fileStorage, // fs
	            null, // map
	            "nPersons", // name
	            0); // default_value
	    if (nPersons == 0) {
	      LOGGER.severe("No people found in the training database 'data/facedata.xml'.");
	      return null;
	    } else {
	      LOGGER.info(nPersons + " persons read from the training database");
	    }
	
	    // Load each person's name.
	    for (i = 0; i < nPersons; i++) {
	      String sPersonName;
	      String varname = "personName_" + (i + 1);
	      sPersonName = cvReadStringByName(
	              fileStorage, // fs
	              null, // map
	              varname,
	              "");
	      personNames.add(sPersonName);
	    }
	    LOGGER.info("person names: " + personNames);
	
	    // Load the data
	    nEigens = cvReadIntByName(
	            fileStorage, // fs
	            null, // map
	            "nEigens",
	            0); // default_value
	    nTrainFaces = cvReadIntByName(
	            fileStorage,
	            null, // map
	            "nTrainFaces",
	            0); // default_value
	    Pointer pointer = cvReadByName(
	            fileStorage, // fs
	            null, // map
	            "trainPersonNumMat"); // name
	    pTrainPersonNumMat = new CvMat(pointer);
	
	    pointer = cvReadByName(
	            fileStorage, // fs
	            null, // map
	            "eigenValMat"); // name
	    eigenValMat = new CvMat(pointer);
	
	    pointer = cvReadByName(
	            fileStorage, // fs
	            null, // map
	            "projectedTrainFaceMat"); // name
	    projectedTrainFaceMat = new CvMat(pointer);
	
	    pointer = cvReadByName(
	            fileStorage,
	            null, // map
	            "avgTrainImg");
	    pAvgTrainImg = new IplImage(pointer);
	
	    eigenVectArr = new IplImage[nTrainFaces];
	    for (i = 0; i <= nEigens; i++) {
	      String varname = "eigenVect_" + i;
	      pointer = cvReadByName(
	              fileStorage,
	              null, // map
	              varname);
	      eigenVectArr[i] = new IplImage(pointer);
	    }
	
	    // release the file-storage interface
	    cvReleaseFileStorage(fileStorage);
	
	    LOGGER.info("Training data loaded (" + nTrainFaces + " training images of " + nPersons + " people)");
	    final StringBuilder stringBuilder = new StringBuilder();
	    stringBuilder.append("People: ");
	    if (nPersons > 0) {
	      stringBuilder.append("<").append(personNames.get(0)).append(">");
	    }
	    for (i = 1; i < nPersons; i++) {
	      stringBuilder.append(", <").append(personNames.get(i)).append(">");
	    }
	    LOGGER.info(stringBuilder.toString());
	
	    return pTrainPersonNumMat;
	  }
	

	  private void storeEigenfaceImages() {
	    // Store the average image to a file
	    LOGGER.info("Saving the image of the average face as 'data/out_averageImage.bmp'");
	    cvSaveImage("img\\out_averageImage.jpg", pAvgTrainImg);
	
	    // Create a large image made of many eigenface images.
	    // Must also convert each eigenface image to a normal 8-bit UCHAR image instead of a 32-bit float image.
	    LOGGER.info("Saving the " + nEigens + " eigenvector images as 'data/out_eigenfaces.bmp'");
	
	    if (nEigens > 0) {
	      // Put all the eigenfaces next to each other.
	      int COLUMNS = 8;        // Put upto 8 images on a row.
	      int nCols = Math.min(nEigens, COLUMNS);
	      int nRows = 1 + (nEigens / COLUMNS);        // Put the rest on new rows.
	      int w = eigenVectArr[0].width();
	      int h = eigenVectArr[0].height();
	      CvSize size = cvSize(nCols * w, nRows * h);
	      final IplImage bigImg = cvCreateImage(
	              size,
	              IPL_DEPTH_8U, // depth, 8-bit Greyscale UCHAR image
	              1);        // channels
	      for (int i = 0; i < nEigens; i++) {
	        // Get the eigenface image.
	        IplImage byteImg = convertFloatImageToUcharImage(eigenVectArr[i]);
	        // Paste it into the correct position.
	        int x = w * (i % COLUMNS);
	        int y = h * (i / COLUMNS);
	        CvRect ROI = cvRect(x, y, w, h);
	        cvSetImageROI(
	                bigImg, // image
	                ROI); // rect
	        cvCopy(
	                byteImg, // src
	                bigImg, // dst
	                null); // mask
	        cvResetImageROI(bigImg);
	        cvReleaseImage(byteImg);
	      }
	      cvSaveImage(
	              "img\\out_eigenfaces.jpg", // filename
	              bigImg); // image
	      cvReleaseImage(bigImg);
	    }
	  }
	
	
	  private IplImage convertFloatImageToUcharImage(IplImage srcImg) {
		  IplImage dstImg;
		  if ((srcImg != null) && (srcImg.width() > 0 && srcImg.height() > 0)) {
		      // Spread the 32bit floating point pixels to fit within 8bit pixel range.
		      CvPoint minloc = new CvPoint();
		      CvPoint maxloc = new CvPoint();
		      double[] minVal = new double[1];
		      double[] maxVal = new double[1];
		      cvMinMaxLoc(srcImg, minVal, maxVal, minloc, maxloc, null);
		      // Deal with NaN and extreme values, since the DFT seems to give some NaN results.
		      if (minVal[0] < -1e30) {
		        minVal[0] = -1e30;
		      }
		      if (maxVal[0] > 1e30) {
		        maxVal[0] = 1e30;
		      }
		      if (maxVal[0] - minVal[0] == 0.0f) {
		        maxVal[0] = minVal[0] + 0.001;  // remove potential divide by zero errors.
		      }                        // Convert the format
		      dstImg = cvCreateImage(cvSize(srcImg.width(), srcImg.height()), 8, 1);
		      cvConvertScale(srcImg, dstImg, 255.0 / (maxVal[0] - minVal[0]), -minVal[0] * 255.0 / (maxVal[0] - minVal[0]));
		      return dstImg;
	    }
	    return null;
	  }
	
	
	  private int findNearestNeighbor(float projectedTestFace[], FloatPointer pConfidencePointer) {
	    double leastDistSq = Double.MAX_VALUE;
	    int i = 0;
	    int iTrain = 0;
	    int iNearest = 0;
	
	    LOGGER.info("................");
	    LOGGER.info("find nearest neighbor from " + nTrainFaces + " training faces");
	    for (iTrain = 0; iTrain < nTrainFaces; iTrain++) {
	      //LOGGER.info("considering training face " + (iTrain + 1));
	      double distSq = 0;
	
	      for (i = 0; i < nEigens; i++) {
	        //LOGGER.debug("  projected test face distance from eigenface " + (i + 1) + " is " + projectedTestFace[i]);
	
	        float projectedTrainFaceDistance = (float) projectedTrainFaceMat.get(iTrain, i);
	        float d_i = projectedTestFace[i] - projectedTrainFaceDistance;
	        distSq += d_i * d_i; // / eigenValMat.data_fl().get(i);  // Mahalanobis distance (might give better results than Eucalidean distance)
	//          if (iTrain < 5) {
	//            LOGGER.info("    ** projected training face " + (iTrain + 1) + " distance from eigenface " + (i + 1) + " is " + projectedTrainFaceDistance);
	//            LOGGER.info("    distance between them " + d_i);
	//            LOGGER.info("    distance squared " + distSq);
	//          }
	      }
	
	      if (distSq < leastDistSq) {
	        leastDistSq = distSq;
	        iNearest = iTrain;
	        LOGGER.info("  training face " + (iTrain + 1) + " is the new best match, least squared distance: " + leastDistSq);
	      }
	    }
	
	    // Return the confidence level based on the Euclidean distance,
	    // so that similar images should give a confidence between 0.5 to 1.0,
	    // and very different images should give a confidence between 0.0 to 0.5.
	    float pConfidence = (float) (1.0f - Math.sqrt(leastDistSq / (float) (nTrainFaces * nEigens)) / 255.0f);
	    pConfidencePointer.put(pConfidence);
	
	    LOGGER.info("training face " + (iNearest + 1) + " is the final best match, confidence " + pConfidence);
	    return iNearest;
	  }
	
	  
	  private String floatArrayToString(final float[] floatArray) {
	    final StringBuilder stringBuilder = new StringBuilder();
	    boolean isFirst = true;
	    stringBuilder.append('[');
	    for (int i = 0; i < floatArray.length; i++) {
	      if (isFirst) {
	        isFirst = false;
	      } 
	      else {
	        stringBuilder.append(", ");
	      }
	      stringBuilder.append(floatArray[i]);
	    }
	    stringBuilder.append(']');
	
	    return stringBuilder.toString();
	  }
	

	  private String floatPointerToString(final FloatPointer floatPointer) {
	    final StringBuilder stringBuilder = new StringBuilder();
	    boolean isFirst = true;
	    stringBuilder.append('[');
	    for (int i = 0; i < floatPointer.capacity(); i++) {
	      if (isFirst) {
	        isFirst = false;
	      } else {
	        stringBuilder.append(", ");
	      }
	      stringBuilder.append(floatPointer.get(i));
	    }
	    stringBuilder.append(']');
	
	    return stringBuilder.toString();
	  }
	

	 private String oneChannelCvMatToString(final CvMat cvMat) {
	    //Preconditions
	    if (cvMat.channels() != 1) {
	      throw new RuntimeException("illegal argument - CvMat must have one channel");
	    }
	
	    final int type = cvMat.type();
	    StringBuilder s = new StringBuilder("[ ");
	    for (int i = 0; i < cvMat.rows(); i++) {
	      for (int j = 0; j < cvMat.cols(); j++) {
	        if (type == CV_32FC1 || type == CV_32SC1) {
	          s.append(cvMat.get(i, j));
	        } else {
	          throw new RuntimeException("illegal argument - CvMat must have one channel and type of float or signed integer");
	        }
	        if (j < cvMat.cols() - 1) {
	          s.append(", ");
	        }
	      }
	      if (i < cvMat.rows() - 1) {
	        s.append("\n  ");
	      }
	    }
	    s.append(" ]");
	    return s.toString();
	  }
	}


网友评论    (发表评论)

共13 条评论 1/1页

发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...