目录

为什么要将OpenCV帧转换为PIL图像

目录

为什么要将OpenCV帧转换为PIL图像

根本原因:字符编码和字体支持

cv2.putText(frame, “中文测试”, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255), 2)

结果:显示为方框 □□□□

OpenCV的问题:
内置字体限制: OpenCV只有7种内置英文字体(FONT_HERSHEY_*系列)
不支持Unicode: 无法正确渲染中文、日文、韩文等Unicode字符
无法加载外部字体: 不能使用系统TrueType字体(.ttf/.ttc)
字符编码问题: 对非ASCII字符处理有限
PIL/Pillow的优势


font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 24)  # 微软雅黑
draw.text((x, y), "中文测试", font=font, fill=(255,255,255))
# 结果:完美显示 中文测试

PIL的优势:
TrueType字体支持: 可以加载系统中任何.ttf/.ttc字体文件
完整Unicode支持: 原生支持所有Unicode字符集
字体回退机制: 当某个字符不存在时,会尝试使用其他字体
更好的文本渲染: 支持抗锯齿、字距调整等高级特性
转换流程详解


# 1. OpenCV使用BGR色彩空间
frame = cv2.imread("video_frame.jpg")  # BGR格式

# 2. PIL使用RGB色彩空间  
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  # 转换色彩空间
pil_image = Image.fromarray(frame_rgb)  # 转换为PIL图像

# 3. 使用PIL进行文字渲染
draw = ImageDraw.Draw(pil_image)
font = ImageFont.truetype("msyh.ttc", 24)  # 加载中文字体
draw.text((x, y), "中文文字", font=font, fill=(255,255,255))

# 4. 转换回OpenCV格式
frame_with_text = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)
性能对比
方面OpenCVPIL转换方案
中文支持❌ 不支持完美支持
字体选择7种内置系统所有字体
渲染质量基础高质量抗锯齿
性能开销最快轻微开销
内存使用最少略微增加

为什么不直接用PIL处理整个视频?
虽然PIL支持中文,但OpenCV在视频处理方面有巨大优势:


# OpenCV的视频处理优势
cap = cv2.VideoCapture("video.mp4")        # 硬件加速解码
ret, frame = cap.read()                    # 高效帧读取
cv2.VideoWriter("output.mp4", fourcc, fps, size)  # 硬件加速编码

所以最佳方案是:
视频处理: 使用OpenCV(性能最优)
 文字渲染: 使用PIL(中文支持最佳)
 格式转换: 只在需要添加文字时转换

总结
这种"混合方案"是目前处理中文视频字幕的标准做法:
保持OpenCV的视频处理优势
借用PIL的字体渲染能力
最小化性能开销(只在添加文字时转换)
获得最佳的中文显示效果