news 2026/6/23 21:38:37

【程序干货】YOLO 预测检测结果不顺心?手把手教你自定义“红框白字”专业视觉效果(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【程序干货】YOLO 预测检测结果不顺心?手把手教你自定义“红框白字”专业视觉效果(附完整代码)

目录

0. 前言——为什么需要自定义可视化?

1. 核心功能点

2. 技术细节:如何实现“红底白字”?

3. 完整代码实现

4. 使用说明

5. 总结


0. 前言——为什么需要自定义可视化?

在使用 Ultralytics YOLO(v8/v9/v10/v11)进行目标检测时,我们通常直接调用 model.predict(save=True)。虽然官方自带的可视化很方便,但它会根据不同的类别分配不同的颜色。

在某些学术论文、工业报告特定演示场景下,我们往往需要更统一、更专业的视觉风格——例如:亮红色的检测框、红色的标签背景,搭配纯白色的文字

今天分享一个实用的 Python 脚本,直接绕过官方 UI,利用OpenCV重新绘制:红色边框、红色标签底、纯白文字。让你的检测结果图瞬间达到出版级水准!

1. 核心功能点

  1. 极简视觉风格:统一采用“红框 + 红底 + 白字”,重点突出,风格专业。

  2. 双重输出:既生成自定义样式的图片,也支持同步保存标准 YOLO 格式的 .txt 标签。

  3. 坐标精准处理:自动处理标签背景框越界问题(当物体在图片顶部时,标签会自动调整位置)。

  4. 参数化配置:支持通过命令行调整置信度、框粗细、字体大小等。


2. 技术细节:如何实现“红底白字”?

官方的 plot() 函数高度封装,难以精细修改颜色逻辑。本脚本通过以下逻辑实现:

  • 提取结果:利用 result.boxes 获取坐标、类别和置信度。

  • OpenCV 绘制

    • cv2.rectangle:画出红色(BGR: 0, 0, 255)的边框。

    • cv2.getTextSize:计算文字宽度,动态生成背景红色矩形。

    • cv2.putText:在红色背景上叠写白色文字。

3. 完整代码实现

您可以直接将以下代码保存为 custom_predict.py 并运行。

import argparse import os import warnings import cv2 from ultralytics import YOLO warnings.filterwarnings("ignore") def save_txt_yolo_format(result, img_w, img_h, txt_path, save_conf=True): """ 保存 YOLO 格式标签: class x_center y_center w h [conf] 归一化到 0~1 """ lines = [] if result.boxes is None or len(result.boxes) == 0: open(txt_path, "w").close() return boxes_xyxy = result.boxes.xyxy.cpu().numpy() clss = result.boxes.cls.cpu().numpy().astype(int) confs = result.boxes.conf.cpu().numpy() if result.boxes.conf is not None else None for i, (x1, y1, x2, y2) in enumerate(boxes_xyxy): x1, y1, x2, y2 = float(x1), float(y1), float(x2), float(y2) xc = (x1 + x2) / 2.0 / img_w yc = (y1 + y2) / 2.0 / img_h bw = (x2 - x1) / img_w bh = (y2 - y1) / img_h if save_conf and confs is not None: lines.append(f"{clss[i]} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f} {confs[i]:.6f}") else: lines.append(f"{clss[i]} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}") with open(txt_path, "w") as f: f.write("\n".join(lines)) def draw_red_box_red_bg_white_text(results, out_dir, save_txt=False, save_conf=True, line_thickness=2, font_scale=0.6): """ 框=红、标签底=红、文字=白色(类别+置信度) """ os.makedirs(out_dir, exist_ok=True) labels_dir = os.path.join(out_dir, "labels") if save_txt: os.makedirs(labels_dir, exist_ok=True) red = (0, 0, 255) # BGR 红色 white = (255, 255, 255) # BGR 白色 for r in results: img_path = r.path img = cv2.imread(img_path) if img is None: print(f"⚠️ 读图失败: {img_path}") continue h, w = img.shape[:2] names = r.names # dict: class_id -> class_name # 保存 txt if save_txt: base = os.path.splitext(os.path.basename(img_path))[0] txt_path = os.path.join(labels_dir, base + ".txt") save_txt_yolo_format(r, w, h, txt_path, save_conf=save_conf) # 画框 + 标签 if r.boxes is not None and len(r.boxes) > 0: boxes = r.boxes.xyxy.cpu().numpy() confs = r.boxes.conf.cpu().numpy() if r.boxes.conf is not None else None clss = r.boxes.cls.cpu().numpy().astype(int) if r.boxes.cls is not None else None for i, (x1, y1, x2, y2) in enumerate(boxes): x1, y1, x2, y2 = map(int, [x1, y1, x2, y2]) # 红框 cv2.rectangle(img, (x1, y1), (x2, y2), red, line_thickness) # 标签文本:class + conf label = "" if clss is not None: label += names.get(int(clss[i]), str(int(clss[i]))) if save_conf and confs is not None: label += f" {confs[i]:.2f}" if label.strip(): (tw, th), baseline = cv2.getTextSize( label, cv2.FONT_HERSHEY_SIMPLEX, font_scale, 2 ) # 标签放在框上方,避免越界;放不下就顶到0 y_top = max(0, y1 - th - baseline - 6) # 标签背景:红色 cv2.rectangle( img, (x1, y_top), (x1 + tw + 6, y1), red, -1 ) # 标签文字:白色 cv2.putText( img, label, (x1 + 3, y1 - 4), cv2.FONT_HERSHEY_SIMPLEX, font_scale, white, 2, cv2.LINE_AA ) save_path = os.path.join(out_dir, os.path.basename(img_path)) cv2.imwrite(save_path, img) def main(opt): model = YOLO(opt.weights) print(f"🔍 开始预测:{opt.source}") print(f"✅ 权重:{opt.weights}") # 预测:关闭官方保存,自己画(才能控颜色) results = model.predict( source=opt.source, imgsz=opt.img_size, device=opt.device, conf=opt.conf, save=False, verbose=False ) out_dir = os.path.join(opt.project, opt.name) draw_red_box_red_bg_white_text( results, out_dir=out_dir, save_txt=opt.save_txt, save_conf=True, line_thickness=opt.thickness, font_scale=opt.font_scale ) print(f"✅ 完成(红框+红底+白字),输出目录:{out_dir}") if opt.save_txt: print(f"✅ txt 已保存到:{os.path.join(out_dir, 'labels')}") if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( "--weights", type=str, default="/root/autodl-tmp/ultralytics-main/runs/detect/train3/weights/best.pt", help="model weight path" ) parser.add_argument( "--source", type=str, default="/root/autodl-tmp/ultralytics-main/images", help="image dir or image file" ) parser.add_argument("--img_size", type=int, default=640, help="image size") parser.add_argument("--device", type=str, default="0", help="cuda device") parser.add_argument("--conf", type=float, default=0.25, help="confidence threshold") parser.add_argument("--project", type=str, default="runs/predict", help="save root dir") parser.add_argument("--name", type=str, default="train1_pred", help="save sub dir name") parser.add_argument("--save_txt", action="store_true", help="save yolo txt labels") parser.add_argument("--thickness", type=int, default=2, help="box line thickness") parser.add_argument("--font_scale", type=float, default=0.6, help="label font scale") opt = parser.parse_args() main(opt)

4. 使用说明

1. 基础预测:

codeBash

downloadcontent_copy

expand_less

python custom_predict.py --weights ./runs/train/best.pt --source ./data/test_images

2. 调整线条粗细与字体(适合高分辨率图):

codeBash

downloadcontent_copy

expand_less

python custom_predict.py --weights best.pt --source ./images --thickness 4 --font_scale 0.8

3. 同时生成标签文件(用于辅助标注):

codeBash

downloadcontent_copy

expand_less

python custom_predict.py --weights best.pt --source ./images --save_txt

5. 总结

通过简单的 OpenCV 二次开发,我们可以轻松突破 YOLO 官方库的可视化限制。这种红底白字的风格不仅统一了视觉语言,更在复杂背景下提供了极佳的辨识度。

如果你觉得这个脚本有用,欢迎点赞、收藏,并关注我的 CSDN 账号,获取更多深度学习实用工具!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 16:59:45

面向工业控制的模拟电子技术基础入门必看指南

面向工业控制的模拟电子技术入门:从传感器到执行器的完整信号链解析在智能制造与工业4.0浪潮席卷全球的今天,自动化系统正变得越来越“聪明”。然而,再先进的PLC、再强大的边缘AI处理器,如果无法准确感知物理世界的变化——温度漂…

作者头像 李华
网站建设 2026/6/23 1:45:58

65、利用组策略管理硬件访问与打印机分配全攻略

利用组策略管理硬件访问与打印机分配全攻略 1. 组策略中硬件禁用与启用选项的缘由 在组策略里,设备扩展项有禁用和启用两个选项。借助组策略对象(GPO)过滤或组策略首选项扩展的项目级别目标设定,就能灵活决定谁的哪些硬件该启用,哪些该禁用。比如,除了实验室技术员需要…

作者头像 李华
网站建设 2026/6/23 17:03:33

f1系列替换下载失败

在 STM32F1 系列中, startup_stm32f10xxx_ld.s 、 startup_stm32f10xxx_md.s 、 startup_stm32f10xxx_hd.s 这几个启动文件的区别主要在于 芯片的 Flash 容量(密度),不同密度的芯片对应不同的启动文件。- ld (Low-de…

作者头像 李华
网站建设 2026/6/23 16:54:12

LangFlow内置模板库发布,涵盖常见AI应用场景

LangFlow 内置模板库发布,开启AI应用可视化开发新纪元 在大模型技术席卷各行各业的今天,越来越多团队希望快速构建智能问答、文档处理、自动化代理等AI系统。然而现实是:即便有了LangChain这样强大的框架,开发者仍需面对复杂的API…

作者头像 李华
网站建设 2026/6/23 12:34:57

Centos7安装Maven环境

1、使用yum(CentOS 7及更早版本) 添加EPEL仓库‌(如果尚未添加) sudo yum install epel-release‌安装Maven sudo yum install maven2、下载并手动安装(适用于所有版本的CentOS) 访问Maven官网 https://mav…

作者头像 李华
网站建设 2026/6/23 17:02:24

【Arbess】1、安装Arbess

1、关于Arbess Arbess包含流水线管理、流水线设计、流水线执行、测试报告、统计分析等模块,支持串行并行可视化设计方式,支持丰富多样的任务类型,支持分布式执行流水线,界面操作简洁明了、开源免费。 2、安装Arbess 官方安装文…

作者头像 李华