【道友避坑】Yolov5给标签编号显示

文章描述了在使用Yolov5进行目标检测时,如何处理一张图片中相同标签重复出现的问题。作者提出了通过添加计数器为每个标签生成唯一的标识,如person-01,person-02等,以便于前端数据匹配和展示。解决方案是在detect.py文件中修改代码,使用defaultdict来跟踪每个标签的计数,并使用cv2.putText在图片上绘制带有编号的标签。
摘要由CSDN通过智能技术生成

写在前面:最近在做yolov5封装成一个接口,然后将数据提供给前端展示。在展示的时候一张照片里可能有多个相同的标签,这样数据就不好进行匹配,所以针对这个问题,下面将会详细描述。

目录

一、问题详情

二、解决办法

三、解决过程


一、问题详情

检测图片如下,前端需要:检测图片+额外数据

如果是下图,那么生成的数据为:{'image1':['person':0.59,'person':0.88,'tie':0.66,'tie':029]}

如果你对返回的数据进行修改:{'image1':['person-01':0.59,'person-02':0.88,'tie-01':0.66,'tie-02':029]},那么这样和图片就不对应了!!!

二、解决办法

图片输出效果如下,给前端返回数据结果为,这样就一一对应了:

{'image1':['person-01':0.59,'person-02':0.88,'tie-01':0.66,'tie-02':029]}

我的解决思路请看第三部分,如果还想进行更多的图片操作,我感觉这篇博客可以为你打开思路:

yolov5/v7修改标签和检测框显示【最全】icon-default.png?t=N7T8https://blog.csdn.net/dal1223/article/details/126727191?spm=1001.2014.3001.8078#comments_27293002

 三、解决过程

可以为每一个特定的标签添加一个计数器,并在每次遇到该标签时,都更新这个计数器。修改代码的地点在delect.py中的if save_img or save_crop or view_img:部分。

label_counter是一个defaultdict,当我们尝试访问一个不存在的键时,它会返回0,并创建一个新的键。因此,label_counter[label_name] += 1会将对应标签的计数器加一,即使这是第一次遇到这个标签。

然后,我们用f'{label_name}-{label_counter[label_name]:02d}'生成了标签和编号。:02d表示我们想要一个至少两位数的整数,如果数字不足两位,则用0填充。所以1会变成012会变成02,依此类推。

# 增加对应的计数器
label_counter[label_name] += 1
label = None if hide_labels else (f'{label_name}-{label_counter[label_name]:02d}' if hide_conf else f'{label_name}-{label_counter[label_name]:02d} {conf:.2f}')

这样就可以是不是对计数的原理有所了解了,接下来就是改变图片上的label,这里使用opencv。

x1, y1, x2, y2 = map(int, xyxy) # 转换为整数类型
cv2.putText(im0s, label, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)

使用cv2.putText()在图片上绘制文本。它的参数是:图片,文本,文本的左下角的位置,字体,字体的大小,颜色,线条的宽度。

注意:xyxy是一个包含了矩形框的四个坐标的列表,[x1, y1, x2, y2]。你可能需要根据你的具体情况来决定标签的位置。在这个示例中,默认标签放在矩形框的左上角。

还有就是,需要对xyxy进行类型转换,在OpenCV中,图像的坐标是以整数表示的,但是xyxy中的坐标可能是浮点数,因此需要将它们转换为整数。要不然你可能会遇到这个问题:

Traceback (most recent call last):
  File "D:\python\item\bird_identification\birds_app\demo.py", line 35, in <module>
    print(f"测试输出:{detector.detect()}")
  File "D:\python\item\bird_identification\birds_app\yolov5_master\detect.py", line 280, in detect
    run(self.weights, self.source, self.data, self.imgsz, self.conf_thres,
  File "C:\Users\liuyu\AppData\Roaming\Python\Python39\site-packages\torch\utils\_contextlib.py", line 115, in decorate_context
    return func(*args, **kwargs)
  File "D:\python\item\bird_identification\birds_app\yolov5_master\detect.py", line 150, in run
    cv2.putText(im0s, label, (xyxy[0], xyxy[1] - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
cv2.error: OpenCV(4.5.5) :-1: error: (-5:Bad argument) in function 'putText'
> Overload resolution failed:
>  - Can't parse 'org'. Sequence item with index 0 has a wrong type
>  - Can't parse 'org'. Sequence item with index 0 has a wrong type

 完整代码如下

#导包
from collections import defaultdict

#定义一个收集的集合
detected_objects = {}

@smart_inference_mode()
def run(
        weights=ROOT / 'yolov5s.pt',  # model path or triton URL
        source=ROOT / 'data/images',  # file/dir/URL/glob/screen/0(webcam)
        data=ROOT / 'data/coco128.yaml',  # dataset.yaml path
        imgsz=(640, 640),  # inference size (height, width)
#省略源代码。。。。。
                detected_objects[path] = []
                label_counter = defaultdict(int)
                # Write results
                for *xyxy, conf, cls in reversed(det):

                    if save_txt:  # Write to file
                        xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh
                        line = (cls, *xywh, conf) if save_conf else (cls, *xywh)  # label format
                        with open(f'{txt_path}.txt', 'a') as f:
                            f.write(('%g ' * len(line)).rstrip() % line + '\n')

                    if save_img or save_crop or view_img:  # Add bbox to image
                        c = int(cls)  # integer class
                        # label = None if hide_labels else (names[c] if hide_conf else f'{names[c]} {conf:.2f}')
                        label_name = names[c]
                        # 增加对应的计数器
                        label_counter[label_name] += 1
                        label = None if hide_labels else (
                            f'{label_name}-{label_counter[label_name]:02d}' if hide_conf else f'{label_name}-{label_counter[label_name]:02d} {conf:.2f}')
                        # 在图片上绘制标签和编号
                        x1, y1, x2, y2 = map(int, xyxy)
                        cv2.putText(im0s, label, (x1, y1 - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)
                        annotator.box_label(xyxy, label, color=colors(c, True))
                        detected_objects[path].append(label)
                    if save_crop:
                        save_one_box(xyxy, imc, file=save_dir / 'crops' / names[c] / f'{p.stem}.jpg', BGR=True)

# 省略源代码。。。

项目内代码展示:

PS:我用的是yolov5-6版本的!本文主要介绍的是标签编号,至于封装部署有空再慢慢更新吧!打工人没啥更新的动力了,要是更了,你可以看看我的yolo专栏。哈哈,在此记录一下心得!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记录菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值