因pillow在linux中有问题难以解决,更换图片处理库为openCV

This commit is contained in:
2024-06-21 13:34:25 +08:00
parent b17104d7cb
commit 641964bda9
3 changed files with 36 additions and 32 deletions

View File

@@ -5,14 +5,14 @@ import os
import sys import sys
import tempfile import tempfile
import time import time
from io import BytesIO import urllib.request
import cv2
import numpy as np
import paddle import paddle
import requests
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from PIL import Image
from time import sleep from time import sleep
from sqlalchemy import update from sqlalchemy import update
from config.keys import PATIENT_NAME, ADMISSION_DATE, DISCHARGE_DATE, MEDICAL_EXPENSES, PERSONAL_CASH_PAYMENT, \ from config.keys import PATIENT_NAME, ADMISSION_DATE, DISCHARGE_DATE, MEDICAL_EXPENSES, PERSONAL_CASH_PAYMENT, \
@@ -35,16 +35,18 @@ from ucloud import ucloud
# 获取图片 # 获取图片
def open_image_from_url(url): def open_image(img_path):
if url.startswith("http"): if img_path.startswith("http"):
# 发送HTTP请求获取图数据 # 发送HTTP请求获取图数据
response = requests.get(url) resp = urllib.request.urlopen(img_path)
# 将响应内容转化为BytesIO对象以便PIL处理 # 将数据读取为字节流
image_stream = BytesIO(response.content) image_data = resp.read()
# 使用PIL的Image.open方法打开图像 # 将字节流转换为NumPy数组
image = Image.open(image_stream) image_np = np.frombuffer(image_data, np.uint8)
# 解码NumPy数组为OpenCV图像格式
image = cv2.imdecode(image_np, cv2.IMREAD_COLOR)
else: else:
image = Image.open(url) image = cv2.imread(img_path)
return image return image
@@ -52,31 +54,37 @@ def open_image_from_url(url):
def split_image(img_path, max_ratio=2.82, best_ration=1.41, overlap=0.05): def split_image(img_path, max_ratio=2.82, best_ration=1.41, overlap=0.05):
split_result = [] split_result = []
# 打开图片 # 打开图片
img = open_image_from_url(img_path) img = open_image(img_path)
# 获取图片的宽度和高度 # 获取图片的宽度和高度
width, height = img.size height, width = img.shape[:2]
# 计算宽高比 # 计算宽高比
ratio = max(width, height) / min(width, height) ratio = max(width, height) / min(width, height)
# 检查是否需要裁剪 # 检查是否需要裁剪
if ratio > max_ratio: if ratio > max_ratio:
# 确定裁剪的尺寸,保持长宽比,以较短边为基准 # 确定裁剪的尺寸,保持长宽比,以较短边为基准
new_ratio = best_ration - overlap new_ratio = best_ration - overlap
if width < height: # 高度是较长边 if width < height:
# 高度是较长边
cropped_width = width * best_ration
for i in range(math.ceil(height / (width * new_ratio))): for i in range(math.ceil(height / (width * new_ratio))):
offset = round(width * new_ratio * i) offset = round(width * new_ratio * i)
cropped_img = img.crop((0, offset, width, round(offset + width * best_ration))) # 参数形式为[y1:y2, x1:x2]
# 统一转为RGB这样可以正确保存为jpg格式 cropped_img = img[offset:round(offset + cropped_width), 0:width]
cropped_img = cropped_img.convert("RGB")
split_result.append({"img": cropped_img, "x_offset": 0, "y_offset": offset}) split_result.append({"img": cropped_img, "x_offset": 0, "y_offset": offset})
else: # 宽度是较长边 # 最后一次裁剪时不足的部分填充黑色
last_img = split_result[-1]["img"]
split_result[-1]["img"] = cv2.copyMakeBorder(last_img, 0, round(cropped_width - last_img.shape[0]), 0, 0, cv2.BORDER_CONSTANT, value=(0, 0, 0))
else:
# 宽度是较长边
cropped_height = height * best_ration
for i in range(math.ceil(width / (height * new_ratio))): for i in range(math.ceil(width / (height * new_ratio))):
offset = round(height * new_ratio * i) offset = round(height * new_ratio * i)
cropped_img = img.crop((offset, 0, round(offset + height * best_ration), height)) cropped_img = img[0:height, offset:round(offset + cropped_height)]
# 统一转为RGB这样可以正确保存为jpg格式
cropped_img = cropped_img.convert("RGB")
split_result.append({"img": cropped_img, "x_offset": offset, "y_offset": 0}) split_result.append({"img": cropped_img, "x_offset": offset, "y_offset": 0})
# 最后一次裁剪时不足的部分填充黑色
last_img = split_result[-1]["img"]
split_result[-1]["img"] = cv2.copyMakeBorder(last_img, 0, 0, 0, round(cropped_height - last_img.shape[1]), cv2.BORDER_CONSTANT, value=(0, 0, 0))
else: else:
img = img.convert("RGB")
split_result.append({"img": img, "x_offset": 0, "y_offset": 0}) split_result.append({"img": img, "x_offset": 0, "y_offset": 0})
return split_result return split_result
@@ -99,8 +107,7 @@ def information_extraction(ie, phrecs):
split_result = split_image(pic_path) split_result = split_image(pic_path)
for img in split_result: for img in split_result:
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file: with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file:
img["img"].save(temp_file.name) cv2.imwrite(temp_file.name, img["img"])
docs.append({"doc": temp_file.name}) docs.append({"doc": temp_file.name})
doc_phrecs.append({"phrec": phrec, "x_offset": img["x_offset"], "y_offset": img["y_offset"]}) doc_phrecs.append({"phrec": phrec, "x_offset": img["x_offset"], "y_offset": img["y_offset"]})
if not docs: if not docs:

View File

@@ -1,5 +0,0 @@
from photo_review.photo_review import open_image_from_url
if __name__ == '__main__':
image = open_image_from_url("./PH20240529000194_1_075936_1.png")
image.save("test.png")

View File

@@ -6,6 +6,8 @@ import tempfile
import time import time
from pprint import pprint from pprint import pprint
import cv2
from photo_review.photo_review import split_image from photo_review.photo_review import split_image
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@@ -48,7 +50,7 @@ def visual_model_test(model_type, test_img, task_path, schema):
doc_parser = DocParser(layout_analysis=False) doc_parser = DocParser(layout_analysis=False)
for img in imgs: for img in imgs:
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file: with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file:
img["img"].save(temp_file.name) cv2.imwrite(temp_file.name, img["img"])
temp_files_paths.append(temp_file.name) temp_files_paths.append(temp_file.name)
parsed_doc = doc_parser.parse({"doc": temp_file.name}, expand_to_a4_size=True) parsed_doc = doc_parser.parse({"doc": temp_file.name}, expand_to_a4_size=True)
if img["x_offset"] or img["y_offset"]: if img["x_offset"] or img["y_offset"]:
@@ -67,7 +69,7 @@ def visual_model_test(model_type, test_img, task_path, schema):
temp_files_paths = [] temp_files_paths = []
for img in split_result: for img in split_result:
with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file: with tempfile.NamedTemporaryFile(delete=False, suffix=".jpg") as temp_file:
img["img"].save(temp_file.name) cv2.imwrite(temp_file.name, img["img"])
temp_files_paths.append(temp_file.name) temp_files_paths.append(temp_file.name)
docs.append({"doc": temp_file.name}) docs.append({"doc": temp_file.name})