comic-text-detector-guide.md 11 KB

Comic-Text-Detector 使用指南

概述

comic-text-detector 是一个专门用于检测漫画页面中文字区域的深度学习工具。它结合了 YOLOv5 目标检测和语义分割技术,能够准确识别和定位漫画中的对话气泡和文字区域。

参数说明

1. TextDetector 初始化参数

TextDetector(
    model_path,           # 模型文件路径(.pt 或 .onnx)
    input_size=1024,      # 输入图片尺寸(默认1024,可以是int或tuple)
    device='cpu',         # 设备:'cpu' 或 'cuda'
    half=False,           # 是否使用半精度(FP16)
    nms_thresh=0.35,      # NMS阈值(0-1,越小越严格)
    conf_thresh=0.4,      # 置信度阈值(0-1,越小检测越多)
    mask_thresh=0.3,      # Mask阈值(用于分割)
    act='leaky'           # 激活函数:'leaky'、'relu'、'silu'等
)

参数详解

参数 类型 默认值 说明
model_path str 必需 模型文件路径,支持 .pt(PyTorch)或 .onnx(ONNX)格式
input_size int/tuple 1024 输入图片尺寸,可以是单个整数(如1024)或元组(如(1024, 1024))
device str 'cpu' 计算设备,'cpu' 或 'cuda'(需要GPU支持)
half bool False 是否使用半精度浮点数(FP16),可加速推理但可能降低精度
nms_thresh float 0.35 非极大值抑制阈值,范围0-1,值越小过滤越严格
conf_thresh float 0.4 置信度阈值,范围0-1,值越小检测到的区域越多
mask_thresh float 0.3 Mask分割阈值,用于生成文字区域的mask
act str 'leaky' 激活函数类型,可选:'leaky'、'relu'、'silu'

2. 检测调用参数

detector(
    img,                              # 输入图片(numpy数组)
    refine_mode=REFINEMASK_INPAINT,   # 精炼模式
    keep_undetected_mask=False        # 是否保留未检测到的mask区域
)

参数详解

参数 类型 默认值 说明
img np.ndarray 必需 输入图片,OpenCV格式(BGR)的numpy数组
refine_mode int REFINEMASK_INPAINT 精炼模式,见下方说明
keep_undetected_mask bool False 是否保留未检测到的mask区域,True会保留更多区域

refine_mode 选项

  • REFINEMASK_INPAINT = 0:使用修复模式

    • 适合后续OCR识别
    • 会填充缺失的文字区域
    • 生成更完整的mask
  • REFINEMASK_ANNOTATION = 1:使用标注模式

    • 适合可视化展示
    • 保持原始检测结果
    • 不进行额外的填充操作

功能组成

1. 核心模块

TextDetector(主检测器类)

  • 负责整个检测流程的协调
  • 管理模型加载和推理
  • 处理输入输出转换

YOLOv5 检测网络

  • 检测文字区域的边界框
  • 输出每个区域的置信度分数
  • 快速定位文字位置

分割网络

  • 生成文字区域的精确mask
  • 提供像素级的文字区域分割
  • 支持不规则形状的文字区域

后处理模块

  • NMS(非极大值抑制):去除重叠的检测框
  • 坐标映射:将模型输出坐标映射回原图尺寸
  • Mask精炼:优化mask边界,填充缺失区域

2. 辅助功能

文字块分组

  • 将检测到的文字区域分组为文本块(TextBlock)
  • 每个TextBlock包含:
    • 边界框坐标(x1, y1, x2, y2)
    • 文字行轮廓(多边形坐标)
    • 中心点坐标
    • 宽度和高度
    • 语言类型(英文/日文/未知)
    • 是否垂直排列

Mask精炼

  • 优化mask边界,使其更贴合文字区域
  • 根据refine_mode选择不同的精炼策略
  • 可选地保留未检测到的区域

多语言支持

  • 支持英文(eng)
  • 支持日文(ja)
  • 支持未知语言(unknown)

多边形轮廓提取

  • 提取文字行的精确轮廓
  • 支持不规则形状的文字区域
  • 提供更准确的文字边界

实现步骤

步骤1:初始化检测器

from inference import TextDetector

detector = TextDetector(
    model_path='data/comictextdetector.pt',
    input_size=1024,
    device='cuda' if torch.cuda.is_available() else 'cpu',
    act='leaky'
)

说明:

  • 加载预训练模型(.pt或.onnx格式)
  • 设置输入尺寸和设备
  • 初始化网络结构

步骤2:图片预处理

import cv2
import numpy as np

# 读取图片(支持中文路径)
img_array = np.fromfile(image_path, dtype=np.uint8)
img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)

处理流程:

  1. 读取图片文件(使用np.fromfilecv2.imdecode处理中文路径)
  2. Letterbox调整:保持宽高比,将图片调整到input_size
  3. 转换为张量格式
  4. 移至指定设备(CPU或GPU)

步骤3:模型推理

mask, mask_refined, blk_list = detector(
    img,
    refine_mode=REFINEMASK_ANNOTATION,
    keep_undetected_mask=True
)

推理过程:

  1. YOLOv5检测

    • 输出边界框和置信度
    • 快速定位文字区域
  2. 分割网络

    • 输出文字区域的mask
    • 提供像素级分割结果
  3. 后处理

    • 应用NMS过滤重叠框
    • 使用置信度阈值过滤低质量检测
    • 将坐标映射回原图尺寸

步骤4:文字块提取

# 从mask中提取文字行轮廓(多边形)
lines, scores = seg_rep(input_size, lines_map)

# 将检测框和轮廓分组为TextBlock对象
blk_list = group_output(blks, lines, im_w, im_h, mask)

处理内容:

  • 从mask中提取文字行轮廓(多边形坐标)
  • 将检测框和轮廓分组为TextBlock对象
  • 计算每个文字块的属性:
    • 边界框坐标
    • 中心点坐标
    • 宽度和高度
    • 语言类型
    • 是否垂直排列

步骤5:Mask精炼

# 使用refine_mask优化mask边界
mask_refined = refine_mask(img, mask, blk_list, refine_mode=refine_mode)

# 可选:保留未检测到的区域
if keep_undetected_mask:
    mask_refined = refine_undetected_mask(
        img, mask, mask_refined, blk_list, refine_mode=refine_mode
    )

精炼策略:

  • INPAINT模式:使用修复算法填充缺失区域,适合后续OCR
  • ANNOTATION模式:保持原始检测结果,适合可视化
  • keep_undetected_mask:可选地保留未检测到的区域

步骤6:输出结果

返回值:

  • mask:原始检测mask(二值图像)
  • mask_refined:精炼后的mask(优化后的二值图像)
  • blk_list:文字块列表,每个元素包含:

    {
      'index': 1,
      'bbox': {
          'x1': 100, 'y1': 200,
          'x2': 300, 'y2': 250,
          'width': 200, 'height': 50,
          'center_x': 200, 'center_y': 225
      },
      'lines': [[[x1, y1], [x2, y2], ...]],  # 多边形轮廓
      'language': 'ja',
      'vertical': False
    }
    

参数调优建议

1. input_size(输入尺寸)

  • 512:速度快,适合低分辨率图片
  • 1024:平衡速度和精度(推荐)
  • 1536:高精度,适合高分辨率图片,但速度较慢

建议: 根据图片分辨率和性能需求选择,一般使用1024即可。

2. conf_thresh(置信度阈值)

  • 检测漏检时:降低阈值(0.3-0.4),检测更多区域
  • 误检多时:提高阈值(0.5-0.7),过滤低质量检测

建议: 默认0.4,根据实际效果调整。

3. nms_thresh(NMS阈值)

  • 重叠框多时:降低阈值(0.2-0.3),更严格地过滤
  • 正常情况:保持0.35

建议: 一般不需要调整,除非出现大量重叠检测框。

4. refine_mode(精炼模式)

  • OCR识别:使用REFINEMASK_INPAINT,生成更完整的mask
  • 可视化展示:使用REFINEMASK_ANNOTATION,保持原始结果

建议: 根据后续用途选择。

5. device(设备选择)

  • CPU:兼容性好,速度较慢
  • CUDA:需要GPU支持,速度显著提升(推荐)

建议: 有GPU时优先使用CUDA。

6. keep_undetected_mask(保留未检测区域)

  • True:保留更多区域,可能包含背景噪声
  • False:只保留检测到的区域,更干净

建议: 根据实际需求选择,一般OCR识别时设为True。

使用示例

完整示例代码

# -*- coding: utf-8 -*-
import sys
import cv2
import numpy as np
from pathlib import Path
from inference import TextDetector, REFINEMASK_ANNOTATION

# 初始化检测器
detector = TextDetector(
    model_path='data/comictextdetector.pt',
    input_size=1024,
    device='cuda' if torch.cuda.is_available() else 'cpu',
    act='leaky'
)

# 读取图片
image_path = 'example.jpg'
img_array = np.fromfile(image_path, dtype=np.uint8)
img = cv2.imdecode(img_array, cv2.IMREAD_COLOR)

# 执行检测
mask, mask_refined, blk_list = detector(
    img,
    refine_mode=REFINEMASK_ANNOTATION,
    keep_undetected_mask=True
)

# 处理结果
print(f"检测到 {len(blk_list)} 个文字区域")
for i, blk in enumerate(blk_list):
    print(f"文字块 {i+1}: {blk.xyxy}")

输出文件说明

1. Mask图片(_text_mask.png)

  • 格式:PNG灰度图
  • 内容:二值化的文字区域mask
  • 用途:用于后续的图像处理和OCR识别

2. 检测结果JSON(_text_detection.json)

{
  "image_file": "example.jpg",
  "image_size": {
    "width": 1334,
    "height": 1940
  },
  "text_blocks": [
    {
      "index": 1,
      "bbox": {
        "x1": 100,
        "y1": 200,
        "x2": 300,
        "y2": 250,
        "width": 200,
        "height": 50,
        "center_x": 200,
        "center_y": 225
      },
      "lines": [[[x1, y1], [x2, y2], ...]],
      "language": "ja",
      "vertical": false
    }
  ],
  "total_count": 1
}

常见问题

Q1: 检测不到某些文字区域?

解决方案:

  • 降低conf_thresh(如从0.4降到0.3)
  • 增大input_size(如从1024增到1536)
  • 设置keep_undetected_mask=True

Q2: 检测到太多误检区域?

解决方案:

  • 提高conf_thresh(如从0.4提高到0.5-0.6)
  • 降低nms_thresh(如从0.35降到0.3)

Q3: 处理速度太慢?

解决方案:

  • 减小input_size(如从1024减到512)
  • 使用GPU(设置device='cuda'
  • 使用ONNX模型(.onnx格式通常更快)

Q4: Mask边界不准确?

解决方案:

  • 使用REFINEMASK_INPAINT模式进行精炼
  • 增大input_size提高精度
  • 检查模型文件是否完整

技术原理

1. 检测架构

comic-text-detector 基于 YOLOv5 目标检测架构,专门针对漫画文字区域进行了优化训练。

2. 分割网络

使用语义分割网络生成精确的文字区域mask,支持不规则形状的文字区域。

3. 后处理流程

  1. NMS过滤:去除重叠的检测框
  2. 坐标映射:将模型输出坐标映射回原图尺寸
  3. Mask精炼:使用形态学操作和修复算法优化mask

4. 文字块分组

将检测到的边界框和分割轮廓进行分组,形成完整的文字块(TextBlock)对象。

参考资料

  • 项目地址:python/comic-text-detector-master/
  • 模型文件:data/comictextdetector.ptdata/comictextdetector.pt.onnx
  • 相关脚本:python/generate-anim/detect_comic_text_with_boxes.py

更新日志

  • 2024-XX-XX:初始版本,支持基本的文字区域检测和mask生成