新增证件识别接口
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
from typing import TypedDict
|
||||
|
||||
from langchain_core.messages import HumanMessage
|
||||
from langgraph.graph import StateGraph, END
|
||||
|
||||
from config.llm import llmVision
|
||||
|
||||
|
||||
# -------- 定义状态 --------
|
||||
class State(TypedDict):
|
||||
image_url: str # 证件照
|
||||
type: int # 证件类别
|
||||
content: str # 最终内容
|
||||
|
||||
|
||||
def analyze_card(state: State, prompt_text: str):
|
||||
messages = [
|
||||
HumanMessage(
|
||||
content=[
|
||||
{"type": "text", "text": prompt_text},
|
||||
{"type": "image_url", "image_url": {"url": state["image_url"]}},
|
||||
]
|
||||
)
|
||||
]
|
||||
return llmVision.invoke(messages).content
|
||||
|
||||
|
||||
# -------- 定义节点 --------
|
||||
def decide_source(state: State, max_retry=3):
|
||||
choice = analyze_card(
|
||||
state,
|
||||
"""
|
||||
请根据图片内容判断其中的证件类型,并输出对应代号。
|
||||
代号说明:
|
||||
-1: 并非证件
|
||||
0:身份证
|
||||
1:银行卡
|
||||
|
||||
只输出代号数字,不要输出任何文字、标点或解释。
|
||||
你的输出是:
|
||||
""",
|
||||
)
|
||||
print("图片类型是", choice)
|
||||
try:
|
||||
choice = int(choice)
|
||||
state["type"] = choice
|
||||
if choice == -1:
|
||||
state["content"] = '{"result": "暂不支持此证件"}'
|
||||
except ValueError:
|
||||
state["type"] = -1
|
||||
state["content"] = '{"result": "暂不支持此证件"}'
|
||||
return state
|
||||
|
||||
|
||||
def idcard(state: State):
|
||||
state["content"] = analyze_card(
|
||||
state,
|
||||
"""
|
||||
你是一个 OCR 信息提取专家,请从图片中识别出身份证的全部可见信息,并输出严格的 JSON 格式。
|
||||
要求:
|
||||
1. 无论是正面还是反面,都要识别所有字段。
|
||||
2. 如果某个字段无法辨认,请将值设为 null。
|
||||
3. 只输出 JSON,不要输出任何解释或多余内容。
|
||||
4. 严格保持 JSON 格式,键名统一为英文。
|
||||
5. "side" 字段为身份证方向,填写:人像面 或 国徽面。
|
||||
|
||||
JSON 示例格式:
|
||||
{
|
||||
"side": "国徽面",
|
||||
"name": "持证人姓名",
|
||||
"gender": "性别",
|
||||
"ethnicity": "民族",
|
||||
"id_number": "身份证号",
|
||||
"birth_date": "出生日期",
|
||||
"address": "住址",
|
||||
"issuing_authority": "签发机关",
|
||||
"valid_period_start": "有效期开始日期",
|
||||
"valid_period_end": "有效期结束日期",
|
||||
"notes": "其他可见文字或备注"
|
||||
}
|
||||
|
||||
请确保输出的 JSON 可以被严格解析。
|
||||
""",
|
||||
)
|
||||
return state
|
||||
|
||||
|
||||
def bankcard(state: State):
|
||||
state["content"] = analyze_card(
|
||||
state,
|
||||
"""
|
||||
你是一个 OCR 信息提取专家,请从图片中识别出银行卡上的全部可见信息,并输出严格的 JSON 格式。
|
||||
要求:
|
||||
1. 识别卡号、发卡行、持卡人、有效期等关键信息。
|
||||
2. 如果某个字段无法辨认,请将值设为 null。
|
||||
3. 只输出 JSON,不要输出任何解释或附加内容。
|
||||
4. 严格保持 JSON 格式,键名统一为英文。
|
||||
|
||||
JSON 示例格式:
|
||||
{
|
||||
"bank_name": "发卡行名称",
|
||||
"card_number": "卡号",
|
||||
"card_holder": "持卡人姓名",
|
||||
"expiry_date": "有效期",
|
||||
"card_type": "卡种类型(如借记卡/信用卡/Visa/MasterCard)",
|
||||
"issuer_country": "发卡国家",
|
||||
"notes": "其他可见文字或符号"
|
||||
}
|
||||
|
||||
请确保输出的 JSON 可以被严格解析。
|
||||
""",
|
||||
)
|
||||
return state
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------ 构建有向图 --------
|
||||
workflow = StateGraph(State)
|
||||
workflow.add_node("decide", decide_source)
|
||||
workflow.add_node("idcard", idcard)
|
||||
workflow.add_node("bankcard", bankcard)
|
||||
workflow.set_entry_point("decide")
|
||||
# 条件边:根据 path 决定走向
|
||||
workflow.add_conditional_edges(
|
||||
"decide",
|
||||
lambda state: state["type"],
|
||||
{
|
||||
-1: END,
|
||||
0: "idcard",
|
||||
1: "bankcard",
|
||||
},
|
||||
)
|
||||
workflow.add_edge("idcard", END)
|
||||
workflow.add_edge("bankcard", END)
|
||||
graph = workflow.compile()
|
||||
|
||||
import re
|
||||
|
||||
|
||||
# 执行函数
|
||||
def get_license_response(image_url: str):
|
||||
final_state = graph.invoke(
|
||||
{
|
||||
"image_url": image_url,
|
||||
}
|
||||
)
|
||||
# 去掉 ```json 和 ``` 包裹
|
||||
final_state["content"] = final_state["content"]
|
||||
final_state["content"] = re.sub(
|
||||
r"^```json\s*|\s*```$", "", final_state["content"].strip()
|
||||
)
|
||||
print("最终识别内容:", final_state["content"])
|
||||
return final_state
|
||||
@@ -1,60 +0,0 @@
|
||||
from typing import Optional
|
||||
from pydantic import BaseModel, Field
|
||||
from langchain_core.messages import HumanMessage
|
||||
|
||||
from config.llm import *
|
||||
from langchain.prompts import PromptTemplate
|
||||
|
||||
from langchain.prompts import PromptTemplate
|
||||
from langchain.schema import HumanMessage
|
||||
import os
|
||||
import base64
|
||||
from langchain.prompts import PromptTemplate
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_core.output_parsers import JsonOutputParser
|
||||
from langchain.schema import HumanMessage
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
import json
|
||||
|
||||
import re
|
||||
import json
|
||||
import requests
|
||||
import cv2
|
||||
import numpy as np
|
||||
import requests
|
||||
|
||||
class CocoonSample(BaseModel):
|
||||
moisture_content: float = Field(
|
||||
...,
|
||||
description="茧的含水量,单位为百分比(%),浮点数"
|
||||
)
|
||||
cocoon_weight: float = Field(
|
||||
...,
|
||||
description="下足茧的重量,单位为克,可带小数"
|
||||
)
|
||||
defective_pupa_count: int = Field(
|
||||
...,
|
||||
description="非好蛹粒数,即不合格蛹的数量,整数"
|
||||
)
|
||||
fresh_shell_weight: float = Field(
|
||||
...,
|
||||
description="鲜壳重量,单位为克,可带小数"
|
||||
)
|
||||
sample_count: int = Field(
|
||||
...,
|
||||
description="小样粒数,用于检测的茧粒数,整数"
|
||||
)
|
||||
net_weight_total: float = Field(
|
||||
...,
|
||||
description="所有样品的净重合计,单位为克,浮点数"
|
||||
)
|
||||
evaluator: Optional[str] = Field(
|
||||
None,
|
||||
description="仪评人姓名,可能为空"
|
||||
)
|
||||
reviewer: Optional[str] = Field(
|
||||
None,
|
||||
description="复核人员姓名,可能为空"
|
||||
)
|
||||
Reference in New Issue
Block a user