OpenCV检测人脸

package com.crscic;




import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;


import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;


import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDouble;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.objdetect.HOGDescriptor;
import org.opencv.highgui.VideoCapture;


/**
 * 调用摄像头检测人脸
 * @author biao
 * opencv2413.jar
 * SVM-十大经典数据挖掘算法-https://www.cnblogs.com/en-heng/p/5965438.html
 * 
 * 
 */
public class CaptureBasic2 extends JPanel {  
      
    private BufferedImage mImg;  
      
    private BufferedImage mat2BI(Mat mat){  
        int dataSize =mat.cols()*mat.rows()*(int)mat.elemSize();  
        byte[] data=new byte[dataSize];  
        mat.get(0, 0,data);  
        int type=mat.channels()==1?  
                BufferedImage.TYPE_BYTE_GRAY:BufferedImage.TYPE_3BYTE_BGR;  
          
        if(type==BufferedImage.TYPE_3BYTE_BGR){  
            for(int i=0;i<dataSize;i+=3){  
                byte blue=data[i+0];  
                data[i+0]=data[i+2];  
                data[i+2]=blue;  
            }  
        }  
        BufferedImage image=new BufferedImage(mat.cols(),mat.rows(),type);  
        image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data);  
          
        return image;  
    }  
  
    public void paintComponent(Graphics g){  
        if(mImg!=null){  
            g.drawImage(mImg, 0, 0, mImg.getWidth(),mImg.getHeight(),this);  
        }  
    }  
      
    public static void main(String[] args) {  
        try{  
            System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            Mat capImg=new Mat();  
            VideoCapture capture=new VideoCapture(0);
            /**
             * opencv中 以帧数来设置读入位置
             * 视频就是很多静态图像组合在一起,一秒钟30帧的播放,看起来就是动态的了。
			 * 但是opencv里面的queryframe提取出来的只是关键帧,
			 * 如果希望每一帧都能提取出来就比较麻烦了。
			 * 
             */
            //int height = (int)capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);  
            //int width = (int)capture.get(Videoio.CAP_PROP_FRAME_WIDTH);  
            int height = (int)capture.get(Highgui.CV_CAP_PROP_FRAME_HEIGHT);  
            int width = (int)capture.get(Highgui.CV_CAP_PROP_FRAME_WIDTH);  
            if(height==0||width==0){
                throw new Exception("camera not found!");  
            }
            
            JFrame frame = new JFrame("camera");  
            frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);  
            CaptureBasic2 panel=new CaptureBasic2();
            Mat temp=new Mat();
            panel.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent arg0) {  
                    System.out.println("click");
                    //鼠标点击的时候,进行人脸对比
                    Highgui.imwrite("E:\\gate2\\opencv\\temp\\click.png", temp);
            		String originalFilePath = "E:\\gate2\\opencv\\biao4.jpg"; 
            		/**
            		 * 读取图片文件,
            		 * CV_LOAD_IMAGE_COLOR- 如果取这个标识的话,总是转换图像到彩色一体
            		 * CV_LOAD_IMAGE_GRAYSCALE- 如果取这个标识的话,始终将图像转换成灰度1
            		 */ 
            		Mat originalImage = Highgui.imread(originalFilePath, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
            		ImageRecognition imageRecognition = new ImageRecognition();
            		imageRecognition.matchImage(temp, originalImage);
            		System.out.println("匹配的像素点总数:" + imageRecognition.getMatchesPointCount());
                }
                @Override
                public void mouseMoved(MouseEvent arg0) { 
                    System.out.println("move");
                }
                @Override
                public void mouseReleased(MouseEvent arg0) { 
                    System.out.println("mouseReleased");
                }
                @Override
                public void mousePressed(MouseEvent arg0) { 
                    System.out.println("mousePressed");
                }
                @Override
                public void mouseExited(MouseEvent arg0) { 
                    System.out.println("mouseExited");
                    //System.out.println(arg0.toString());
                }
                @Override
                public void mouseDragged(MouseEvent arg0) { 
                    System.out.println("mouseDragged");
                    //System.out.println(arg0.toString());
                }
            });
            frame.setContentPane(panel);  
            frame.setVisible(true);  
            frame.setSize(width+frame.getInsets().left+frame.getInsets().right,  
                    height+frame.getInsets().top+frame.getInsets().bottom);  
            int n=0;
           
            while(frame.isShowing()&& n<10){
                System.out.println("第"+n+"张");
                capture.read(capImg);
                Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_RGB2GRAY);
                //TODO 应该在此处对temp进行特征识别,满足特征的就去和库中的人脸进行对比。
                Highgui.imwrite("E:\\gate2\\opencv\\temp\\back"+n+".png", temp);
                panel.mImg = panel.mat2BI(detectFace(capImg));
                panel.repaint();
                //n++;
                //break;
            }  
            capture.release();  
            frame.dispose();  
        }catch(Exception e){  
            System.out.println("例外:" + e);  
        }finally{  
            System.out.println("--done--");  
        }  
  
    }
    /**
     * opencv实现人脸识别
     * @param img
     */
    public static Mat detectFace(Mat img) throws Exception{


        System.out.println("Running DetectFace ... ");
        // 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
        CascadeClassifier faceDetector = new CascadeClassifier("E:\\gate2\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");


        // 在图片中检测人脸
        MatOfRect faceDetections = new MatOfRect();


        faceDetector.detectMultiScale(img, faceDetections);


        //System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));


        Rect[] rects = faceDetections.toArray();
        //Mat tmp_img = new Mat();
        if(rects != null && rects.length >= 1){
            for (Rect rect : rects) {
            	//给脸上面画矩形
                Core.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),  
                        new Scalar(0, 0, 255), 2);  
            }
        }
        return img;
    }
    
    public static double calcArea(Rect rect)  {  
        return rect.width*rect.height;  
    }  
    
    /**
     * opencv实现人型识别,hog默认的分类器。所以效果不好。
     * @param img
     */
    public static Mat detectPeople(Mat img) {
        //System.out.println("detectPeople...");
        if (img.empty()) {  
            System.out.println("image is exist");  
        }  
        HOGDescriptor hog = new HOGDescriptor();
        hog.setSVMDetector(HOGDescriptor.getDefaultPeopleDetector());
        System.out.println(HOGDescriptor.getDefaultPeopleDetector());
        //hog.setSVMDetector(HOGDescriptor.getDaimlerPeopleDetector());  
        MatOfRect regions = new MatOfRect();  
        MatOfDouble foundWeights = new MatOfDouble(); 
        //System.out.println(foundWeights.toString());
        hog.detectMultiScale(img, regions, foundWeights);        
        for (Rect rect : regions.toArray()) {             
            Core.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),new Scalar(0, 0, 255), 2);  
        }  
        return img;  
    }
    
}

猜你喜欢

转载自blog.csdn.net/u012138706/article/details/80007400
今日推荐