上个月做实名认证,用户上传身份证照片,后端得自动读出姓名和号码。第一版直接丢给接口识别,结果一半的图返回失败,要么说没检测到身份证,要么号码少一位,投诉一堆。

身份证识别的难点不在模型,在图片本身。用户拍的角度歪、反光、手指挡边、背景杂乱,都会让识别率掉下来。所以第一步不是调接口,是把图处理干净。

上传前先卡一道:正反面分清楚

身份证有正面人像面和反面国徽面,字段不一样,正面的号别当反面读。前端最好让用户分两次传,标明正面和反面,别指望后端猜。接口一般会返回检测到的人脸位置,拿不到就说明拿反了或者没拍全。

预处理能做不少事。压缩到长边一千六百像素左右,太大上传慢,太小字看不清。然后用接口自带的清晰度检测,模糊的直接让用户重拍,比后面人工核对省事。

字段校验:号码能自证真假

  • 位数校验:二代证是18位,前17位数字加末位数字或X
  • 校验码:用加权因子算出第18位,算错说明识别有误
  • 出生日期:从第7位起取8位,转成日期再判是否合法
  • 敏感处理:传第三方前先脱敏,日志里别打印完整号码
请求示例 action=idcard side=front image=base64路径 返回字段 name,id_number,address,birth

校验码这一招特别管用。模型把8看成0、把1看成7,肉眼看不出来,但校验码一算就露馅。算出不符就标成待人工复核,别直接入库。地址字段常有换行和空格,入库前统一去掉,姓名里夹的奇怪空白也清理下。

取舍很清楚。要求高、量大就自己训模型或买带活体检测的接口,安全但贵。量小走按次计费的云接口最划算,配上前端重拍提示,识别率够用。号码一定要本地校一遍,别全信接口返回值。