opencv人脸识别

 前几天用Java做了一个人脸识别项目,当时的我还不了解OpenCV是什么,然后突击学习了opencv大概的了解了它的内容,就开始项目的编写了,opencvmat了解一下

opencv的概念

定义识别规则
  haarcascade_frontalface_alt.xml
 摄像头类 对象
  VideoCapture
  read(Mat);// 拍一次
  Mat //一张相片
OpenVCTools
  Mat-Image的转换
  BufferedImage mat2BufferedImage(Mat)
 

 

前提:

 所有的UI显示的内容,都是画出来
  JVM一个专门的线程定时画
  paintComponent(G...)方法

思路
  重写组件的paintComponent()方法
  在里面追加我们要画图片的逻辑代码
手段
  写一个类,继承JPanel,重写paintComponent()方法
     super.paintComponent();
     画图片
     获取图片文件对应的Image对象
     加载图片文件->url
     将url封装成ImageIcon
     从ImageIcon获取Image对象
     g.drawImage(xxx);
 

 

显示一张图片功能的功能:
  1 创建摄像头对象
  2 使用摄像头拍一张照片
  3 将照片转换成图片
  4 将图片画在JPanel上面

下面是openvctools的代码

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

public final class OpenVCTools {
	public final static String FACE_DETECTOR_XML = "e:/work/code/temp/haarcascade_frontalface_alt.xml";
	public static Mat convImageFile2Mat(String imgFile, String detectorXml) {
		CascadeClassifier detector = new CascadeClassifier(detectorXml);
        return convImageFile2Mat(imgFile, detector);
    }
	public static Mat convImageFile2Mat(String imgFile, CascadeClassifier detector) {
        Mat image0 = Imgcodecs.imread(imgFile);

        Mat image = new Mat();
        //灰度转换
        Imgproc.cvtColor(image0, image, Imgproc.COLOR_BGR2GRAY);
        MatOfRect faceDetections = new MatOfRect();
        //探测人脸
        detector.detectMultiScale(image, faceDetections);

        // rect中是人脸图片的范围
        for (Rect rect : faceDetections.toArray()) {
            //切割rect人脸
            Mat mat = new Mat(image, rect);
            return mat;
        }
        return null;
    }
	public static void writeMat(String fileName, Mat capImg) {
		Mat mat = new Mat();
		Imgproc.cvtColor(capImg, mat, Imgproc.COLOR_RGB2GRAY);
		Imgcodecs.imwrite(fileName, mat);
	}
	public static BufferedImage mat2BufferedImage(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 static Mat fetchMat(VideoCapture capture)throws Exception{
		Mat capImg = new Mat();
		capture.read(capImg);
		return capImg;
	}
	public static double compareMats(Mat mat1, Mat mat2) {
		double result = 0;
		Mat hist_1 = new Mat();
        Mat hist_2 = new Mat();

        //颜色范围
        MatOfFloat ranges = new MatOfFloat(0f, 256f);
        //直方图大小, 越大匹配越精确 (越慢)
        MatOfInt histSize = new MatOfInt(1000);

        Imgproc.calcHist(Arrays.asList(mat1), new MatOfInt(0), new Mat(), hist_1, histSize, ranges);
        Imgproc.calcHist(Arrays.asList(mat2), new MatOfInt(0), new Mat(), hist_2, histSize, ranges);

        // CORREL 相关系数
        result = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL);
		return result;
                 }
	public static DetectResult detectEye(Mat img, Rect faceRect, String eyeXml) throws Exception{
		if(img == null || faceRect == null) {
			return null;
		}
		DetectResult result = new DetectResult();
		if (eyeXml == null || "".equals(eyeXml)) {
			throw new RuntimeException("没有face识别器文件");
		}
		CascadeClassifier eyeDetector = new CascadeClassifier(eyeXml);
		Mat faceMat = new Mat(img, faceRect);
        // 在图片中检测眼睛
        MatOfRect eyeDetections = new MatOfRect();
        eyeDetector.detectMultiScale(faceMat, eyeDetections);
        Rect[] eyeRects = eyeDetections.toArray();
        if (null != eyeRects && eyeRects.length >= 2) {
            for (Rect eyeRect : eyeRects) {
                // 需要加上人脸框的坐标
                Imgproc.rectangle(img, new Point(faceRect.x + eyeRect.x, faceRect.y + eyeRect.y),
                        new Point(faceRect.x + eyeRect.x + eyeRect.width, faceRect.y + eyeRect.y + eyeRect.height),
                        new Scalar(213, 223, 255), 2);
                result.rectHeight.add(eyeRect.height);
    			result.rectWidth.add(eyeRect.width);
    			result.rectX.add(faceRect.x+eyeRect.x);
    			result.rectY.add(faceRect.y+eyeRect.y);
            }
            
        }
        result.faceRect = faceRect;
        result.mat = img;
		return result;
		
	}
	public static DetectResult detectFace(Mat img, String faceXml) throws Exception {
		DetectResult result = new DetectResult();

		if (faceXml == null || "".equals(faceXml)) {
			throw new RuntimeException("没有face识别器文件");
		}

		CascadeClassifier faceDetector = new CascadeClassifier(faceXml);
		// 在图片中检测人脸
		MatOfRect faceDetections = new MatOfRect();
		faceDetector.detectMultiScale(img, faceDetections);
		Rect[] faceRects = faceDetections.toArray();
		// 只需要捕捉一张人脸
		if (faceRects != null && faceRects.length == 1) {
			Rect faceRect = faceRects[0];
			// 绘制矩形
			Imgproc.rectangle(img, new Point(faceRect.x, faceRect.y),
					new Point(faceRect.x + faceRect.width, faceRect.y + faceRect.height), 
					new Scalar(0, 0, 255), 2);
			result.rectHeight.add(faceRect.height);
			result.rectWidth.add(faceRect.width);
			result.rectX.add(faceRect.x);
			result.rectY.add(faceRect.y);
			result.faceRect = faceRect;
		}
		result.mat=img;
		return result;
	}

	public static DetectResult detectFace(Mat img, String faceXml, String eyeXml) throws Exception {
		DetectResult result = new DetectResult();
		if (faceXml == null && eyeXml == null) {
			throw new RuntimeException("没有识别器xml");
		}
		CascadeClassifier faceDetector = null;
		CascadeClassifier eyeDetector = null;

		if (faceXml != null) {
			faceDetector = new CascadeClassifier(faceXml);
		}
		if (eyeXml != null) {
			eyeDetector = new CascadeClassifier(eyeXml);
		}

		return result;
	}

	public static class DetectResult {
		public Mat mat;
		public Rect faceRect;
		public List rectX=new ArrayList();
		public List rectY=new ArrayList();
		public List rectWidth=new ArrayList();
		public List rectHeight=new ArrayList();
	}
}

  

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.LayoutStyle.ComponentPlacement;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JTextField;

public class openVCUI extends JFrame {

	private JPanel contentPane;
    private BufferedImage matImage;
    private JPanel panel;
    private VideoCapture capture;
    private boolean isRunning=true;
    private boolean isStop=true;
    private int count=4;
    private Mat mat;
    private Mat myMat;
    private JTextField textField;
	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					openVCUI frame = new openVCUI();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public openVCUI() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 625, 503);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		
		panel = new JPanel(){
			protected void paintComponent(Graphics g){
				super.paintComponent(g);
				if(matImage!=null){
					g.drawImage(matImage,0,0,this.getWidth(), this.getHeight(),this);
				}
			}
		};
		
		JButton button = new JButton("��ʼ");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				isRunning=true;
				Thread t=new Thread(){
					public void run(){
						System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
						capture=new VideoCapture(0);
						while(isRunning){
							mat =new Mat();
							capture.read(mat);
							//mat1=mat.clone();
							CascadeClassifier faceDetector=new CascadeClassifier(OpenCVTools.FACE_DETECTOR_XML);
							MatOfRect matOfRect=new MatOfRect();
							faceDetector.detectMultiScale(mat,matOfRect);
							Rect[] faceRects=matOfRect.toArray();
							if(faceRects !=null&&faceRects.length>0){
								Rect firstRect=faceRects[0];
								Imgproc.rectangle(mat, new Point(firstRect.x,firstRect.y), new Point(firstRect.x+firstRect.width,firstRect.y+firstRect.height),new Scalar(0, 0, 255), 2);								}
							myMat=mat;
							matImage=OpenCVTools.mat2BufferedImage(myMat);
	                        panel.repaint(); 
	                      //  isRunning=true;
						}
						capture.release();
						
					}
				};
				t.start();
//				System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//				VideoCapture capture=new VideoCapture(0);
//				Mat mat =new Mat();
//				capture.read(mat);
//				matImage =OpenVCTools.mat2BufferedImage(mat);
//				//cvtColor(matImage,matImage, CV_RGB2GRAY);//תΪ�Ҷ�ͼ
//			    panel.repaint();
//				capture.release();
			}
		});
		button.setFont(new Font("����", Font.PLAIN, 20));
		
		JButton btnStop = new JButton("����");
		btnStop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				isRunning=false;
			}
		});
		btnStop.setFont(new Font("����", Font.PLAIN, 20));
		
		JButton button_1 = new JButton("�Ա�");
		button_1.setFont(new Font("����", Font.PLAIN, 20));
		button_1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//CascadeClassifier faceDedector=new CascadeClassfier();
			//	1 ץ������ͷ���ĵ���
				// ��������ʶ����
				CascadeClassifier faceDetector = new CascadeClassifier(OpenCVTools.FACE_DETECTOR_XML);
				MatOfRect matOfRect = new MatOfRect();
				// ʶ��mat�е�������
				faceDetector.detectMultiScale(myMat, matOfRect);
				// ��ȡ������������
				Rect[] faceRects = matOfRect.toArray();
				Mat newFaceMat = null;
				if (faceRects != null && faceRects.length > 0) {
					// ��һ����
					newFaceMat = new Mat(myMat, faceRects[0]);
				}

//				2 ץ��������ͼƬ�ļ��е�������ǰ�ɼ��ģ�
				// 2.0 ��ȡ���е�ͼƬ�ļ�
				File dir = new File("E:\\Image");
				File[] files = dir.listFiles();
				if(files==null){
					System.out.println("ƥ�䲻�ɹ�");
				}
				if (files != null && files.length > 0) {
					String resultFileName = null;
					double finallyResult = 0.8;
					for (File f : files) {
						// ��ȡ�ļ��ģ�����·��������
						String fileName = f.getAbsolutePath();
//				  2.1 ��ȡ�ļ�-��Mat
						Mat fileMat = Imgcodecs.imread(fileName);
//				  2.2 ��Mat��ץȡ��
						faceDetector.detectMultiScale(fileMat, matOfRect);
						faceRects = matOfRect.toArray();
						Mat oldMat = null;
						if (faceRects != null && faceRects.length > 0) {
							oldMat = new Mat(fileMat, faceRects[0]);
						}
//				3 ������������ƥ���ʵıȶ�
						// ׼���ȶԵ�ϵ��
						// ����ϵ���ȶԽ��
						if (newFaceMat != null && !newFaceMat.empty() && oldMat != null && !oldMat.empty()) {
							double result = OpenCVTools.compareMats(newFaceMat, oldMat);
							System.out.println(result);
							if (result > finallyResult) {
								resultFileName = fileName;
							}
						}else{
							resultFileName=null;
						}
					}
					textField.setText(resultFileName);
				}else{
					System.out.println("ƥ�䲻�ɹ�");
				}
			}
		});
		
		textField = new JTextField();
		textField.setColumns(10);
		
		JButton button_2 = new JButton("\u91C7\u96C6");
		button_2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (myMat != null && !myMat.empty()) {
					System.out.println("123456789");
					Imgcodecs.imwrite("E:\\Image\\Image" + count++ + ".png", myMat);

				}
			}
		});
		button_2.setFont(new Font("����", Font.PLAIN, 20));
		
		GroupLayout gl_contentPane = new GroupLayout(contentPane);
		gl_contentPane.setHorizontalGroup(
			gl_contentPane.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_contentPane.createSequentialGroup()
					.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
						.addGroup(gl_contentPane.createSequentialGroup()
							.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING, false)
								.addGroup(gl_contentPane.createSequentialGroup()
									.addGap(98)
									.addComponent(panel, GroupLayout.PREFERRED_SIZE, 341, GroupLayout.PREFERRED_SIZE)
									.addPreferredGap(ComponentPlacement.RELATED))
								.addGroup(gl_contentPane.createSequentialGroup()
									.addGap(64)
									.addComponent(button)
									.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
									.addComponent(button_2)
									.addGap(49)
									.addComponent(btnStop)
									.addGap(58)))
							.addComponent(button_1))
						.addGroup(gl_contentPane.createSequentialGroup()
							.addGap(171)
							.addComponent(textField, GroupLayout.PREFERRED_SIZE, 259, GroupLayout.PREFERRED_SIZE)))
					.addContainerGap(87, Short.MAX_VALUE))
		);
		gl_contentPane.setVerticalGroup(
			gl_contentPane.createParallelGroup(Alignment.TRAILING)
				.addGroup(gl_contentPane.createSequentialGroup()
					.addGap(46)
					.addComponent(panel, GroupLayout.PREFERRED_SIZE, 287, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED, 46, Short.MAX_VALUE)
					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
						.addComponent(button)
						.addComponent(button_1)
						.addComponent(btnStop)
						.addComponent(button_2))
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addGap(7))
		);
		contentPane.setLayout(gl_contentPane);
	}
}

注意事项:路径问题不要出错

                  正确的配置opencv

                  合理的使用windowbuilder插件

                  建立文件夹来存放照片

你可能感兴趣的:(Java,opencv)