由于公司的项目赶在 “某某打车” 事件期间,所以你懂得。老板说要个信用安全、和人身安全等等,后来寻思了一下,还是老板说的对,毕竟给钱了。
老板说完我就想到了芝麻信用,还有下面几个。
芝麻信用
身份证人证
人脸识别
人证对比
接下来就是一些冤枉路。
呐,阿里云官网
https://www.aliyun.com/?utm_content=se_1000301881
注册绑定身份证,在阿里云上找了个身份证验证的api,卧槽,因为是第一次搞,整了半天终于测通了,心理美滋滋,大喊一声舒服。
还没嘚瑟三秒,发现这个api好像没有图片扫描的接口,也就是说,身份证号、姓名和身份证到期日期全靠手动输入。
嗯…en…
这怕是个智障吧。
和产品硬着头皮讨论了半天,最终也没说服他…恨己无有三寸不烂之舌啊。
所以只能换个api
对阿里云也算是很钟情的
所以就又在这个上面找了个很牛逼的、很贵的、可以扫面图片的(身份证)的api,整了两小时,这下应该可以秀一下了。
这个写好了,就先放着了,毕竟仅仅一个身份证有点扯
整好了身份证验证,再来一个芝麻认证吧。
从在蚂蚁金服上注册用户到申请企业账号、企业认证整了两三才才通过审核。当然这个是产品经理的活。。。。
三天后账号终于到我手上了,但是芝麻认证需要申请授权,这个申请了四次都打回来了。
最后当然还是通过审核了。
但是芝麻认证把芝麻分砍掉了,就是不再提供芝麻分的接口了。
然后芝麻认证的人脸识别不能在自己的app的进行认证,必须跳转到支付宝进行认证,这就很扯了。。。。
当然这个我也都接好了,实现了。。。实现了。。。实现了、。。。。。打扰了
https://b.xin.xin/ant/index.htm 官网
这个时候突然看到,百度ai。。。。。有个全套的认证流程api,卧槽…
那岂不是,之前写的要全删? 嗯么。。。全删了
先说一下百度Face这一套吧。
百度云官网
https://cloud.baidu.com/
http://ai.baidu.com/docs#/OCR-Android-SDK/f01bf7e2
嗯嗯…这个sdk 接入的方法,上面的连接都有,按照官网接入就行
直接上调用的代码。
/**
* idCardSide 身份证正反面识别码 正面:IDCardParams.ID_CARD_SIDE_FRONT 反面:IDCardParams.ID_CARD_SIDE_BACK
* filePath 图片地址
*
*
*/
private void recIDCard(String idCardSide, String filePath) {
IDCardParams param = new IDCardParams();
param.setImageFile(new File(filePath));
// 设置身份证正反面
param.setIdCardSide(idCardSide);
// 设置方向检测
param.setDetectDirection(true);
// 设置图像参数压缩质量0-100, 越大图像质量越好但是请求时间越长。 不设置则默认值为20
param.setImageQuality(30);
OCR.getInstance(getContext()).recognizeIDCard(param, new OnResultListener<IDCardResult>() {
@Override
public void onResult(IDCardResult result) {
if (result != null) {
if (idCardSide.equals(IDCardParams.ID_CARD_SIDE_FRONT)) {
if ((result.getDirection() + "").equals("0") && (result.getWordsResultNumber() + "").equals("6")
&& !"".equals(result.getAddress()) && !"".equals(result.getBirthday()) && !"".equals(result.getName())
&& !"".equals(result.getGender()) && !"".equals(result.getEthnic())) {
tv_id.setText("" + result.getIdNumber());//身份证号
tv_name.setText("" + result.getName());//姓名
Log.e("TAG",result.toString()+"");
// upImgData(filePath,idCardSide);
} else {
Log,e("TAG", "图片扫描失败,请重新上传");
}
} else if (idCardSide.equals(IDCardParams.ID_CARD_SIDE_BACK)) {
if (!"".equals(result.getSignDate()) && !"".equals(result.getExpiryDate()) && !"".equals(result.getIssueAuthority())) {
// 身份证背面返回值
Log.e("ddddddddddddd",result.toString()+"");
} else {
alertText("", "图片扫描失败,请重新上传");
}
}
}
}
@Override
public void onError(OCRError error) {
alertText("", error.getMessage());
}
});
}
http://ai.baidu.com/docs#/FaceSDK-Collect-WithLiveness-Android/top
上面是人脸采集的sdk接入方式,按照官网上的接入就行
将身份证扫描得到的信息保存起来,或者直接上传到后台,留着稍后用。。。。
/**
*@auther Fsnzzz
*@date 2018.11.1
*/
public class FaceLivenessExpActivity extends FaceLivenessActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在线活体检测和公安核实需要使用该token,为了防止ak、sk泄露,建议在线活体检测和公安接口在您的服务端请求
initAccessToken();
}
@Override
public void onCreateView(ViewGroup viewGroup) {
setContentView(R.layout.activity_main);
// 根据需求添加活体动作
ExampleApplication.livenessList.clear();
ExampleApplication.livenessList.add(LivenessTypeEnum.Eye);
ExampleApplication.livenessList.add(LivenessTypeEnum.Mouth);
ExampleApplication.livenessList.add(LivenessTypeEnum.HeadUp);
ExampleApplication.livenessList.add(LivenessTypeEnum.HeadDown);
ExampleApplication.livenessList.add(LivenessTypeEnum.HeadLeft);
ExampleApplication.livenessList.add(LivenessTypeEnum.HeadRight);
ExampleApplication.livenessList.add(LivenessTypeEnum.HeadLeftOrRight);
//初始化SDK
initLib();
}
/**
* 初始化SDK
*/
private void initLib() {
// 为了android和ios 区分授权,appId=appname_face_android ,其中appname为申请sdk时的应用名
// 应用上下文
// 申请License取得的APPID
// assets目录下License文件名
FaceSDKManager.getInstance().initialize(getContext(), Config.licenseID, Config.licenseFileName);
// setFaceConfig();
}
public class Config {
// 为了apiKey,secretKey为您调用百度人脸在线接口的,如注册,比对等。
// 为了的安全,建议放在您的服务端,端把人脸传给服务器,在服务端端
// license为调用sdk的人脸检测功能使用,人脸识别 = 人脸检测(sdk功能) + 人脸比对(服务端api)
public static String apiKey = "***********";
public static String secretKey = "*************";
public static String licenseID = "***********";
public static String licenseFileName = "idl-license.face-android";
}
// 在线活体检测和公安核实需要使用该token,为了防止ak、sk泄露,建议在线活体检测和公安接口在您的服务端请求
private void initAccessToken() {
APIService.getInstance().init(getApplicationContext());
APIService.getInstance().initAccessTokenWithAkSk(new OnResultListener<AccessToken>() {
@Override
public void onResult(AccessToken result) {
if (result != null && !TextUtils.isEmpty(result.getAccessToken())) {
waitAccesstoken = false;
accessToken = result.getAccessToken().toString();
policeVerify(filePath);
} else if (result != null) {
Log.e("GAT", "在线活体token获取失败");
} else {
Log.e("GAT", "在线活体token获取失败");
}
}
/**
*人脸采集后的返回值
*
*/
@Override
public void onLivenessCompletion(FaceStatusEnum status, String message, HashMap<String, String> base64ImageMap) {
super.onLivenessCompletion(status, message, base64ImageMap);
if (status == FaceStatusEnum.OK && mIsCompletion) {
showMessageDialog("活体检测", "检测成功");//自己的dialog
saveImage(base64ImageMap);// 调用保存img方法,在下面
} else if (status == FaceStatusEnum.Error_DetectTimeout ||
status == FaceStatusEnum.Error_LivenessTimeout ||
status == FaceStatusEnum.Error_Timeout) {
showMessageDialog("活体检测", "采集超时");
}
}
}
private void saveImage(HashMap<String, String> imageMap) {
// imageMap 里保存了最佳人脸和各个动作的图片,若对安全要求比较高,可以传多张图片进行在线活体,目前只用最佳人脸进行了在线活体检测
String bestimageBase64 = imageMap.get("bestImage0");
Bitmap bmp = base64ToBitmap(bestimageBase64);
try {
File file = File.createTempFile("face", ".jpg");
FileOutputStream outputStream = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);
outputStream.close();
filePath = file.getAbsolutePath();
Log.e("GAT", filePath + "");
//公安验证
policeVerify(filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
上面两部得到了身份证的相关信息和采集到本人的照片
接下来调用公安认证api
/**
* 公安接口合并在线活体,调用公安验证接口进行最后的核身比对;公安权限需要在官网控制台提交工单开启
* 接口地址:https://aip.baidubce.com/rest/2.0/face/v2/person/verify
* 入参为「姓名」「身份证号」「bestimage」
* ext_fields 扩展功能。如 faceliveness 表示返回活体值, qualities 表示返回质检测结果
* quality string 判断质 是否达标。“use” 表示做质 控制,质 好的照 会 直接拒绝
* faceliveness string 判断活体值是否达标。 use 表示做活体控制,低于活体阈值的 照 会直接拒绝
* quality_conf和faceliveness_conf 用于指定阈值,超过此分数才调用公安验证,
*
* @param filePath 采集到的人脸图片
*/
private void policeVerify(String filePath) {
if (TextUtils.isEmpty(filePath) || waitAccesstoken) {
return;
}
File file = new File(filePath);
if (!file.exists()) {
return;
}
Log.e("GAT", "公安身份核实中...");
APIService.getInstance().policeVerify("姓名", "412326199254144542X", filePath, new
OnResultListener<LivenessVsIdcardResult>() {
@Override
public void onResult(LivenessVsIdcardResult result) {
if (result != null && result.getScore() >= 80) {
Log.e("GAT", "核身成功...");
// delete();
Log.e("GAT", filePath + "");
} else {
Log.e("GAT", "核身失败...");
Log.e("GAT", "公安验证分数过低..." + result.getScore());
}
}
@Override
public void onError(FaceException error) {
delete();
// TODO 错误处理
// 如返回错误码为:216600,则核身失败,提示信息为:身份证号码错误
// 如返回错误码为:216601,则核身失败,提示信息为:身份证号码与姓名不匹配
Log.e("GAT", "公安身份核实失败" + error.getMessage() + "");
}
}
);
}
以上就是人脸识别的核心代码。sdk接入文档官方就很详细了