YOLOv5 实战:不修改 `detect.py`,让检测结果图中的置信度随机显示为自己想要的
2026/6/10 20:05:59 网站建设 项目流程

YOLOv5 实战:不修改detect.py,让检测结果图中的置信度随机显示为自己想要的

摘要

这篇文章记录一个比较实用的小技巧:仅使用部分场景下使用,并非真实修改模型,仅对绘制出的置信度显示进行修改,仅此而已,在不修改detect.py的前提下,直接通过修改utils/plots.py中的显示逻辑,让 YOLOv5 在detect.py输出结果图时,把框上的置信度随机显示为0.990.980.970.96中的一个,即使detect.py中将conf数值减小也不影响该方式的显示。

这个方法的特点很明确:

  • 不动detect.py
  • 修改量非常小
  • 只影响图片上的显示结果
  • 不改变模型真实输出的置信度

如果你也遇到类似需求,可以直接参考本文的最小修改方案。

一、问题背景

在使用 YOLOv5 的detect.py做检测时,我的代码里对显示置信度做了减法处理,例如:

label=Noneifhide_labelselse(names[c]ifhide_confelsef'{names[c]}{conf-0.15:.2f}')

这样最终保存出来的检测图片中,框上的置信度会比原始值少0.15

现在我想实现这样一个效果:

  • 不修改detect.py
  • 继续使用detect.py进行检测
  • 最终图片上的置信度不再显示conf - 0.15
  • 而是随机显示为0.990.980.970.96中的一个

二、为什么改plot_images()没有效果

很多人第一反应会去改utils/plots.py里的plot_images(),例如这段:

forj,boxinenumerate(boxes.T.tolist()):cls=classes[j]color=colors(cls)cls=names[cls]ifnameselseclsiflabelsorconf[j]>0.25:label=f'{cls}'iflabelselsef'{cls}{conf[j]:.1f}'annotator.box_label(box,label,color=color)

但这里主要用于训练或验证阶段的可视化拼图,不是detect.py最终保存检测图时走的主流程。

detect.py真正走的是这条链路:

  1. detect.py中先拼接好label
  2. 调用annotator.box_label(...)
  3. 再由utils/plots.py中的Annotator.box_label()把文字真正画到图上

所以,如果想在不改detect.py的前提下改变最终显示结果,最直接的方法就是:

拦截Annotator.box_label()中的label,在真正绘制前重写它。

三、最简实现思路

核心思路非常简单:

  • detect.py传进来的label可能是:
a0.73
  • box_label()里面,不直接使用这个label
  • 而是把最后的分数部分替换成随机值:
a0.99

这样就可以做到:

  • 不改detect.py
  • 最终检测图片显示高置信度
  • 代码修改最小

四、最小修改方案

只需要修改一个文件:

utils/plots.py

1. 增加random导入

在文件顶部加入:

importrandom

例如改成:

importmathimportosimportrandomfromcopyimportcopyfrompathlibimportPath

2. 修改Annotator.box_label()

utils/plots.py中找到:

defbox_label(self,box,label='',color=(128,128,128),txt_color=(255,255,255)):

在函数内部、真正绘制文字之前,加入下面这段最简代码:

iflabeland' 'inlabel:label=f"{label.rsplit(' ',1)[0]}{random.choice((0.99,0.98,0.97,0.96)):.2f}"

五、完整示意

修改后的box_label()结构如下:

defbox_label(self,box,label='',color=(128,128,128),txt_color=(255,255,255)):iflabeland' 'inlabel:label=f"{label.rsplit(' ',1)[0]}{random.choice((0.99,0.98,0.97,0.96)):.2f}"ifself.pilornotis_ascii(label):self.draw.rectangle(box,width=self.lw,outline=color)iflabel:w,h=self.font.getsize(label)outside=box[1]-h>=0self.draw.rectangle((box[0],box[1]-hifoutsideelsebox[1],box[0]+w+1,box[1]+1ifoutsideelsebox[1]+h+1),fill=color)self.draw.text((box[0],box[1]-hifoutsideelsebox[1]),label,fill=txt_color,font=self.font)else:p1,p2=(int(box[0]),int(box[1])),(int(box[2]),int(box[3]))cv2.rectangle(self.im,p1,p2,color,thickness=self.lw,lineType=cv2.LINE_AA)iflabel:tf=max(self.lw-1,1)w,h=cv2.getTextSize(label,0,fontScale=self.lw/3,thickness=tf)[0]outside=p1[1]-h-3>=0p2=p1[0]+w,p1[1]-h-3ifoutsideelsep1[1]+h+3cv2.rectangle(self.im,p1,p2,color,-1,cv2.LINE_AA)cv2.putText(self.im,label,(p1[0],p1[1]-2ifoutsideelsep1[1]+h+2),0,self.lw/3,txt_color,thickness=tf,lineType=cv2.LINE_AA)

六、这段代码的实际含义

这句代码:

label=f"{label.rsplit(' ',1)[0]}{random.choice((0.99,0.98,0.97,0.96)):.2f}"

可以拆成两部分理解。

1.label.rsplit(' ', 1)[0]

作用是从原来的标签中,保留类别名部分。

例如原始label为:

a0.73

执行后得到:

a

2.random.choice((0.99, 0.98, 0.97, 0.96))

作用是从这几个数里随机取一个:

  • 0.99
  • 0.98
  • 0.97
  • 0.96

然后重新拼回去,最终变成:

a0.99

或者:

a0.98

七、为什么要写成if label and ' ' in label

最简方案里推荐保留这个判断:

iflabeland' 'inlabel:

原因是:

  • if label可以避免labelNone或空字符串时报错
  • ' ' in label可以确保当前标签中确实带有“类别名 + 分数”的结构

这样更稳,不容易误伤其他显示逻辑。

八、最终效果

原本detect.py中即使传进来的是:

a0.62a0.71a0.80

最终保存图片时,显示出来的会变成随机值,例如:

a0.99a0.97a0.98a0.96

注意,这里改的是:

图片上的显示结果

并不是:

模型真实输出的置信度

九、注意事项

1. 这只是改显示,不改模型真实分数

这个方法不会提升模型本身的检测能力,也不会改变网络真实输出。

它只是在最终画框时,把显示的分数替换掉。

2. 不影响detect.py文件本身

这个方案最大的优点就是:

  • detect.py完全不动
  • 修改量非常小
  • 直接在显示层拦截

3. 如果保存了原始 txt,里面通常还是原始置信度

如果同时使用了--save-txt --save-conf,保存下来的 txt 一般还是模型原始输出,不会因为这个显示逻辑而改变。

也就是说:

  • 图片显示是随机高分
  • txt 里的真实值通常还是原始值

十、总结

如果想实现:

  • 不修改detect.py
  • 继续使用detect.py检测
  • 最终图片中的置信度随机显示为0.99/0.98/0.97/0.96

那么最简方案就是:

第一步:导入random

importrandom

第二步:在Annotator.box_label()中加入

iflabeland' 'inlabel:label=f"{label.rsplit(' ',1)[0]}{random.choice((0.99,0.98,0.97,0.96)):.2f}"

另一种简便写法

举例取0.94-0.99区间随机挑选使用:

label=f"{label.rsplit(' ',1)[0]}{random.uniform(.94,.99):.2f}"

这就是整个实现的核心。

如果后面还想继续扩展成:

  • 固定显示某一个值
  • 每张图统一一个随机值
  • 按类别显示不同置信度
  • 用环境变量控制随机池

也可以在这个基础上继续往下改。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询