1、pom添加依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.coobird/thumbnailator -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
<dependency>
<groupId>opencv</groupId>
<artifactId>opencv</artifactId>
<version>4.1.0</version>
</dependency>
2、工具类
package com.ahies.stm.app.util;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.log.LogFactory;
import com.ahies.stm.app.synthesizes.sys.entity.FileUpload;
import net.coobird.thumbnailator.Thumbnails;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
/**
* @Description
* @Date 2019/12/10 19:10
* @Author zsj
*/
public class FaceCompareUtils {
// 初始化人脸探测器
public static CascadeClassifier faceDetector;
static {
String os = System.getProperty("os.name");
LogFactory.get().info(os);
String opencvDllName = "D:\\opencv_java410.dll";
String xmlPath = "d:\\haarcascade_frontalface_alt.xml";
//路径不能包含中文 linux使用libopencv_java410.so
if (!os.toLowerCase().startsWith("win")) {
opencvDllName = "/home/opencv/share/java/opencv4/libopencv_java410.so";
xmlPath = "/home/stm/jar/haarcascade_frontalface_alt.xml";
System.load(opencvDllName);
faceDetector = new CascadeClassifier(xmlPath);
} else {
System.load(opencvDllName);
// xml路径不能包含中文
faceDetector = new CascadeClassifier(xmlPath);
}
}
// 灰度化人脸
public static Mat conv_Mat(String img) {
Mat image0 = Imgcodecs.imread(img);
Mat image1 = new Mat();
// 灰度化
Imgproc.cvtColor(image0, image1, Imgproc.COLOR_BGR2GRAY);
// 探测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image1, faceDetections);
// rect中人脸图片的范围
for (Rect rect : faceDetections.toArray()) {
Mat face = new Mat(image1, rect);
return face;
}
return null;
}
public static double compare_image(String img_1, String img_2) {
Mat mat_1 = conv_Mat(img_1);
Mat mat_2 = conv_Mat(img_2);
Mat hist_1 = new Mat();
Mat hist_2 = new Mat();
//颜色范围
MatOfFloat ranges = new MatOfFloat(0f, 256f);
//直方图大小, 越大匹配越精确 (越慢)
MatOfInt histSize = new MatOfInt(10000000);
Imgproc.calcHist(Arrays.asList(mat_1), new MatOfInt(0), new Mat(), hist_1, histSize, ranges);
Imgproc.calcHist(Arrays.asList(mat_2), new MatOfInt(0), new Mat(), hist_2, histSize, ranges);
// CORREL 相关系数
double res = Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL);
return res;
}
/*
* @Description:
* @param uploadFolder 文件夹, multipartFileName 文件名, tempFile 包含人脸的文件
* @return com.ahies.stm.app.synthesizes.sys.entity.FileUpload
* @menu /
* @status done
*/
public static FileUpload cutFace(String uploadFolder, String multipartFileName, File tempFile) {
Mat image = Imgcodecs.imread(tempFile.getAbsolutePath());
MatOfRect faceDetections = new MatOfRect();
// 进行人脸检测
FaceCompareUtils.faceDetector.detectMultiScale(image, faceDetections);
Integer i = 1;
String cutImagePath = null;
int x = 0;
int y = 0;
int width = 0;
int height = 0;
// 制图将图填充到image中
if (faceDetections.toArray().length <= 0) {
LogFactory.get().info("没有检测到人脸");
return null;
} else if (faceDetections.toArray().length > 1) {
LogFactory.get().info("检测到多张人脸");
return null;
} else {
Rect rect = faceDetections.toArray()[0];
x = rect.x;
y = rect.y;
width = rect.width;
height = rect.height;
image.release();
faceDetections.release();
image = null;
faceDetections = null;
}
String location = uploadFolder + multipartFileName;
java.io.File outFile = new java.io.File(location);
String cutFileName = "cut" + multipartFileName;
String cutLocation = uploadFolder + cutFileName;
//图片裁剪
ImgUtil.cut(tempFile, outFile, new Rectangle(x, y, width, height));
// //把图片缩放至150kb左右
try {
Thumbnails.of(location)
.size(500, 500)
.outputQuality(1f)
.toFile(cutLocation);
} catch (IOException e) {
e.printStackTrace();
return null;
}finally {
System.gc();
}
FileUpload fileUpload = FileUpload.builder().name(cutFileName)
.location(cutLocation).build();
return fileUpload;
}
}
3、调用
@Override
public FileUpload saveFaceFile(MultipartFile multipartFile) throws IOException {
java.io.File tempFile = new java.io.File(uploadFolder + multipartFile.getOriginalFilename());
// 保存文件流到 tempFile
FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), tempFile);
// 读取创建的图片tempFile
FileUpload fileUpload = FaceCompareUtils.cutFace(uploadFolder, multipartFile.getOriginalFilename(), tempFile);
return fileUpload;
}