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

与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 "人脸对比失败";
		}
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值