如何快速为YOLO准备标注好的图像样本库

1. YOLO目标检测

    YOLO是时下工业界用的比较多的视觉目标检测算法,特别是YOLOv5有专门的团队维护,提供了从小s到大l到巨x各种预训练模型文件,并且为使用者提供了近乎傻瓜式的train和detect,是非常良心的github项目。不过,YOLOv5要求提供满足格式要求的标注图像样本,具体而言:

1. 要求提供yaml文件,来描述样本图片的路径,样本的类别数量,以及每种类别的含义;

2. 样本图片和每张图片同名txt标准文件,文件的每行为(详见官方文档中的 Or manually prepare your dataset (click to expand) 记得点开):

class x_center y_center width heigh

    关于YOLOv5如何跑自己的数据集,B站up主做了详细讲解。只不过,在图片上面一个一个去框选标注有些费力,或许可以试试通过视频文件自动生成标注图片?

2. 通过视频生成标注样本库的思路

    假设我们的被检测对象是一个物体,我们对这类物体录制了多段视频,那如果我们能通过先验知识+图像处理手段从视频中找出该物体的x,y,w,h,不就能生成标注文件了么?30帧的视频1分钟就是1800张图片啊,并且还有丰富的动态特性!下面就是如何找出视频中物体的边框了,这就要通过opencv的findContours了。

3. opencv找出物体轮廓

    findContours是opencv十分强大的函数,普通图片经过高斯滤噪、色彩过滤等预处理后,就可以找到轮廓了。一次会得到不止一个轮廓,这时候就要预先给定物体出现的区域中心点位置,然后把包含这个中心点的轮廓作为样本轮廓,然后调用cv2.contourArea(contour)得到轮廓的x,y,w,h,简单吧。

4.用x,y,w,h生成YOLOv5标注

    前面提的B站up主提供了一段代码来做转换convert,无非就是除以长宽得到相对坐标,再用x=x+w/2,y=y+h/2 得到中心点坐标,最后合并得到 class centerx centery width height 这样一条标注信息,写入到txt文件。

5. 例子代码

    下面这段代码在dataset\flame2\images下生成图片,在dataset\flame2\labels下生成对应的标注文件。由于是单类对象检测问题,class只有一个,所以标注只有一行,且class=0。

import cv2
import numpy as np


def convert(dw, dh, x, y, w, h):
    x += w/2.0
    y += h/2.0
    x = x*dw
    w = w*dw
    y = y*dh
    h = h*dh
    return f'0 {x} {y} {w} {h}'


videoname = 'flame2'
cap = cv2.VideoCapture(videoname+'.mp4')
success, frame = cap.read()
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
dh = 1.0/height
dw = 1.0/width

centerx, centery = 585, 231
lower_bound = np.array([0, 0, 175])
upper_bound = np.array([360, 120, 249])
imagepath = f'dataset\\{videoname}\\images\\'
labelpath = f'dataset\\{videoname}\\labels\\'
frameindex = 0
stat = {}
while success:
    blur = cv2.GaussianBlur(frame, (3, 3), 0)
    frame_hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
    frame_copy = cv2.inRange(frame_hsv, lower_bound, upper_bound)
    contours, hier = cv2.findContours(frame_copy, cv2.RETR_EXTERNAL,
                                      cv2.CHAIN_APPROX_SIMPLE)

    if len(contours) > 0:
        maxcontour = None
        maxarea = 0
        mx, my, mw, mh = 0, 0, 0, 0
        for i, c in enumerate(contours):
            x, y, w, h = cv2.boundingRect(c)
            if centerx > x and centerx < x+w and centery > y and centery < y + h:
                area = cv2.contourArea(c)
                if maxarea < area:
                    maxarea = area
                    maxcontour = c
                    mx, my, mw, mh = x, y, w, h
        if maxarea > 100 and maxcontour is not None:
            imagename = f'{imagepath}{videoname}_{frameindex}.jpg'
            textname = f'{labelpath}{videoname}_{frameindex}.txt'
            cv2.imwrite(imagename, frame)
            file2 = open(textname, 'w+')
            file2.write(convert(dw, dh, mx, my, mw, mh))
            file2.close()
            frameindex += 1
    cv2.imshow("Fire", frame)
    if cv2.waitKey(10) == 27:
        break
    success, frame = cap.read()
cap.release()
cv2.destroyAllWindows()

6. 使用效果

    我用手机录的几段视频,几分钟就生成了上万张标注图像,然后YOLOv5 train 起来!颇有些一夜暴富的感觉,你还等什么?

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值