新增自动识别错误检查功能

This commit is contained in:
2024-08-26 14:42:50 +08:00
parent aa3009e6a9
commit aea6f19951
4 changed files with 332 additions and 48 deletions

View File

@@ -0,0 +1,230 @@
import json
import os
import sys
from datetime import date, timedelta
from decimal import Decimal
from io import BytesIO
from itertools import groupby
import requests
from PIL import ImageFont, ImageDraw, Image
from sqlalchemy import update
from db import MysqlSession
from db.mysql import ViewErrorReview, ZxPhhd, ZxPhrec, ZxIeResult, ZxIeSettlement, ZxIeDischarge, ZxIeCost
from ucloud import ufile
from util import image_util
def main(pk_phhd=None):
session = MysqlSession()
error_query = (session.query(ZxPhhd.pk_phhd, ZxPhhd.cXm, ViewErrorReview.pk_yljg, ViewErrorReview.pk_yljg_ocr,
ViewErrorReview.pk_ylks, ViewErrorReview.pk_ylks_ocr, ViewErrorReview.cdoctor,
ViewErrorReview.cdoctor_ocr, ViewErrorReview.czyh, ViewErrorReview.czyh_ocr,
ViewErrorReview.dzyrq, ViewErrorReview.dzyrq_ocr, ViewErrorReview.dcyrq,
ViewErrorReview.dcyrq_ocr, ViewErrorReview.input_cxm, ViewErrorReview.input_cxm_ocr,
ViewErrorReview.ffsylfy, ViewErrorReview.ffsylfy_ocr, ViewErrorReview.fgrzfje1,
ViewErrorReview.fgrzfje1_ocr, ViewErrorReview.fgezfje2, ViewErrorReview.fgezfje2_ocr,
ViewErrorReview.fgrzfje, ViewErrorReview.fgrzfje_ocr, ViewErrorReview.yb_type,
ViewErrorReview.yb_type_ocr, ViewErrorReview.cjsd_id, ViewErrorReview.cjsd_id_ocr,
ViewErrorReview.fage, ViewErrorReview.fage_ocr, ZxPhhd.problem_note)
.join(ZxPhhd, ViewErrorReview.pk_phhd == ZxPhhd.pk_phhd, isouter=True))
if pk_phhd:
error_query = error_query.filter(ZxPhhd.pk_phhd == pk_phhd)
else:
today = date.today()
error_query = (error_query.filter(ZxPhhd.problem_note.is_(None))
.filter(ViewErrorReview.creationtime >= today)
.filter(ViewErrorReview.creationtime < today + timedelta(days=1))
.order_by(ViewErrorReview.creationtime.desc()))
error_review = error_query.limit(1).one_or_none()
if error_review is None:
print("没有需要检查的记录")
sys.exit()
pk_phhd = error_review.pk_phhd
# 文件路径
directory = f"./review_error_check/{pk_phhd}"
if not os.path.exists(directory):
os.makedirs(directory)
json_result = {
"pk_phhd": pk_phhd,
"cXm": error_review.cXm
}
settlement_query = session.query(ZxIeSettlement.pk_ie_settlement)
discharge_query = session.query(ZxIeDischarge.pk_ie_discharge)
cost_query = session.query(ZxIeCost.pk_ie_cost)
if error_review.pk_yljg != error_review.pk_yljg_ocr:
json_result["医院pk_yljg"] = error_review.pk_yljg
json_result["pk_yljg_ocr"] = error_review.pk_yljg_ocr
discharge_query = discharge_query.add_columns(ZxIeDischarge.hospital, ZxIeDischarge.pk_yljg)
if error_review.pk_ylks != error_review.pk_ylks_ocr:
json_result["科室pk_ylks"] = error_review.pk_ylks
json_result["pk_ylks_ocr"] = error_review.pk_ylks_ocr
discharge_query = discharge_query.add_columns(ZxIeDischarge.department, ZxIeDischarge.pk_ylks)
if error_review.cdoctor != error_review.cdoctor_ocr:
json_result["医生cdoctor"] = error_review.cdoctor
json_result["cdoctor_ocr"] = error_review.cdoctor_ocr
discharge_query = discharge_query.add_column(ZxIeDischarge.doctor)
if error_review.czyh != error_review.czyh_ocr:
json_result["住院号czyh"] = error_review.czyh
json_result["czyh_ocr"] = error_review.czyh_ocr
settlement_query = settlement_query.add_column(ZxIeSettlement.admission_id)
discharge_query = discharge_query.add_column(ZxIeDischarge.admission_id)
if error_review.dzyrq != error_review.dzyrq_ocr:
json_result["入院日期dzyrq"] = error_review.dzyrq
json_result["dzyrq_ocr"] = error_review.dzyrq_ocr
settlement_query = settlement_query.add_columns(ZxIeSettlement.admission_date_str,
ZxIeSettlement.admission_date)
discharge_query = discharge_query.add_columns(ZxIeDischarge.admission_date_str, ZxIeDischarge.admission_date)
cost_query = cost_query.add_columns(ZxIeCost.admission_date_str, ZxIeCost.admission_date)
if error_review.dcyrq != error_review.dcyrq_ocr:
json_result["出院日期dcyrq"] = error_review.dcyrq
json_result["dcyrq_ocr"] = error_review.dcyrq_ocr
settlement_query = settlement_query.add_columns(ZxIeSettlement.discharge_date_str,
ZxIeSettlement.discharge_date)
discharge_query = discharge_query.add_columns(ZxIeDischarge.discharge_date_str, ZxIeDischarge.discharge_date)
cost_query = cost_query.add_columns(ZxIeCost.discharge_date_str, ZxIeCost.discharge_date)
if error_review.input_cxm != error_review.input_cxm_ocr:
json_result["姓名input_cxm"] = error_review.input_cxm
json_result["input_cxm_ocr"] = error_review.input_cxm_ocr
settlement_query = settlement_query.add_column(ZxIeSettlement.name)
discharge_query = discharge_query.add_column(ZxIeDischarge.name)
cost_query = cost_query.add_column(ZxIeCost.name)
if error_review.ffsylfy != error_review.ffsylfy_ocr:
json_result["费用总额ffsylfy"] = error_review.ffsylfy
json_result["ffsylfy_ocr"] = error_review.ffsylfy_ocr
settlement_query = settlement_query.add_columns(ZxIeSettlement.medical_expenses_str,
ZxIeSettlement.medical_expenses)
cost_query = cost_query.add_columns(ZxIeCost.medical_expenses_str, ZxIeCost.medical_expenses)
if error_review.fgrzfje1 != error_review.fgrzfje1_ocr:
json_result["个人现金支付fgrzfje1"] = error_review.fgrzfje1
json_result["fgrzfje1_ocr"] = error_review.fgrzfje1_ocr
settlement_query = settlement_query.add_columns(ZxIeSettlement.personal_cash_payment_str,
ZxIeSettlement.personal_cash_payment)
if error_review.fgezfje2 != error_review.fgezfje2_ocr:
json_result["个人账户支付fgezfje2"] = error_review.fgezfje2
json_result["fgezfje2_ocr"] = error_review.fgezfje2_ocr
settlement_query = settlement_query.add_columns(ZxIeSettlement.personal_account_payment_str,
ZxIeSettlement.personal_account_payment)
if error_review.fgrzfje != error_review.fgrzfje_ocr:
json_result["个人自费fgrzfje"] = error_review.fgrzfje
json_result["fgrzfje_ocr"] = error_review.fgrzfje_ocr
settlement_query = settlement_query.add_columns(ZxIeSettlement.personal_funded_amount_str,
ZxIeSettlement.personal_funded_amount)
if error_review.yb_type != error_review.yb_type_ocr:
json_result["医保类型yb_type"] = error_review.yb_type
json_result["yb_type_ocr"] = error_review.yb_type_ocr
settlement_query = settlement_query.add_columns(ZxIeSettlement.medical_insurance_type_str,
ZxIeSettlement.medical_insurance_type)
if error_review.cjsd_id != error_review.cjsd_id_ocr:
json_result["结算单号cjsd_id"] = error_review.cjsd_id
json_result["cjsd_id_ocr"] = error_review.cjsd_id_ocr
settlement_query = settlement_query.add_column(ZxIeSettlement.settlement_id)
if error_review.fage != error_review.fage_ocr:
json_result["年龄fage"] = error_review.fage
json_result["fage_ocr"] = error_review.fage_ocr
discharge_query = discharge_query.add_column(ZxIeDischarge.age)
settlement = settlement_query.filter(ZxIeSettlement.pk_phhd == pk_phhd).one_or_none()
if settlement is not None:
json_result["settlement"] = settlement._asdict()
discharge = discharge_query.filter(ZxIeDischarge.pk_phhd == pk_phhd).one_or_none()
if discharge is not None:
json_result["discharge"] = discharge._asdict()
cost = cost_query.filter(ZxIeCost.pk_phhd == pk_phhd).one_or_none()
if cost is not None:
json_result["cost"] = cost._asdict()
phrecs = session.query(ZxPhrec.pk_phrec, ZxPhrec.pk_phhd, ZxPhrec.cRectype, ZxPhrec.cfjaddress).filter(
ZxPhrec.pk_phhd == pk_phhd).all()
for phrec in phrecs:
img_name = phrec.cfjaddress
img_path = ufile.get_private_url(img_name)
response = requests.get(img_path)
image = Image.open(BytesIO(response.content)).convert("RGB")
font_size = image.width * image.height / 200000
font = ImageFont.truetype("./font/simfang.ttf", size=font_size)
ie_result = session.query(ZxIeResult.id, ZxIeResult.content, ZxIeResult.rotation_angle, ZxIeResult.x_offset,
ZxIeResult.y_offset).filter(ZxIeResult.pk_phrec == phrec.pk_phrec).all()
if not ie_result:
no_ie_directory = f"{directory}/0"
if not os.path.exists(no_ie_directory):
os.makedirs(no_ie_directory)
image.save(f"{no_ie_directory}/{img_name}")
for _, group_results in groupby(ie_result, key=lambda x: x.id):
draw = ImageDraw.Draw(image)
for ocr_item in group_results:
result = json.loads(ocr_item.content)
rotation_angle = ocr_item.rotation_angle
x_offset = ocr_item.x_offset
y_offset = ocr_item.y_offset
for key in result:
for value in result[key]:
box = value["bbox"][0]
if rotation_angle:
box = image_util.invert_rotate_rectangle(box, (image.width / 2, image.height / 2),
rotation_angle)
if x_offset:
box[0] += x_offset
box[2] += x_offset
if y_offset:
box[1] += y_offset
box[3] += y_offset
draw.rectangle(box, outline="red", width=2) # 绘制矩形
draw.text((box[0], box[1] - font_size), key, fill="blue", font=font) # 在矩形上方绘制文本
draw.text((box[0], box[3]), value["text"], fill="blue", font=font) # 在矩形下方绘制文本
ie_directory = f"{directory}/{ocr_item.id}"
os.makedirs(ie_directory, exist_ok=True)
image.save(f"{ie_directory}/{img_name}")
session.close()
# 自定义JSON处理器
def default(obj):
if isinstance(obj, Decimal):
return float(obj)
if isinstance(obj, date):
return obj.strftime("%Y-%m-%d")
with open(f"{directory}/result.json", "w", encoding="utf-8") as json_file:
json.dump(json_result, json_file, indent=4, ensure_ascii=False, default=default)
return pk_phhd
if __name__ == '__main__':
pk_phhd = main()
while True:
check_finish = input(f"{pk_phhd}是否完成(是/否)")
if check_finish == "":
"""
错误描述的写法:
1. 查看result.json以含中文的key中的中文为现在的key
2. 为方便输入key之后跟中文冒号
3. 冒号之后写错误原因,原因最好是固定的几种写法
4. 可以在原因后跟中文括号,并在括号中进行补充说明
5. 写完错误原因以中文分号结尾,最后一个可以不加分号
举例:
错误描述:医院:未知错误;科室:还是未知错误(补充说明)
"""
error_descript = input("错误描述:")
break
elif check_finish == "":
sys.exit()
else:
print("无效输入!请输入“是”或者“否”")
session = MysqlSession()
update_error = update(ZxPhhd).where(ZxPhhd.pk_phhd == pk_phhd).values(problem_note=error_descript)
session.execute(update_error)
session.commit()
session.close()
print(f"{pk_phhd}】错误分析已完成。错误描述:{error_descript}")

View File

@@ -0,0 +1,99 @@
import json
from collections import defaultdict
from datetime import date, timedelta
from sqlalchemy.sql.functions import count
from db import MysqlSession
from db.mysql import ZxPhhd, ViewErrorReview
from util import util
def handle_reason(reason):
if "" in reason:
reason = reason.split("")[0]
return reason
if __name__ == '__main__':
today = date.today()
session = MysqlSession()
error_reviews_count = (session.query(count())
.filter(ViewErrorReview.creationtime >= today)
.filter(ViewErrorReview.creationtime < today + timedelta(days=1))
.scalar())
error_reviews = (session.query(ZxPhhd.problem_note, ViewErrorReview.pk_phhd)
.join(ZxPhhd, ViewErrorReview.pk_phhd == ZxPhhd.pk_phhd, isouter=True)
.filter(ZxPhhd.problem_note.is_not(None))
.filter(ViewErrorReview.creationtime >= today)
.filter(ViewErrorReview.creationtime < today + timedelta(days=1))
.all())
session.close()
result = {f"{today}涂抹错误图片总数": error_reviews_count}
hospital_result = defaultdict(int)
department_result = defaultdict(int)
doctor_result = defaultdict(int)
admission_id_result = defaultdict(int)
admission_date_result = defaultdict(int)
discharge_date_result = defaultdict(int)
name_result = defaultdict(int)
medical_expenses_result = defaultdict(int)
personal_cash_payment_result = defaultdict(int)
personal_account_payment_result = defaultdict(int)
personal_funded_amount_result = defaultdict(int)
medical_insurance_type_result = defaultdict(int)
settlement_id_result = defaultdict(int)
age_result = defaultdict(int)
for error_review in error_reviews:
columns = error_review.problem_note.split("")
for column in columns:
key, value = column.split("")
if key == "医院":
hospital_result[handle_reason(value)] += 1
elif key == "科室":
department_result[handle_reason(value)] += 1
elif key == "医生":
doctor_result[handle_reason(value)] += 1
elif key == "住院号":
admission_id_result[handle_reason(value)] += 1
elif key == "入院日期":
admission_date_result[handle_reason(value)] += 1
elif key == "出院日期":
discharge_date_result[handle_reason(value)] += 1
elif key == "姓名":
name_result[handle_reason(value)] += 1
elif key == "费用总额":
medical_expenses_result[handle_reason(value)] += 1
elif key == "个人现金支付":
personal_cash_payment_result[handle_reason(value)] += 1
elif key == "个人账户支付":
personal_account_payment_result[handle_reason(value)] += 1
elif key == "个人自费":
personal_funded_amount_result[handle_reason(value)] += 1
elif key == "医保类别":
medical_insurance_type_result[handle_reason(value)] += 1
elif key == "结算单号":
settlement_id_result[handle_reason(value)] += 1
elif key == "年龄":
age_result[handle_reason(value)] += 1
result["医院"] = hospital_result
result["科室"] = department_result
result["主治医生"] = doctor_result
result["住院号"] = admission_id_result
result["住院日期"] = admission_date_result
result["出院日期"] = discharge_date_result
result["患者姓名"] = name_result
result["费用总额"] = medical_expenses_result
result["个人现金支付"] = personal_cash_payment_result
result["个人账户支付"] = personal_account_payment_result
result["个人自费"] = personal_funded_amount_result
result["医保类型"] = medical_insurance_type_result
result["结算单号"] = settlement_id_result
result["年龄"] = age_result
print(result)
with open("photo_review_error_report.txt", 'w', encoding='utf-8') as file:
file.write(json.dumps(result, indent=4, ensure_ascii=False))
file.write(util.get_default_datetime())
print("结果已保存。")