SpringBoot实现扫码登录的示例代码
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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~