与SpringmvcSpring+OpenCV+Linux(libopencv_java460.so、opencv-460.jar)人脸识别、人脸对比实现_殷长庆的博客-CSDN博客
方式区别在于springboot是jar包方式启动的,
jar\so\xml文件下载OpenCV+Linux(libopencv_java460.so、opencv-460.jar)-Java文档类资源-CSDN下载
opencv load无法读取jar包中的so文件,
解决方案
1、在Linux某文件夹下提前预置so和xml这俩文件
2、springboot启动时候从jar包读取这两个文件生成到某文件夹下,在用load读取
第二种方案实现
在项目根目录下创建lib文件夹,把jar放进去
Maven
<dependency>
<groupId>com.opencv</groupId>
<artifactId>opencv_java460</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${basedir}/lib/opencv-460.jar</systemPath>
</dependency>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includeSystemScope>true</includeSystemScope>
<mainClass>com.opencv.MainApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
在src/main/resources下创建opencv文件夹,把so、xml文件放进去
Java实现
启动时会在Linux中创建/opencv文件夹,并把so、xml文件创建到文件夹下,再次启动时会先检查文件是否存在,存在则直接load
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import javax.annotation.PostConstruct;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 人脸对比处理
*/
@Controller
public class FaceDetectorController {
private CascadeClassifier faceDetector;
@PostConstruct
private void init() {
try {
String openCVDiv = "/opencv/";
String openCVSo = openCVDiv + "libopencv_java460.so";
String openCVXml = openCVDiv + "lbpcascade_frontalface.xml";
File fileso = new File(openCVSo);
if (null == fileso || !fileso.exists()) {
File fileDiv = new File(openCVDiv);
fileDiv.mkdirs();
ClassPathResource cpr = new ClassPathResource(openCVSo);
InputStream cprIn = cpr.getInputStream();
copyFile(cprIn, fileso);
ClassPathResource cprxml = new ClassPathResource(openCVXml);
InputStream xmlIn = cprxml.getInputStream();
File filexml = new File(openCVXml);
copyFile(xmlIn, filexml);
}
System.load(openCVSo);
faceDetector = new CascadeClassifier(openCVXml);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 复制文件
* @param input 源文件流
* @param targetFile 目标文件
*/
private void copyFile(InputStream input, File targetFile) throws Exception {
BufferedInputStream inBuff = new BufferedInputStream(input);
FileOutputStream output = new FileOutputStream(targetFile);
BufferedOutputStream outBuff = new BufferedOutputStream(output);
byte[] b = new byte[1024 * 5];
int len;
while ((len = inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
outBuff.flush();
inBuff.close();
outBuff.close();
output.close();
input.close();
}
// 灰度化人脸
private 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;
}
private 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 相关系数
return Imgproc.compareHist(hist_1, hist_2, Imgproc.CV_COMP_CORREL);
}
/**
* 人脸对比
* @return
*/
@RequestMapping("faceDetector")
@ResponseBody
public String faceDetector() {
try {
//图片路径不能包含中文
double compareHist = compare_image("/home/opencv/1.jpg", "/home/opencv/2.jpg");
if (compareHist > 0.6) {
return "人脸对比成功";
} else {
return "人脸不匹配";
}
} catch (Exception e) {
return "人脸对比失败";
}
}
}