Yolov/mapping_cn.py

112 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import os
class ChineseTextRenderer:
def __init__(self, font_path=None):
self.font_cache = {}
self.font_path = font_path
def put_text(self, img, text, position, font_size=20, color=(0, 255, 0)):
"""安全的中文文本绘制函数"""
# 输入验证
if img is None:
raise ValueError("输入图像不能为None")
if not isinstance(img, np.ndarray):
raise TypeError(f"输入图像必须是numpy数组实际是{type(img)}")
if len(img.shape) != 3 or img.shape[2] != 3:
# 尝试转换
if len(img.shape) == 2:
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
elif len(img.shape) == 3 and img.shape[2] == 4:
img = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
else:
raise ValueError(f"不支持的图像格式shape={img.shape}")
try:
# BGR转RGB
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
pil_img = Image.fromarray(img_rgb)
draw = ImageDraw.Draw(pil_img)
# 获取字体
font = self._get_font(font_size)
# 颜色转换BGR到RGB
rgb_color = color[::-1]
# 绘制文本
draw.text(position, text, font=font, fill=rgb_color)
# RGB转BGR
return cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)
except Exception as e:
print(f"中文渲染失败: {e},使用英文后备")
# 后备方案使用OpenCV绘制英文
cv2.putText(img, text, position, cv2.FONT_HERSHEY_SIMPLEX,
font_size / 30, color, 2)
return img
def _get_font(self, size):
"""获取字体对象,带缓存"""
if size in self.font_cache:
return self.font_cache[size]
# 查找字体文件
font_paths = []
if self.font_path and os.path.exists(self.font_path):
font_paths.append(self.font_path)
# 添加常用字体路径
font_paths.extend([
"simhei.ttf",
"msyh.ttc",
"C:/Windows/Fonts/simhei.ttf",
"C:/Windows/Fonts/msyh.ttc",
"C:/Windows/Fonts/Deng.ttf",
"C:/Windows/Fonts/simsun.ttc",
])
# 遍历所有可能的字体路径
font = None
for path in font_paths:
if os.path.exists(path):
try:
font = ImageFont.truetype(path, size, encoding="utf-8")
print(f"加载字体: {path}")
break
except Exception as e:
continue
# 如果找不到字体,尝试创建默认字体
if font is None:
try:
font = ImageFont.load_default()
# 调整默认字体大小
font = ImageFont.truetype("arial.ttf", size)
except:
# 最后手段使用PIL的默认字体
font = ImageFont.load_default()
self.font_cache[size] = font
return font
def ensure_image_valid(img, default_size=(640, 480)):
"""确保图像有效,如果无效则创建默认图像"""
if img is None or not isinstance(img, np.ndarray) or img.size == 0:
print("创建默认图像...")
img = np.zeros((default_size[0], default_size[1], 3), dtype=np.uint8)
img.fill(50)
# 添加一些参考线
h, w = img.shape[:2]
cv2.line(img, (0, 0), (w, h), (0, 255, 0), 1)
cv2.line(img, (w, 0), (0, h), (0, 255, 0), 1)
cv2.circle(img, (w // 2, h // 2), min(w, h) // 4, (255, 0, 0), 2)
return img