|
|
@@ -0,0 +1,106 @@
|
|
|
+package com.ktg.iscs.config;
|
|
|
+
|
|
|
+
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import com.ktg.iscs.domain.vo.cabinet.VerificationVO;
|
|
|
+import com.machinezoo.sourceafis.FingerprintImage;
|
|
|
+import com.machinezoo.sourceafis.FingerprintImageOptions;
|
|
|
+import com.machinezoo.sourceafis.FingerprintMatcher;
|
|
|
+import com.machinezoo.sourceafis.FingerprintTemplate;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
+import java.util.concurrent.ExecutorService;
|
|
|
+import java.util.concurrent.Executors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <p>
|
|
|
+ * FingerprintComparison<br>
|
|
|
+ * 指纹比对算法(图片)
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author CGJ
|
|
|
+ * @version 1.0
|
|
|
+ * @since 2025年03月07日 11:51
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+public class FingerprintComparisonByImg {
|
|
|
+
|
|
|
+ // 相似度门槛
|
|
|
+ private static final double THRESHOLD = 40; // 相当于错误率是0.01%,THRESHOLD越高,错误率越低
|
|
|
+ private static final ExecutorService THREAD_POOL_EXECUTOR = Executors.newFixedThreadPool(4); // 线程池
|
|
|
+
|
|
|
+ public static VerificationVO completableFutureComparison(final String inputImg, final Set<String> matcherImg) {
|
|
|
+ // 转成list
|
|
|
+ List<String> matcherImgList = new ArrayList<>(matcherImg);
|
|
|
+ // 切分四等份
|
|
|
+ List<List<String>> averageMatcherImgList = Lists.partition(matcherImgList, matcherImgList.size() / 4);
|
|
|
+ // 构建四个线程进行处理,防止人员过多对比速度太慢
|
|
|
+ CompletableFuture<VerificationVO>[] completableFutureArray = averageMatcherImgList.stream().map(
|
|
|
+ partitionFingerprint -> CompletableFuture.supplyAsync(
|
|
|
+ () -> comparison(inputImg, new ArrayList<>(partitionFingerprint)), THREAD_POOL_EXECUTOR)
|
|
|
+ ).toArray(CompletableFuture[]::new);
|
|
|
+ // 等待所有任务执行完
|
|
|
+ CompletableFuture.allOf(completableFutureArray).join();
|
|
|
+ List<VerificationVO> verificationList = new ArrayList<>();
|
|
|
+ for (CompletableFuture<VerificationVO> completableFuture : completableFutureArray) {
|
|
|
+ try {
|
|
|
+ VerificationVO verification = completableFuture.get();
|
|
|
+ if (ObjectUtil.isNotEmpty(verification)) {
|
|
|
+ verificationList.add(verification);
|
|
|
+ }
|
|
|
+ } catch (InterruptedException | ExecutionException e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 找出最匹配的指纹(匹配度最高)
|
|
|
+ if (ObjectUtil.isNotEmpty(verificationList)) {
|
|
|
+ VerificationVO max = verificationList.stream().max(Comparator.comparing(VerificationVO::getScore)).get();
|
|
|
+ log.info("相似值最佳的的指纹:{},分数{}", max.getFingerprintImg(), max.getScore());
|
|
|
+ return max;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static VerificationVO comparison(final String inputImg, final List<String> matcherImgList) {
|
|
|
+ try {
|
|
|
+ // 开始解析输入的指纹到指纹模板
|
|
|
+ byte[] bytes = Files.readAllBytes(Paths.get(inputImg));
|
|
|
+ FingerprintImageOptions dpi = new FingerprintImageOptions().dpi(500);
|
|
|
+ FingerprintImage fingerprintImage = new FingerprintImage(bytes, dpi);
|
|
|
+ FingerprintTemplate fingerprintTemplate = new FingerprintTemplate(fingerprintImage);
|
|
|
+
|
|
|
+ if (!matcherImgList.isEmpty()) {
|
|
|
+ // 输入的被验证指纹
|
|
|
+ FingerprintMatcher matcher = new FingerprintMatcher(fingerprintTemplate);
|
|
|
+ // 最匹配的指纹
|
|
|
+ String match = null;
|
|
|
+ // 峰值
|
|
|
+ double high = 0;
|
|
|
+ for (String matcherImg : matcherImgList) {
|
|
|
+ // 输入的指纹和指纹库中的指纹进行对比,找到当前线程中的分数最高的指纹
|
|
|
+ double score = matcher.match(new FingerprintTemplate(new FingerprintImage(Files.readAllBytes(Paths.get(matcherImg)), dpi)));
|
|
|
+ if (score > high) {
|
|
|
+ high = score;
|
|
|
+ match = matcherImg;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return high >= THRESHOLD ? new VerificationVO().setFingerprintImg(match).setScore(high) : null;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("指纹比对异常:{}", e.getMessage());
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|