Spring+OpenCV+Linux(libopencv_java460.so、opencv-460.jar)人脸识别、人脸对比实现

准备工作

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文件

Spring+OpenCV+Linux(libopencv_java460.so、opencv-460.jar)人脸识别、人脸对比实现_第1张图片

 上传到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依赖


    com.opencv
    opencv_java460
    1
    system
    ${basedir}/src/main/resources/lib/opencv-460.jar

在build 的resources下忽略掉这个包,因为在war项目包中会引用,人脸识别模块就不要引用了

    
    src/main/resources
    
        **/*.*
    
    
        lib/*.jar
    

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
    3.2.0
    
        
            
                
                ../face-service/src/main/resources/lib/
                WEB-INF/lib
                
                    **/*.jar
                
            
        
    

resource修改,避免maven打包对so文件的修改,需要配两个resources,分别配置filtering


    src/main/${package.environment}
    
        **/*.*
    
    ${project.basedir}/target/classes
    true
    
        opencv/*.*
    


    src/main/${package.environment}
    
        opencv/*.*
    
    ${project.basedir}/target/classes
    false

你可能感兴趣的:(opencv,计算机视觉,人工智能)