Java+OpenCV实现图片中的人脸识别

网友投稿 323 2022-08-17


Java+OpenCV实现图片中的人脸识别

目录MatOfRect.detectMultiScale函数实现代码ImageViewer.javaDetectFace.java运行把识别出来的脸存成文件

经过前三个教程,我们可以知道了OpenCV的基本使用了。

今天,我们就要讲OpenCV中认出,这是一个人脸是怎么做的。

MatOfRect.detectMultiScale函数

OpenCV用的是detectMultiScale来认出这是一个脸的。记得,这只是认出这是一个脸,而不是这个脸是谁。

这个脸是谁我们会逐步展开,前面勿求夯实基础。

detectMultiScale需要两个参数(Mat src, MatOfRect objDetections);

第一个函数,是传入的图片,带有人脸的图片;第二个函数,是把所有的这个图片里的人脸得到并输出到MatOfRect对象里;

比如说下面这个图片里,一共有5个脸,我们把脸一个个识别出来并在脸上用方框把它们标记出来。

然后用我们前面教程中提到的ImageViewer类来显示带有“标识”的人脸。

实现代码

ImageViewer.java

再上一遍

package org.mk.opencv;

import org.mk.opencv.util.OpenCVUtil;

import org.opencv.core.Mat;

import javax.swing.*;

import java.awt.*;

public class ImageViewer {

private JLabel imageView;

private Mat image;

private String windowName;

private JFrame frame = null;

public ImageViewer() {

frame = createJFrame(windowName, 800, 600);

}

public ImageViewer(Mat image) {

this.image = image;

}

/**

* @param image 要显示的mat

* @param windowName 窗口标题

*/

public ImageViewer(Mat image, String windowName) {

frame = createJFrame(windowName, 10http://24, 768);

this.image = image;

this.windowName = windowName;

}

public void setTitle(String windowName) {

this.windowName = windowName;

}

public void setImage(Mat image) {

this.image = image;

}

/**

* 图片显示

*/

public void imshow() {

setSystemLookAndFeel();

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 用户点击窗口关闭

if (image != null) {

Image loadedImage = OpenCVUtil.matToImage(image);

// JFrame frame = createJFrame(windowName, image.width(), image.height());

imageView.setIcon(new ImageIcon(loadedImage));

frame.pack();

// frame.setLocationRelativeTo(null);

// frame.setVisible(true);

// frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 用户点击窗口关闭

}

}

private void setSystemLookAndFeel() {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (UnsupportedLookAndFeelException e) {

e.printStackTrace();

}

}

private JFrame createJFrame(String windowName, int width, int height) {

JFrame frame = new JFrame(windowName);

imageView = new JLabel();

final jscrollPane imageScrollPane = new JScrollPane(imageView);

imageScrollPane.setPreferredSize(new Dimension(width, height));

frame.add(imageScrollPane, BorderLayout.CENTER);

frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

return frame;

}

}

DetectFace.java

这个是主类。

老三样:

1.加载opencv_java343.dll;

2.加载人脸分拣器;

3.创建Mat对象;

然后我们开始把脸识别出来:

1.使用detectMultiScale把传入的Mat对象中含有脸的那些全部识别出来;

2.识别出来后我们可以使用for (Rect rect : objDetections.toArray())把所有的脸枚举出来;

3.使用Imgproc.rectangle在每个识别出来的脸上用“绿”色把它们一个个框出来;

4.使用ImageViewer的.imgShow显示标识出来的脸;

package org.mk.opencv;

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;

public class DetectFace {

public static void main(String[] args) {

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

//Mat src = Imgcodecs.imread("/Users/chrishu123126.com/opt/img/detect-face-4.jpg");

Mat src = Imgcodecs.imread("D:\\opencv-demo\\green-arrow.jpg");

if (src.empty()) {

System.out.println("图片路径不正确");

return;

}

Mat dst = dobj(src);

ImageViewer imageViewer = new ImageViewer(dst, "识脸");

imageViewer.imshow();

}

private static Mat dobj(Mat src) {

Mat dst = src.clone();

CascadeChttp://lassifier objDetector = new CascadeClassifier(

"D:\\opencvinstall\\build\\install\\etc\\lbpcascades\\lbpcascade_frontalface.xml");

MatOfRect objDetections = new MatOfRect();

objDetector.detectMultiScale(dst, objDetections);

if (objDetections.toArray().length <= 0) {

return src;

}

for (Rect rect : objDetections.toArray()) {

Imgproc.rectangle(dst, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.width),

new Scalar(0, 255, 0), 1); //new Scalar(0, 255, 0), 1)绿 //new Scalar(0, 0, 255), 1)红 //new Scalar(255, 0, 0), 1)蓝

}

return dst;

}

}

运行

运行效果如下

把识别出来的脸存成文件

我们现在把识别出来的5张脸存成5个jpg图片。

制作一个写盘函数,很简单。

private static void outputFace(String outputDir, Mat face) {

long millSecs = System.currentTimeMillis();

int temp = (int) (Math.random() * 10000);

StringBuffer outputImgName = new StringBuffer();

outputImgName.append(outputDir).append("/").append(millSecs).append(temp).append(".jpg");

if (face != null) {

Imgcodecs.imwrite(outputImgName.toString(), face);

logger.info(">>>>>>write image into->" + outputDir);

}

}

然后我们在我们的原来的代码中加入这个函数

package org.mk.opencv;

import org.http://apache.log4j.Logger;

import org.mk.opencv.face.FaceRecogFromFiles;

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;

public class DetectFace {

private static Logger logger = Logger.getLogger(DetectFace.class);

private final static String faceOutPutDir = "d://opencv-demo/face";

public static void main(String[] args) {

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

// Mat src =

// Imgcodecs.imread("/Users/chrishu123126.com/opt/img/detect-face-4.jpg");

Mat src = Imgcodecs.imread("D:\\opencv-demo\\green-arrow.jpg");

if (src.empty()) {

System.out.println("图片路径不正确");

return;

}

Mat dst = dobj(src);

ImageViewer imageViewer = new ImageViewer(dst, "识脸");

imageViewer.imshow();

}

private static Mat dobj(Mat src) {

Mat dst = src.clone();

CascadeClassifier objDetector = new CascadeClassifier(

"D:\\opencvinstall\\build\\install\\etc\\lbpcascades\\lbpcascade_frontalface.xml");

MatOfRect objDetections = new MatOfRect();

objDetector.detectMultiScale(dst, objDetections);

if (objDetections.toArray().length <= 0) {

return src;

}

for (Rect rect : objDetections.toArray()) {

Imgproc.rectangle(dst, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.width),

new Scalar(0, 255, 0), 1); // new Scalar(0, 255, 0), 1)绿 //new Scalar(0, 0, 255), 1)红 //new

// Scalar(255, 0, 0), 1)蓝

outputFace(faceOutPutDir, src.submat(rect));

}

return dst;

}

private static void outputFace(String outputDir, Mat face) {

long millSecs = System.currentTimeMillis();

int temp = (int) (Math.random() * 10000);

StringBuffer outputImgName = new StringBuffer();

outputImgName.append(outputDir).append("/").append(millSecs).append(temp).append(".jpg");

if (face != null) {

Imgcodecs.imwrite(outputImgName.toString(), face);

logger.info(">>>>>>write image into->" + outputDir);

}

}

}

运行DetectFace.java,我们可以在D:\opencv-demo\face目录中得到5个写出的人脸的图片。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Netty分布式pipeline管道Handler的添加代码跟踪解析
下一篇:Netty分布式pipeline管道创建方法跟踪解析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~