栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

OpenCV Java入门四 认出这是“一张脸”

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

OpenCV 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;
	}

	
	public ImageViewer(Mat image, String windowName) {
		frame = createJframe(windowName, 1024, 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

这个是主类。

老三样:

    加载opencv_java343.dll;加载人脸分拣器;创建Mat对象;

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

    使用detectMultiScale把传入的Mat对象中含有脸的那些全部识别出来;识别出来后我们可以使用for (Rect rect : objDetections.toArray())把所有的脸枚举出来;使用Imgproc.rectangle在每个识别出来的脸上用“绿”色把它们一个个框出来;使用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();

		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)蓝
		}
		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.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-demoface目录中得到5个写出的人脸的图片。

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/781191.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号