尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

YOLOv11古籍上色实战:从目标检测到图像生成的全流程CV系统

YOLOv11古籍上色实战:从目标检测到图像生成的全流程CV系统 这次我们来看一个把 YOLOv11 用在古籍上色方向的完整 CV 系统项目。如果你已经学过深度学习但感觉自己还停留在“加载预训练权重、跑个 demo、看个效果”的阶段那么这个项目的价值点就很直接它帮你把目标检测、图像分割、图像上色、数据集构建、模型训练、批量推理、API 服务串成一条完整链路。做完之后你不是只“会调包”而是能说清楚一个 CV 系统从数据到部署的每一环。先说这个项目的核心特点以 YOLOv11 为基础模型针对古籍页面中的插画、人物、山水、花卉、文字标题等元素做检测或分割再基于检测结果把灰度线稿交给上色模型处理最终输出彩色还原效果。整个系统覆盖数据集标注、YOLOv11 训练、上色模型推理、结果合并、批量任务和接口封装。换句话说这不是一个“上传图片自动出结果”的玩具而是一个可以继续扩展的工程框架。这篇文章会带你拆解它的系统架构给出环境准备、数据准备、YOLOv11 训练、上色模型推理、API 批量调用、资源占用观察和问题排查的完整操作路线。适合已经学过深度学习基础、了解一些 YOLO 系列检测思路、想完成一个综合项目的读者。1. 核心能力速览能力项说明项目类型CV 完整系统目标检测/分割 图像上色 API 服务基础模型YOLOv11可选用 nano / small / medium 等规格主要功能古籍元素检测、线稿/灰度图上色、批量推理、接口调用检测任务对古籍插画、人物、山水、花鸟、印章、文字区域检测或分割上色任务基于灰度图或线稿生成彩色结果独立模块可替换推荐硬件GPU 显存 6G 起步8G 以上更稳妥检测训练可用 CPU 但很慢支持平台Windows / Linux有 NVIDIA GPU 时效果更好启动方式命令行 / Python 脚本 / FastAPI 接口 / 批处理脚本是否支持 API支持可封装检测和上色接口是否支持批量任务支持按目录批量处理是否支持 CPU检测部分支持上色部分 CPU 可跑但速度慢适合场景古籍数字化、文物图像修复学习、CV 综合项目实战、图像处理工具开发说明上表基于项目标题和常见实现思路整理具体显存占用和耗时需要以你的本机环境和模型规格为准。不同 YOLOv11 版本对显存和速度的影响很大后面我会给出一套可执行的验证流程。2. 适用场景与使用边界2.1 适用场景这个系统最适合的路线是“古籍图像数字化处理”。传统古籍扫描件包含线稿插图、钩勒人物、山水背景、界画楼阁、花鸟虫鱼等元素。人工上色和修复需要大量美术功底和时间算法能够先做辅助性还原。它也可以迁移到其他领域。比如书法字帖图像的文字区域检测、古建筑构件分类、旧照片检测与上色、手绘线稿自动上色等。因为主模型是 YOLOv11只要替换数据集和类别定义就能改变检测目标。2.2 使用边界与合规提醒先强调三点尤其是涉及古籍和文物图像的项目第一版权边界。不是所有“古籍扫描图”都可以随意使用。公有领域古籍可以自由研究但馆藏数字化成果、私人影印本、当代出版社排印整理本通常有版权。上色结果如果用于发布、商用或文创产品必须先确认图像来源和授权范围。第二历史真实性。古籍上色是辅助性修复不是考古定论。检测模型可能会漏检小面积印章或人物脸部上色模型也可能出现色彩偏移。对学术研究而言结果不能直接作为原始文献证据。第三隐私和数据安全。如果系统接入到真实馆藏平台图像素材可能涉及未公开文物资料。建议在离线环境运行不随便上传到第三方接口避免素材外泄。3. 系统架构设计从检测到上色的完整链路“完整 CV 系统”并不等于“跑通一个上色模型”。它的核心是把多个模型模块组装成可复用的流水线。3.1 整体流程输入古籍图像 - 预处理灰度化、尺寸统一、降噪 - YOLOv11 检测/分割定位插画区域、人物、文字等 - 裁剪目标区域 - 上色模型推理对灰度区域生成彩色结果 - 区域回填与融合边缘羽化避免生硬拼贴 - 输出彩色还原图 - 按目录批量保存 / 调用 API从工程视角看这个流程分为五个模块数据层图像采集、标注、数据集划分。检测层YOLOv11 训练和推理。上色层灰度图到彩色图的重建模型。集成层检测结果与上色结果合并处理重叠区域。部署层脚本批量任务、FastAPI 接口、日志和失败重试。3.2 模块解耦的好处检测模块和上色模块要分开训练。原因很实际两者解决的不是同一类问题。YOLOv11 负责“在哪里”上色模型负责“变成什么样”。如果耦合在一起单独优化任何一个模型都要重新训练整条链路。从项目实战角度看这种解耦也方便换模型。检测部分今天用 YOLOv11明天想换 RT-DETR只改检测模块上色部分想换成 DeOldify、U-Net 或扩散模型也不用动检测代码。这个设计思路比“一个脚本跑到底”更接近真实项目。4. 环境准备与前置条件4.1 基础环境清单建议按下面的清单准备环境版本不需要完全一致但尽量保持 Python 3.9 以上。组件建议配置说明操作系统Windows 10/11 或 Ubuntu 20.04/22.04教程命令以通用方式给出Python3.9 - 3.11避免过新版本造成依赖冲突GPUNVIDIA 显卡显存 8G 以上6G 也可训练 nano 模型CUDACUDA 11.8 / 12.1 左右以 PyTorch 官方支持为准磁盘预留 20G 以上数据集、权重、输出结果都需要空间内存16G 以上上色模型大图推理时内存占用明显4.2 创建虚拟环境强烈建议用虚拟环境不要直接装进全局 Python。否则项目依赖很容易互相污染。# 创建 Python 虚拟环境 python -m venv yolov11_color_env # 激活环境 # Windows: yolov11_color_env\Scripts\activate # Linux / macOS: source yolov11_color_env/bin/activate4.3 安装 PyTorch 与 UltralyticsPyTorch 需要根据你的电脑是否支持 CUDA 选择安装命令。先在命令行输入nvidia-smi查看驱动支持的 CUDA 版本再按 PyTorch 官网提供的安装命令安装。# CPU 版本不推荐训练调试可以用 pip install torch torchvision # GPU 版本示例实际命令以 PyTorch 官网为准 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121安装完成后安装 Ultralyticspip install ultralytics4.4 验证环境python -c import torch; print(torch.__version__); print(torch.cuda.is_available())如果输出True说明 PyTorch 能访问 GPU。如果输出False后面训练会退到 CPU速度会慢很多。4.5 安装上色模块依赖上色模型常用 PyTorch 生态一般需要安装pip install numpy opencv-python pillow fastapi uvicorn如果后续想用 U-Net 作为上色模型推荐用segmentation-models-pytorch库它封装了多种分割和生成架构pip install segmentation-models-pytorch5. 数据集准备古籍图像的标注与划分一个 CV 系统能不能用数据集比模型选择更关键。YOLOv11 需要我们提供一个格式标准的目标检测数据集。5.1 图像采集采集古籍图像时可以整理公开的公有领域古籍扫描图、自己拍摄/收藏的影印资料、或模拟的手绘线稿。建议每张图像提前做裁剪把无关的空白边缘去掉。5.2 类别设计古籍上色的检测类别建议按元素划分类别 id类别名说明0figure人物1landscape山水2flower花鸟植物3text文字区域4seal印章5building建筑/器物类别不要过多。如果某个类别样本量少于 50训练容易崩宁可先合并成“插画”类。检测任务追求的是给上色模型提供准确的候选框不需要把每一个细节都精确分类。5.3 标注工具推荐用 LabelImg 或 Label Studio。LabelImg 适合快速画矩形框Label Studio 支持矩形框、多边形分割和多标签更适合后续扩展。标注完成后会得到 PASCAL VOC 格式的 XML 文件需要转换为 YOLOv11 使用的 TXT 标签格式。YOLO 每行格式是class_id center_x center_y width height坐标都是归一化到 0-1 的相对坐标。例如0 0.535 0.672 0.134 0.187 2 0.220 0.345 0.089 0.145可以用 OpenCV 或 pycocotools 写一个转换脚本也可以直接用ultralytics.data.converter中的工具转换。更原始的方法是手写一个 XML 到 TXT 脚本这样能深入理解数据格式。5.4 数据集目录结构YOLOv11 训练时读取的目录结构建议如下dataset/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ └── labels/ ├── train/ ├── val/ └── test/同时需要一个 YAML 配置文件告诉 YOLOv11 数据路径和类别名称。# data.yaml path: ./dataset train: images/train val: images/val test: images/test names: 0: figure 1: landscape 2: flower 3: text 4: seal 5: building6. YOLOv11 检测模型训练6.1 选择模型规格YOLOv11 常见规格包括 yolo11n、yolo11s、yolo11m、yolo11l、yolo11x。数字越小速度越快精度相对越低数字越大精度上限越高显存占用和训练时间也越高。规格推荐显存适用场景yolo11n4G - 6G快速验证流程yolo11s6G - 8G大多数古籍检测场景yolo11m8G - 12G需要更高精度的场景yolo11l/x12G 以上学术精度验证第一次做这个项目先用 yolo11n 把流程跑通再决定是否需要升级规格。6.2 训练命令用 Ultralytics 官方 API 训练from ultralytics import YOLO # 加载预训练权重第一次会联网下载 model YOLO(yolo11n.pt) # 开始训练 results model.train( datadata.yaml, epochs100, imgsz640, batch16, device0, workers4, projectruns/detect, nameancient_book, )参数说明data数据集 YAML 路径。epochs训练轮数。如果数据集只有几百张先跑 50 轮看曲线再增加到 100 轮。imgsz输入图像尺寸。古籍插画细节多640 是折中选择。batch按显存调整。显存不足时降到 8 或 4。device显卡 id用 CPU 训练时填cpu。project和name训练结果保存路径。6.3 验证训练结果训练完成后检查runs/detect/ancient_book/目录下的results.png和confusion_matrix.png。重点看两个指标mAP50类别平均精确率目标检测最常用。mAP50-95更严格的检测标准数值会比 mAP50 低。第一次训练时如果 mAP50 低于 0.5不建议直接上色模型先增加数据或调整类别。6.4 模型推理测试from ultralytics import YOLO model YOLO(runs/detect/ancient_book/weights/best.pt) results model.predict( sourcetest_images/001.jpg, conf0.25, saveFalse, save_txtFalse, ) for r in results: boxes r.boxes print(boxes.xyxy) print(boxes.cls) print(boxes.conf)这段代码会输出每个检测框的坐标、类别和置信度。如果你在脚本里输出打印结果说明 YOLOv11 推理已经正常。7. 古籍上色模型U-Net 流程与调用7.1 上色模型的定位YOLOv11 只负责检测不能生成颜色。真正上色需要单独的图像生成模型。经典方案是用 U-Net 结构把灰度图作为输入输出彩色的 RGB 图。这里给出一个通用流程。实际训练上色模型需要大量黑白线稿和对应彩色图数据成本高。更快的落地方式有两种使用开源的预训练上色模型 Inference 代码比如 DeOldify 风格的模型。自己用少量配对数据微调一个轻量 U-Net。7.2 U-Net 上色模型推理示例以下代码是 U-Net 上色模块的简化示例使用segmentation-models-pytorch创建网络结构加载你自己的权重后做单张推理。import torch import cv2 import numpy as np import segmentation_models_pytorch as smp # 创建模型结构需要和训练时保持一致 model smp.Unet( encoder_nameresnet34, encoder_weightsNone, in_channels3, classes3, ) # 加载训练好的权重 state_dict torch.load(colorization_model.pth, map_locationcpu) model.load_state_dict(state_dict) model.eval() def colorize(image_path): # 读取灰度图 img cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # 转为三通道灰度图 img cv2.cvtColor(img, cv2.COLOR_GRAY2RGB) img cv2.resize(img, (512, 512)) input_tensor torch.from_numpy(img).float().permute(2, 0, 1) / 255.0 input_tensor input_tensor.unsqueeze(0) with torch.no_grad(): output model(input_tensor) output torch.clamp(output, 0.0, 1.0) output_img output.squeeze(0).permute(1, 2, 0).numpy() * 255.0 output_img output_img.astype(np.uint8) output_img cv2.cvtColor(output_img, cv2.COLOR_RGB2BGR) return output_img result colorize(test_images/detected_crop.jpg) cv2.imwrite(outputs/colorized_crop.jpg, result)7.3 系统集成把检测结果接入上色模型完整的流程不能只对整张图做上色应该先裁剪检测区域再对裁剪区域上色最后回填。from ultralytics import YOLO import cv2 import numpy as np det_model YOLO(runs/detect/ancient_book/weights/best.pt) def detect_and_colorize(image_path, output_path): image cv2.imread(image_path) results det_model.predict(sourceimage_path, conf0.25) for r in results: boxes r.boxes for i in range(len(boxes)): x1, y1, x2, y2 boxes.xyxy[i].cpu().numpy().astype(int) crop image[y1:y2, x1:x2] # 转灰度送入上色模型 gray cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY) gray_rgb cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB) colored colorize_from_array(gray_rgb) # 回填 colored_resized cv2.resize(colored, (x2 - x1, y2 - y1)) image[y1:y2, x1:x2] colored_resized cv2.imwrite(output_path, image) detect_and_colorize(test_images/001.jpg, outputs/final_001.jpg)这段代码的思路是主流程骨架。colorize_from_array函数需要把前面 U-Net 推理代码改成接收 numpy 数组并返回 numpy 数组。注意回填时如果检测框边缘太锐利可以用cv2.erode生成边缘 mask或采用羽化融合。否则彩色的裁剪块和周围原图边界会非常明显。8. 接口 API 与批量任务一个“完整 CV 系统”至少要提供本地批量处理脚本和接口服务两种使用方式。8.1 FastAPI 接口封装from fastapi import FastAPI, UploadFile, File from PIL import Image import io import numpy as np import cv2 app FastAPI() app.post(/detect) async def detect_image(file: UploadFile File(...)): image_bytes await file.read() nparr np.frombuffer(image_bytes, np.uint8) image cv2.imdecode(nparr, cv2.IMREAD_COLOR) results det_model.predict(sourceimage, conf0.25) detections [] for r in results: boxes r.boxes for i in range(len(boxes)): x1, y1, x2, y2 boxes.xyxy[i].cpu().numpy().astype(int) detections.append({ bbox: [int(x1), int(y1), int(x2), int(y2)], class: int(boxes.cls[i]), confidence: float(boxes.conf[i]), }) return {detections: detections} app.post(/colorize) async def colorize_image(file: UploadFile File(...)): image_bytes await file.read() nparr np.frombuffer(image_bytes, np.uint8) image cv2.imdecode(nparr, cv2.IMREAD_COLOR) gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray_rgb cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB) colorized colorize_from_array(gray_rgb) success, encoded cv2.imencode(.jpg, colorized) return Response(contentencoded.tobytes(), media_typeimage/jpeg)启动服务# 需要先把 det_model 和 colorize_from_array 导入 uvicorn api_server:app --host 0.0.0.0 --port 8000注意det_model和colorize_from_array需要在上面的示例代码中提前定义。接口服务只暴露在局域网或本机调试时建议绑定127.0.0.1不要直接暴露到公网。8.2 curl 调用示例启动服务后可以用 curl 测试接口# 检测接口 curl -X POST http://127.0.0.1:8000/detect \ -F filetest_images/001.jpg # 上色接口 curl -X POST http://127.0.0.1:8000/colorize \ -F filetest_images/crop.jpg \ -o outputs/colorized.jpg返回后检查colorized.jpg是否能正常打开这是判断接口是否可用的最直接标准。8.3 Python 调用示例import requests # 检测 resp requests.post( http://127.0.0.1:8000/detect, files{file: open(test_images/001.jpg, rb)}, timeout30, ) print(resp.json()) # 上色 resp requests.post( http://127.0.0.1:8000/colorize, files{file: open(test_images/crop.jpg, rb)}, timeout60, ) with open(outputs/api_colorized.jpg, wb) as f: f.write(resp.content)8.4 批量任务脚本批量处理的核心是维护一个待处理队列并记录日志。简单场景可以用目录扫描。import os import time from pathlib import Path input_dir Path(./batch_input) output_dir Path(./batch_output) output_dir.mkdir(exist_okTrue) for image_path in input_dir.glob(*.jpg): start_time time.time() try: detect_and_colorize(str(image_path), str(output_dir / image_path.name)) elapsed time.time() - start_time print(f[OK] {image_path.name} 耗时 {elapsed:.2f}s) except Exception as e: print(f[FAIL] {image_path.name} 错误: {e})如果需要更稳定把失败列表写入一个failed.txt批量结束后统一重试。9. 资源占用与性能观察9.1 显存占用观察方法训练时用nvidia-smi实时观察nvidia-smi -l 2推理时也在另一个终端运行nvidia-smi重点看Memory-Usage列。如果显存满了降低 batch、imgsz、或换更小的模型。9.2 影响性能的因素输入图像尺寸imgsz640 和 1280 的显存差距接近 4 倍。上色模型分辨率512x512 的 U-Net 比 1024x1024 快很多。检测框数量图片中检测到超过 20 个目标时裁剪和上色循环会明显变慢。推理设备CPU 上色一张需要几十秒到几分钟GPU 上色通常只需要几秒到十几秒。具体数值由显卡和模型共同决定。9.3 如何减少显存占用训练检测模型时把 batch 从 16 降到 8。推理时只保留检测模型权重不保留训练器状态。上色模型先用 256x256 测试稳定后再提高到 512x512。大批量处理时逐张推理不要一次性把整个目录读进内存。9.4 端口占用与进程残留FastAPI 启动后如果端口被占用服务会直接报错。可以先查端口# Linux / macOS lsof -i :8000 # Windows netstat -ano | findstr :8000如果发现占用进程不是自己的就换端口启动uvicorn api_server:app --host 127.0.0.1 --port 800110. 常见问题与排查方法问题现象可能原因排查方式解决方案安装 ultralytics 失败依赖冲突或 Python 版本过旧查看 pip 报错升级 Python 到 3.9-3.11重新创建虚拟环境torch.cuda.is_available() 返回 False显卡驱动或 PyTorch 版本不匹配运行nvidia-smi和python -c import torch; print(torch.__version__)按官方命令重装对应 CUDA 版本的 PyTorch训练时显存溢出batch 过大或 imgsz 过大看训练日志OutOfMemoryError降低 batch降低 imgsz减小模型规格模型训练 mAP 很低数据集样本太少或类别不平衡查看 confusion_matrix 和每个类别的样本数增加样本合并类别或使用预训练权重继续微调检测框漏掉小目标印章、小文字尺寸太小查看原始图像和检测结果缩放比例提高 imgsz 到 1280或使用更大的模型规格上色结果出现色斑上色模型分辨率不够或训练数据风格单一对比不同输入尺寸的上色结果提高推理分辨率加入更多灰度线稿样本微调回填后边缘明显检测框裁剪区域和原图融合生硬检查输出图边界使用羽化 mask 或边缘模糊处理API 调用超时上色模型推理耗时过长查看服务日志和耗时提高 timeout或把接口改为异步任务队列批量任务卡住单张图片处理异常循环不退出查看控制台是否有异常被吞掉增加 try/except 和失败列表跳过坏图端口被占用其他进程占用同一端口用 netstat/lsof 查询换端口或杀掉占用进程输出目录没有结果输入路径写错或检测置信度过高打印 image_path 和检测结果数量检查目录权限和 conf 阈值11. 最佳实践与工程建议11.1 先小后大不要一上来就用大模型训 300 轮。先用 yolo11n 50 张图 20 轮把整个链路跑通确认数据格式、训练流程、上色回填逻辑没问题再扩展数据量。11.2 保留一份最小可用配置项目目录建议固定成标准结构project/ ├── config/ │ └── data.yaml ├── dataset/ │ ├── images/ │ └── labels/ ├── weights/ │ ├── yolo11n.pt │ └── colorization_model.pth ├── scripts/ │ ├── train_det.py │ ├── detect.py │ ├── colorize.py │ └── pipeline.py ├── batch_input/ ├── batch_output/ └── api_server.py这样换机器、换环境时能快速恢复不用到处找文件。11.3 日志和数据版本管理批量处理时建议每个图片记录一行日志包含文件名、耗时、检测目标数、是否成功。上色效果有波动最好把输入输出文件名映射保存下来方便回溯。11.4 合规与伦理前面提过古籍图像来源一定要确认授权。这里再补充一点如果涉及到人物面部、近现代人物照片或私人藏品必须确保肖像权和隐私权没有问题。这个项目虽然是技术学习但不要拿它做未经授权的盈利工具。12. 总结与下一步这个项目最值得尝试的点是它把深度学习学习中最容易断裂的几块补上了数据处理格式、检测模型训练、上色模型推理、系统集成和接口封装。你做完这一套之后再回头看那些“调包跑 demo”的痛点就会意识到真正重要的是把模块之间的数据流串起来。如果你现在准备动手先不要急着收集大量古籍图片。第一步先拿 10 张图标注 20 个检测框用 yolo11n 跑 5 轮把训练到推理的流程走通。第二步再优化上色模型。第三步才是上 API 和批处理。最容易踩的坑有两个一是数据集标注格式不一致导致训练时报错二是检测回填上色后边缘生硬看起来像贴纸。这两个问题几乎每个上手的人都会遇到建议提前预留时间处理。后续可以扩展的方向很多把 YOLOv11 检测换成实例分割模型让上色区域更精细用扩散模型替代 U-Net 提升上色质感加入批量任务队列用 Redis 或简单文件队列管理任务状态还可以接入更多的古籍字体识别模块把文字区域单独走 OCR 流程。从“调包跑 demo”到“自己做完整系统”区别不在于模型多先进而在于你能否控制数据、训练、推理、接口、部署每一个环节。这个 YOLOv11 古籍上色项目正好给了你一条完整的线索建议收藏备用。
返回列表