嗨咯,又好久没有更新了。今天写个前阵子做的人脸识别程序。该程序客户端基于Jave JFrame
客户端的主要作用是,调用电脑的摄像头(我的直接调用笔记本摄像头),然后回显摄像头录取的信息,再利用openCV进行人脸识别。可以框出人脸、并采集人脸数据,采集好后进行模型训练,训练得到模型后,可以进行人脸对比。
这个客户端目前已经实现以上功能,但是实现得比较简单,每一步还需要手动点击,为了使他更智能,客户端目前还在改进。
所以今天就先简单讲下openCV的环境部署,以及基本的调用。
首先,要部署openCV的环境,解压openCV的环境包,然后配置环境变量。
这个包我已经上传我的资源,可以直接下载。也可以到openCV官网去进行下载。
解压以后长这样
然后,我们去系统环境变量里边,添加一下路径,我的包在F盘,所以环境变量为F:\face\install\x64\vc14\bin
然后是openCV的简单调用,以下这个类是调起摄像头,可以利用openCV识别出人脸,在画面上边画出框框
FaceDetection.java
package face.detect;import javax.swing.*;import face.util.VideoPanel;import org.opencv.core.Core;import org.opencv.core.Mat;import org.opencv.core.MatOfRect;import org.opencv.core.Rect;import org.opencv.core.Scalar;import org.opencv.core.Size;import org.opencv.imgproc.Imgproc;import org.opencv.objdetect.CascadeClassifier;import org.opencv.objdetect.Objdetect;import org.opencv.videoio.VideoCapture;public class FaceDetection {public static void main(String[] args) {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);// 新建窗口JFrame cameraFrame = new JFrame("camera");cameraFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);cameraFrame.setSize(640, 480);cameraFrame.setBounds(0, 0, cameraFrame.getWidth(), cameraFrame.getHeight());VideoPanel videoPanel = new VideoPanel();cameraFrame.setContentPane(videoPanel);cameraFrame.setVisible(true);CascadeClassifier faceCascade = new CascadeClassifier();// 获取模型文件faceCascade.load("F:/face/install/etc/haarcascades/haarcascade_frontalface_alt.xml");// 调用摄像头VideoCapture capture = new VideoCapture();try {capture.open(0);if (capture.isOpened()) {Mat image = new Mat();while(true) {capture.read(image);if (!image.empty()) {detectAndDisplay(image, faceCascade);videoPanel.setImageWithMat(image);cameraFrame.repaint();} else {break;}}}} finally {capture.release();}}/*** 绘制图形界面* @param frame* @param faceCascade*/public static void detectAndDisplay(Mat frame, CascadeClassifier faceCascade){MatOfRect faces = new MatOfRect();Mat grayFrame = new Mat();// convert the frame in gray scaleImgproc.cvtColor(frame, grayFrame, Imgproc.COLOR_BGR2GRAY);// equalize the frame histogram to improve the resultImgproc.equalizeHist(grayFrame, grayFrame);// compute minimum face size (20% of the frame height, in our case)int absoluteFaceSize = 0;int height = grayFrame.rows();if (Math.round(height * 0.2f) > 0) {absoluteFaceSize = Math.round(height * 0.2f);}// detect facesfaceCascade.detectMultiScale(grayFrame, faces, 1.1, 2, 0 | Objdetect.CASCADE_SCALE_IMAGE,new Size(absoluteFaceSize, absoluteFaceSize), new Size());// each rectangle in faces is a face: draw them!Rect[] facesArray = faces.toArray();for (int i = 0; i < facesArray.length; i++)Imgproc.rectangle(frame, facesArray[i].tl(), facesArray[i].br(), new Scalar(0, 255, 0), 3);}}
面板工具类VideoPanel.java
import java.awt.*;import java.awt.image.BufferedImage;import javax.swing.*;import org.opencv.core.Mat;public class VideoPanel extends JPanel {private BufferedImage image;public void setImageWithMat(Mat mat) {image = mat2BufferedImage.matToBufferedImage(mat);this.repaint();}@Override protected void paintComponent(Graphics g) {super.paintComponent(g);if (image != null) g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), this);}public static VideoPanel show(String title, int width, int height, int open) {JFrame frame = new JFrame(title);if(open==0) {frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);} else {frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);}frame.setSize(width, height);frame.setBounds(0, 0, width, height);VideoPanel videoPanel = new VideoPanel();videoPanel.setSize(width, height);frame.setContentPane(videoPanel);frame.setVisible(true);return videoPanel;}}
然后运行FaceDetection.java类就可以启动程序啦,效果图所示
然后突然想起来,还需要下载这个jar包,导入到工程里边
这次忘记上传了,这个百度一下就可以下载到。
openCV人脸识别的初步运用先写到这里,下次会把项目打包上传
-----------------------------------------------------------------------------------------------------------------------
-07-16 补充代码
有小伙伴反映有个地方不能运行,然后我发现有个工具类忘记贴了
mat2BufferedImage.java
import org.opencv.core.Mat;import java.awt.image.BufferedImage;public class mat2BufferedImage {public static BufferedImage matToBufferedImage(Mat matrix) {int cols = matrix.cols();int rows = matrix.rows();int elemSize = (int) matrix.elemSize();byte[] data = new byte[cols * rows * elemSize];int type;matrix.get(0, 0, data);switch (matrix.channels()) {case 1:type = BufferedImage.TYPE_BYTE_GRAY;break;case 3:type = BufferedImage.TYPE_3BYTE_BGR;// bgr to rgbbyte b;for (int i = 0; i < data.length; i = i + 3) {b = data[i];data[i] = data[i + 2];data[i + 2] = b;}break;default:return null;}BufferedImage image2 = new BufferedImage(cols, rows, type);image2.getRaster().setDataElements(0, 0, cols, rows, data);return image2;}}
相关博客:
java利用openCV进行人脸识别,采集照片和训练模型(二)