码上焚香

Yahocen

SourceAFIS for Java 指纹识别

29
2024-05-10

SourceAFIS for Java是SourceAFIS的纯Java端口,SourceAFIS是一种用于识别人类指纹的算法。它可以对两个指纹进行1:1的比对,或者在大型数据库1:N中搜索匹配的指纹。它在输入时获取指纹图像,在输出时生成相似度评分。然后将相似度评分与可自定义匹配阈值进行比较

比如制作考勤系统,通过指纹采集设备将指纹图片保存并与对应的用户姓名或其他唯一性标识关联

打卡时获取用户指纹,并且与之前采集的指纹列表进行比对,获取当前指纹的对象身份

保存用户指纹时最好生成指纹模板对象Base64字符串,这样比对时不使用指纹图片创建指纹模板可以大大节省比对消耗

Maven引入

<dependency>
    <groupId>com.machinezoo.sourceafis</groupId>
    <artifactId>sourceafis</artifactId>
    <version>3.8.1</version>
</dependency>

自定义比对类

//用户与指纹对象
import org.apache.commons.codec.binary.Base64;

import com.machinezoo.sourceafis.FingerprintImage;
import com.machinezoo.sourceafis.FingerprintTemplate;

public class UserDetails {

    public UserDetails(String name, String imgp) throws IOException {
        this.name = name;
        byte[] probeImage = Files.readAllBytes(Paths.get(imgp));
        this.ft = new FingerprintTemplate(new FingerprintImage().dpi(500).decode(probeImage));
        //将指纹转换成byte数组,并转成Base64字符串进行储存
        this.ftt = Base64.encodeBase64String(this.ft.toByteArray());
    }

    //人员姓名
    private String name;

    //指纹比对模板
    private FingerprintTemplate ft;

    //将指纹模板信息转成字符串格式,方便储存,但是原指纹图片也不能删除,因为版本不同,所生成的指纹字符串也不同
    private String ftt;

    public byte[] getFtt() {
        return Base64.decodeBase64(ftt);
    }

    /* 省略get/set */
}

一比一示例

//样本指纹
//此处可以改成使用用户指纹对象的ftt字段创建指纹模板效率会快很多
UserDetails probe = new UserDetails("用户1", "G:\\xxx\\1.png");
//比对指纹
UserDetails candidate = new UserDetails("用户1", "G:\\xxx\\11.png");
//获取二个指纹相似度
double score = new FingerprintMatcher().index(probe.getFt()).match(candidate.getFt());
//自定义一个阈值,越高越好,这里取值40
double threshold = 40;
//高于阈值确定为相等
boolean matches = score >= threshold;

System.out.println(score);
System.out.println(matches);

一比多示例

//创建用户指纹列表,指纹图片请在百度自行获取
public static List<UserDetails> zhiwens() {
    List<UserDetails> result = new ArrayList<>();
    File dir = new File(System.getProperty("user.dir") + File.separatorChar + "zhiwen");
    Arrays.asList(dir.list()).forEach(s -> {
        try {
            result.add(new UserDetails(s, dir.getPath() + File.separatorChar + s));
        } catch (IOException e) {
            e.printStackTrace();
        }
    });
    return result;
}

//使用样本指纹和用户指纹列表进行比较,获取第一个匹配到的指纹
private static UserDetails find(UserDetails probe, List<UserDetails> candidates) {
    FingerprintMatcher matcher = new FingerprintMatcher().index(probe.getFt());
    UserDetails match = null;
    double high = 0;
    for (UserDetails candidate : candidates) {
        double score = matcher.match(candidate.getFt());
        if (score > high) {
            high = score;
        match = candidate;
        }
    }
    double threshold = 40;
    return high >= threshold ? match : null;
}

//测试一比多
List<UserDetails> lud = Util.zhiwens();
UserDetails probe = lud.get(10);
System.out.println(probe.getName());
UserDetails ud = find(lud.get(10), lud);
System.out.println(ud.getName());