JDK1.6+OpenCV2.4.9+SWT 人脸识别

1. 前言

近期有个人脸识别的需求,这里使用到的是OpenCV.推荐大家使用最新版本,貌似识别准确.但是由于服务器环境(jdk版本)限制,只能使用老版本才能兼容.这里以OpenCV 2.4.9为例写一个demo.在jdk1.6环境上运行.

2. 配置环境
2.1 下载OpenCV

首先去官网下载OpenCV 2.4.9,地址https://opencv.org/releases.html.
解压到C盘,目录为C:\opencv-2.4.9.解压出来文件比较大,可以删除不必要的文件.
保留build/java目录和sources/data目录.

2.2 创建项目,添加依赖
  • 创建项目
    打开MyEclipse,新建一个项目opencv2.
  • 添加依赖
    右键选择Bulid Path–>Add Libraries...,弹出Add Library窗口,选择User Library,点击Next,再选择右侧的User Libraries...按钮,然后New一个,名字为OpenCV-2.4.9.添加好之后,选中,再选择右侧的Add External JARs...按钮添加C:\opencv-2.4.9\build\java里面的opencv-249.jar包.
    之后打开jar包,选中Native library location,点击右侧Edit按钮进行编辑.
    这里写图片描述
    选择External Folder,把C:\opencv-2.4.9\build\java\x86(根据JDK版本确定,64位则选择x64文件夹).确定保存.
    回到Add Library窗口,选择刚刚添加的OpenCV-2.4.9User Library保存.这样环境就配置好了.
3. 编写实现代码

实现类

import java.awt.Container;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;

public class Camera {
    private DaemonThread myThread = null;
    public Shell shell;
    private VideoCapture capture;
    private CascadeClassifier faceDetector;
    private JPanel panel;

    public Camera() {
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);//加载动态库
        capture = new VideoCapture(0);//打开摄像头
        String path = this.getClass().getResource("haarcascade_frontalface_alt2.xml").getPath();//跟Camera类在统一路径
        path = new File(path).getAbsolutePath();
        faceDetector = new CascadeClassifier(path);
    }

    // 摄像头显示模块
    public void initComponents() {
        Display display = Display.getDefault();
        shell = new Shell(display, SWT.EMBEDDED);
        shell.setBounds(0,0, 600, 400);//设置界面大小
        Frame frame = SWT_AWT.new_Frame(shell);
        frame.setLayout(null);
        panel = new JPanel();
        panel.setBounds((frame.getWidth() - 250) / 2, 10, 250, 300);//设置摄像头显示区域大小
        frame.add(panel);

        //提示语
        JLabel label = new JLabel("请把脸部对准摄像头,等待1-5秒");
        label.setBounds((frame.getWidth() - 210) / 2, 320, 210, 30);
        frame.add(label);

        myThread = new DaemonThread();
        Thread t = new Thread(myThread);
        myThread.runnable = true;
        t.start(); // start thrad
        shell.open();

        while (!shell.isDisposed()) {
            while (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        t.interrupt();
    }

    class DaemonThread implements Runnable {
        private Mat target = new Mat();
        private Mat sub;
        private String path = "C:\\opencv-2.4.9\\pic\\";// 照片存储位置
        protected volatile boolean runnable = false;
        private boolean isCollect = false;
        private int width, height;
        private Mat capImg;
        private MatOfByte mem;
        private MatOfRect faceDetections;

        public DaemonThread() {
            capImg = new Mat();
            mem = new MatOfByte();
            faceDetections = new MatOfRect();
        }

        @Override
        public void run() {
            capture.set(3, 250);//摄像头分辨率,3-表示width
            capture.set(4, 300);//摄像头分辨率,4-表示height
            Graphics g = panel.getGraphics();
            width = panel.getWidth();
            height = panel.getHeight();
            final Container parent = panel.getParent();
            final JLabel label = (JLabel) parent.getComponent(1);

            while (runnable) {
                try {
                    if (capture.grab()) {
                        capture.retrieve(capImg);
                        // Imgproc.cvtColor(capImg, capImg,Imgproc.COLOR_RGB2GRAY); //转变成灰色照片
						//设置人脸识别参数,如果使用默认的可以直接写成 faceDetector.detectMultiScale(capImg, faceDetections);
                        faceDetector.detectMultiScale(capImg, faceDetections, 1.2, 4, 0, new Size(80, 100), new Size(250, 300));

                        for (Rect rect : faceDetections.toArray()) {
                            int h = rect.height, w = rect.width, x = rect.x, y = rect.y;
                            if (!isCollect) {
                                sub = capImg.submat(new Rect(x, y, w, h));
                                Imgproc.resize(sub, target, new Size(w, h));// 将人脸进行截图并保存
                                Display.getDefault().asyncExec(new Runnable() {
                                    public void run() {
                                        String photoName = path + System.nanoTime() + ".jpg";
                                        Highgui.imwrite(photoName, target);
                                        label.setText("人脸信息已提取..."); 
										isCollect = true;//只截取一张图
                                    }
                                });
                            }
                            Core.rectangle(capImg, new Point(x, y), new Point(x + w, y + h), new Scalar(0, 255, 0), 2);//脸部区域
                        }
                    }
                    Highgui.imencode(".png", capImg, mem);

                    Image im = ImageIO.read(new ByteArrayInputStream(mem.toArray()));
                    BufferedImage buff = (BufferedImage) im;
					//把图像刷新到界面上
                    g.drawImage(buff, 0, 0, width, height, 50, 50, buff.getWidth() - 50, buff.getHeight() - 50, null);
                } catch (Exception ex) {
                    System.out.println("Error:" + ex.getLocalizedMessage());
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值