From 2b15d49b5ce4ee3924053eac1aa3e22c2aacfbd3 Mon Sep 17 00:00:00 2001 From: liubiren Date: Thu, 11 Dec 2025 01:07:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=B8=B8=E6=9B=B4=E6=96=B0=20from=20m?= =?UTF-8?q?ac=20mini(intel)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 票据理赔自动化/main.py | 212 ++++++++++++++++++++--------------------- 1 file changed, 104 insertions(+), 108 deletions(-) diff --git a/票据理赔自动化/main.py b/票据理赔自动化/main.py index d046bd8..79beaf4 100644 --- a/票据理赔自动化/main.py +++ b/票据理赔自动化/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()