parent
6fd52609e9
commit
2b15d49b5c
212
票据理赔自动化/main.py
212
票据理赔自动化/main.py
|
|
@ -14,7 +14,7 @@ from datetime import datetime
|
|||
from decimal import Decimal, ROUND_HALF_UP
|
||||
from hashlib import md5
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional, Tuple
|
||||
from typing import Optional, Tuple
|
||||
|
||||
import cv2
|
||||
import numpy
|
||||
|
|
@ -28,66 +28,6 @@ from utils.client import Authenticator, HTTPClient
|
|||
# from utils.ocr import fuzzy_match
|
||||
|
||||
|
||||
def idcard_extraction(**kwargs) -> dict | None:
|
||||
"""居民身份证数据提取"""
|
||||
|
||||
# 影像件全局唯一标识:优先使用关键词变量,其次使用全局变量,再次使用随机唯一标识
|
||||
image_guid = kwargs.get(
|
||||
"image_guid", globals().get("image_guid", uuid.uuid4().hex.upper())
|
||||
)
|
||||
|
||||
# 影像件格式
|
||||
image_format = kwargs.get("image_format", globals()["image_format"])
|
||||
if image_format is None:
|
||||
return None
|
||||
|
||||
# 影像件BASE64编码
|
||||
image_base64 = kwargs.get("image_base64", globals()["image_base64"])
|
||||
if image_base64 is None:
|
||||
return None
|
||||
|
||||
# 请求深圳快瞳居民身份证识别接口
|
||||
response = globals()["http_client"].post(
|
||||
url=(url := "https://ai.inspirvision.cn/s/api/ocr/identityCard"),
|
||||
headers={"X-RequestId-Header": image_guid},
|
||||
data={
|
||||
"token": globals()["authenticator"].get_token(
|
||||
servicer="szkt"
|
||||
), # 使用全局变量
|
||||
"imgBase64": f"data:image/{image_format};base64,{image_base64}",
|
||||
}, # 支持同时识别居民身份证正反面
|
||||
guid=hashlib.md5((url + image_guid).encode("utf-8")).hexdigest().upper(),
|
||||
)
|
||||
|
||||
# 若响应非成功,则返回NONE
|
||||
if not (response.get("status") == 200 and response.get("code") == 0):
|
||||
return None
|
||||
|
||||
extraction = {
|
||||
"姓名": response["data"]["name"],
|
||||
"性别": response["data"]["sex"],
|
||||
"民族": response["data"]["nation"],
|
||||
"出生": response["data"][
|
||||
"birthday"
|
||||
], # 深圳快瞳居民身份证出生日期格式为%Y-%m-%d
|
||||
"住址": response["data"]["address"],
|
||||
"公民身份号码": response["data"]["idNo"],
|
||||
"签发机关": response["data"]["issuedBy"],
|
||||
"有效期起": parse(
|
||||
(date := response["data"]["validDate"]).split("-")[0]
|
||||
).strftime(
|
||||
"%Y-%m-%d"
|
||||
), # 深圳快瞳居民身份证识别中有效期日期格式为%Y.%m.%d,转为%Y-%m-%d
|
||||
"有效期止": (
|
||||
date
|
||||
if (date := date.split("-")[1]) == "长期"
|
||||
else parse(date).strftime("%Y-%m-%d")
|
||||
),
|
||||
}
|
||||
|
||||
return extraction
|
||||
|
||||
|
||||
def bankcard_extraction(**kwargs) -> dict | None:
|
||||
"""银行卡数据提取"""
|
||||
|
||||
|
|
@ -1195,14 +1135,112 @@ if __name__ == "__main__":
|
|||
return image_base64, image_type, image_orientation
|
||||
|
||||
# noinspection PyShadowingNames
|
||||
def image_recognize(image_base64, image_type) -> Optional[Dict]:
|
||||
def image_recognize(image_guid, image_format, image_base64, image_type) -> None:
|
||||
"""
|
||||
影像件分类并旋正
|
||||
影像件识别并整合至赔案档案
|
||||
:param image_guid: 影像件唯一标识
|
||||
:param image_format: 影像件格式
|
||||
:param image_base64: 影像件BASE64编码
|
||||
:param image_type: 影像件类型
|
||||
:return: 影像件识别内容
|
||||
:return: 空
|
||||
"""
|
||||
|
||||
# noinspection PyShadowingNames
|
||||
def idcard_recognize(
|
||||
image_guid, image_format, image_base64, image_type
|
||||
) -> None:
|
||||
"""
|
||||
居民身份证别并整合至赔案档案
|
||||
:param image_guid: 影像件唯一标识
|
||||
:param image_format: 影像件格式
|
||||
:param image_base64: 影像件BASE64编码
|
||||
:param image_type: 影像件类型
|
||||
:return: 空
|
||||
"""
|
||||
# 请求深圳快瞳居民身份证识别接口
|
||||
response = http_client.post(
|
||||
url=(url := "https://ai.inspirvision.cn/s/api/ocr/identityCard"),
|
||||
headers={
|
||||
"X-RequestId-Header": image_guid
|
||||
}, # 以影像件唯一标识作为请求唯一标识,用于双方联查
|
||||
data={
|
||||
"token": authenticator.get_token(
|
||||
servicer="szkt"
|
||||
), # 获取深圳快瞳访问令牌
|
||||
"imgBase64": f"data:image/{image_format.lstrip(".")};base64,{image_base64}",
|
||||
}, # 支持同时识别居民身份证正反面
|
||||
guid=md5((url + image_guid).encode("utf-8")).hexdigest().upper(),
|
||||
)
|
||||
# 若响应非成功则抛出异常
|
||||
# TODO: 若响应非成功则流转至人工处理
|
||||
if not (response.get("status") == 200 and response.get("code") == 0):
|
||||
raise RuntimeError("请求深圳快瞳居民身份证识别接口发生异常")
|
||||
|
||||
if image_type in ["居民身份证(正背面)", "居民身份证(正面)"]:
|
||||
dossier["赔案层"]["申请人信息"].update(
|
||||
{
|
||||
"证件有效期起": datetime.strptime(
|
||||
extraction["有效期起"], "%Y-%m-%d"
|
||||
),
|
||||
"证件有效期止": (
|
||||
date
|
||||
if (date := extraction["有效期止"]) == "长期"
|
||||
else datetime.strptime(date, "%Y-%m-%d")
|
||||
), # 若证件有效期止为NONE默认为“长期”,
|
||||
}
|
||||
) # 原则上由影像件数据提取环节负责数据标准化,赔案档案数据填充环节负责数据机构化
|
||||
|
||||
if image_type in ["居民身份证(正背面)", "居民身份证(背面)"]:
|
||||
dossier["赔案层"]["申请人信息"].update(
|
||||
{
|
||||
"姓名": extraction["姓名"],
|
||||
"证件类型": "居民身份证",
|
||||
"证件号码": extraction["公民身份号码"],
|
||||
"性别": extraction["性别"],
|
||||
"出生": datetime.strptime(
|
||||
extraction["出生"], "%Y-%m-%d"
|
||||
), # 默认日期格式为%Y-%m-%d
|
||||
"省": (address := parse_location(extraction["住址"])).get(
|
||||
"province"
|
||||
),
|
||||
"地": address.get("city"),
|
||||
"县": address.get("county"),
|
||||
"详细地址": address.get("detail"),
|
||||
}
|
||||
)
|
||||
|
||||
extraction = {
|
||||
"姓名": response["data"]["name"],
|
||||
"性别": response["data"]["sex"],
|
||||
"民族": response["data"]["nation"],
|
||||
"出生": response["data"][
|
||||
"birthday"
|
||||
], # 深圳快瞳居民身份证出生日期格式为%Y-%m-%d
|
||||
"住址": response["data"]["address"],
|
||||
"公民身份号码": response["data"]["idNo"],
|
||||
"签发机关": response["data"]["issuedBy"],
|
||||
"有效期起": parse(
|
||||
(date := response["data"]["validDate"]).split("-")[0]
|
||||
).strftime(
|
||||
"%Y-%m-%d"
|
||||
), # 深圳快瞳居民身份证识别中有效期日期格式为%Y.%m.%d,转为%Y-%m-%d
|
||||
"有效期止": (
|
||||
date
|
||||
if (date := date.split("-")[1]) == "长期"
|
||||
else parse(date).strftime("%Y-%m-%d")
|
||||
),
|
||||
}
|
||||
|
||||
# 根据影像件类型匹配影像件识别方法
|
||||
match image_type:
|
||||
# TODO: 后续添加居民户口簿识别和整合方法
|
||||
case "居民户口簿":
|
||||
raise RuntimeError("暂不支持居民户口簿")
|
||||
case (
|
||||
"居民身份证(国徽、头像面)" | "居民身份证(国徽面)" | "居民身份证(头像面)"
|
||||
):
|
||||
idcard_recognize(image_guid, image_format, image_base64)
|
||||
|
||||
# 遍历工作目录中赔案目录并创建赔案档案(模拟自动化域就待自动化任务创建理赔档案)
|
||||
for case_path in [x for x in directory_path.iterdir() if x.is_dir()]:
|
||||
# 初始化赔案档案(实际报案层包括保险分公司名称、报案渠道、批次号、报案号和报案时间等)
|
||||
|
|
@ -1264,9 +1302,8 @@ if __name__ == "__main__":
|
|||
}
|
||||
)["result"]["recognition_enable"]:
|
||||
continue
|
||||
|
||||
# 影像件识别
|
||||
recognition = image_recognize(image_base64, image_type)
|
||||
# 影像件识别并整合至赔案档案
|
||||
image_recognize(image_guid, image_format, image_base64, image_type)
|
||||
|
||||
|
||||
"""
|
||||
|
|
@ -1274,48 +1311,7 @@ if __name__ == "__main__":
|
|||
|
||||
|
||||
|
||||
# 根据影像件类型匹配影像件数据提取
|
||||
# noinspection PyUnreachableCode
|
||||
match image_type:
|
||||
case "居民身份证(正背面)" | "居民身份证(正面)" | "居民身份证(背面)":
|
||||
extraction = idcard_extraction()
|
||||
# 若发生异常则跳过该影像件
|
||||
if extraction is None:
|
||||
dossier["影像件层"][-1]["已识别"] = "否,无法识别"
|
||||
continue
|
||||
|
||||
if image_type in ["居民身份证(正背面)", "居民身份证(正面)"]:
|
||||
dossier["赔案层"]["申请人信息"].update(
|
||||
{
|
||||
"证件有效期起": datetime.strptime(
|
||||
extraction["有效期起"], "%Y-%m-%d"
|
||||
),
|
||||
"证件有效期止": (
|
||||
date
|
||||
if (date := extraction["有效期止"]) == "长期"
|
||||
else datetime.strptime(date, "%Y-%m-%d")
|
||||
), # 若证件有效期止为NONE默认为“长期”,
|
||||
}
|
||||
) # 原则上由影像件数据提取环节负责数据标准化,赔案档案数据填充环节负责数据机构化
|
||||
|
||||
if image_type in ["居民身份证(正背面)", "居民身份证(背面)"]:
|
||||
dossier["赔案层"]["申请人信息"].update(
|
||||
{
|
||||
"姓名": extraction["姓名"],
|
||||
"证件类型": "居民身份证",
|
||||
"证件号码": extraction["公民身份号码"],
|
||||
"性别": extraction["性别"],
|
||||
"出生": datetime.strptime(
|
||||
extraction["出生"], "%Y-%m-%d"
|
||||
), # 默认日期格式为%Y-%m-%d
|
||||
"省": (
|
||||
address := parse_location(extraction["住址"])
|
||||
).get("province"),
|
||||
"地": address.get("city"),
|
||||
"县": address.get("county"),
|
||||
"详细地址": address.get("detail"),
|
||||
}
|
||||
)
|
||||
|
||||
case "银行卡":
|
||||
extraction = bankcard_extraction()
|
||||
|
|
|
|||
Loading…
Reference in New Issue