准备工作
Linux生成libopencv_java460.so\opencv-460.jar\lbpcascade_frontalface.xml文件
opencv源码地址:https://github.com/opencv/opencv
下载4.6.0版本:Releases · opencv/opencv · GitHub
从git上找到对应版本号下载zip文件
?上传到Linux中并解压
unzip opencv-4.6.0.zip
mv opencv-4.6.0 /cloud/
cd /cloud/opencv-4.6.0/
mkdir build && cd build
接下来就是需要编译源码,这时候需要cmake命令,如果Linux自带的cmake版本低不好使或者是本机并没有装cmake那需要提前准备一下
wget https://cmake.org/files/v3.9/cmake-3.9.2.tar.gz
tar zxvf cmake-3.9.2.tar.gz
mv cmake-3.9.2 /cloud/
cd /cloud/cmake-3.9.2/
./configure
make
make install
cmake -version
# 检查一下版本,如果报错,可能是本机原来的cmake还有缓存,没替换过来需要执行以下 hash -r命令
# hash -r
# 这时候如果显示版本号为3.9.2就对了
cmake执行编译源码过程中会用到java环境和ant,没有的话也需要提前准备
yum -y install ant
ant -version
接下来编译源码
cd /cloud/opencv-4.6.0/build
cmake -D BUILD_SHARED_LIBS=OFF -D BUILD_TEST=OFF ..
?出现下面的ant: /bin/ant (ver 1.9.4)和java的信息说明命令执行成功过
-- Java:
-- ant: /bin/ant (ver 1.9.4)
-- JNI: /usr/java/jdk1.8.0_121/include /usr/java/jdk1.8.0_121/include/linux /usr/java/jdk1.8.0_121/include
-- Java wrappers: YES
-- Java tests: YES
--
-- Install to: /usr/local
-- -----------------------------------------------------------------
--
接下来执行make命令,执行完成后会出现对应的so包和jar包
# 8核cpu 就写 j8
make -j8 & make
生成的libopencv_java460.so包位置
cd /cloud/opencv-4.6.0/build/lib
生成的opencv-460.jar包位置
cd /cloud/opencv-4.6.0/build/bin
生成的lbpcascade_frontalface.xml文件位置
cd /cloud/opencv-4.6.0/build/java_test/res/raw
准备工作完成
spring集成
把上一步的三个文件放到项目中,
因为我是maven管理的多模块项目,
人脸识别模块
在人脸识别模块添加jar包,把jar放到
人脸识别模块/src/main/resources/lib下
如果没有lib那就新建一个lib文件夹
pom引入jar依赖
<dependency>
<groupId>com.opencv</groupId>
<artifactId>opencv_java460</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/opencv-460.jar</systemPath>
</dependency>
在build 的resources下忽略掉这个包,因为在war项目包中会引用,人脸识别模块就不要引用了
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<excludes>
<exclude>lib/*.jar</exclude>
</excludes>
</resource>
Java代码
import java.util.Arrays;
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.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 人脸对比处理
*/
@Controller
public class FaceDetectorController {
// 初始化人脸探测器
static CascadeClassifier faceDetector;
static {
boolean isWin = false;
if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
isWin = true;
}
if (!isWin) {
//路径不能包含中文 linux使用libopencv_java410.so
String opencvDllName = null;
try {
opencvDllName = FaceDetectorController.class.getResource("/opencv/libopencv_java460.so").toURI().getRawPath();
} catch (Exception e) {
e.printStackTrace();
}
System.load(opencvDllName);
// xml路径不能包含中文
String faceXml = null;
try {
faceXml = FaceDetectorController.class.getResource("/opencv/lbpcascade_frontalface.xml").toURI().getRawPath();
} catch (Exception e) {
e.printStackTrace();
}
faceDetector = new CascadeClassifier(faceXml);
}
}
// 灰度化人脸
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("1.jpg", "2.jpg");
if (compareHist > 0.6) {
return "人脸对比成功";
} else {
return "人脸不匹配";
}
} catch (Exception e) {
return "人脸对比失败";
}
}
}
war模块
在war模块的resources下新建opencv文件夹并把so文件和xml文件放进去
plugin修改
<!--使用maven-war-plugin插件在编译时指定第三方jar包目录并引入-->
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<webResources>
<resource>
<!-- 引入人脸识别模块的jar -->
<directory>../face-service/src/main/resources/lib/</directory>
<targetPath>WEB-INF/lib</targetPath>
<includes>
<include>**/*.jar</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
resource修改,避免maven打包对so文件的修改,需要配两个resources,分别配置filtering
<resource>
<directory>src/main/${package.environment}</directory>
<includes>
<include>**/*.*</include>
</includes>
<targetPath>${project.basedir}/target/classes</targetPath>
<filtering>true</filtering>
<excludes>
<exclude>opencv/*.*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/${package.environment}</directory>
<includes>
<include>opencv/*.*</include>
</includes>
<targetPath>${project.basedir}/target/classes</targetPath>
<filtering>false</filtering>
</resource>
|