fisheye bev图像上的目标检测01:地面箭头方向检测

1、箭头标注

可以采用labelme标注工具标注,我在windows下使用如下链接

Windows环境使用Lableme - LiWeixiao - 博客园 (cnblogs.com)

  • 标注格式:3点折线
  • 类型:arrowPoint
  • 标注细则
  1. )箭头的三个点全部可见且清晰
  2. )Labelme打开后,鼠标右键选中Create LineStrip先标箭头的顶点,然后逆时针标另外两个点(三个点不用闭合),存储类别为arrowPoint。
  3. )有一个及以上点被遮挡或看不见,其余点按单点标注,Labelme打开后,鼠标右键选中Create Point ,标注单点类别为singleArrowPoint。

 2、labelme格式的json文件转voc格式的xml文件

把labeme标注的json格式的文件写个脚本,分别生成:

1、箭头的最小外接矩形框(箭头的三个顶点),下图arrowRect类别矩形框

2、箭头三个顶点的外接矩形框(以箭头顶点为中心),下图arrowPointRect类别矩形框

下图为labeme标注的箭头

下图为上图json文件生成的 矩形框,箭头外接矩形框(arrowRect),三个箭头顶点矩形框(以箭头顶点为中心生成固定长度的正方形框arrowPointRect)

脚本代码如下:配置好json文件夹路径,和xml文件夹路径运行即可生成json文件对应的xml文件

import os
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import ElementTree,Element
from lxml import etree, objectify
import numpy as np
import json

json_path = r'C:\Users\Desktop\park\arrow\jsons/'                    #json文件的路径
annotations_path = r'C:\Users\Desktop\park\arrow\xml/'          #生成的xml文件需要保存的路径

class_names = ("singleArrowPoint", "arrowPoint")

def write_xml(imgname,filepath,labeldicts,width,height):                     #参数imagename是图片名(无后缀)
    annotation = etree.Element('annotation')                             #创建Annotation根节点
    etree.SubElement(annotation, "folder").text = "labels"
    etree.SubElement(annotation, 'filename').text = str(imgname)+".xml"         #创建filename子节点(无后缀)
    etree.SubElement(annotation, "path").text = filepath[:-3]+"jpg"
    source = etree.SubElement(annotation, "source")
    etree.SubElement(source, "database").text = "Unknown"
    size = etree.SubElement(annotation,'size')                          #创建size子节点
    etree.SubElement(size, 'width').text = str(width)                 #没带脑子直接写了原图片的尺寸......
    etree.SubElement(size, 'height').text = str(height)
    etree.SubElement(size, 'depth').text = '3'                    #图片的通道数:img.shape[2]
    etree.SubElement(annotation, "segmented").text = '0'
    for labeldict in labeldicts:
        objects = etree.SubElement(annotation, 'object')                 #创建object子节点
        etree.SubElement(objects, 'name').text = labeldict['name']        #BDD100K_10.names文件中
                                                                       #的类别名
        etree.SubElement(objects, 'pose').text = 'Unspecified'
        etree.SubElement(objects, 'truncated').text = '0'
        etree.SubElement(objects, 'difficult').text = '0'
        bndbox = etree.SubElement(objects,'bndbox')
        etree.SubElement(bndbox, 'xmin').text = str(int(labeldict['xmin']))
        etree.SubElement(bndbox, 'ymin').text = str(int(labeldict['ymin']))
        etree.SubElement(bndbox, 'xmax').text = str(int(labeldict['xmax']))
        etree.SubElement(bndbox, 'ymax').text = str(int(labeldict['ymax']))
    tree = etree.ElementTree(annotation)
    tree.write(filepath,  pretty_print=True)

def boundaryJudge(xmin,ymin,xmax,ymax,imgW,imgH):
    if xmin < 0:
        xmax = xmax + xmin
        xmin = 0
    if ymin < 0:
        ymax = ymax + ymin
        ymin = 0
    if xmax > imgW - 1:
        xmin = xmin + xmax - imgW
        xmax = imgW - 1

    if ymax > imgH - 1:
        ymin = ymin + ymax - imgH
        ymax = imgH - 1
    return xmin,ymin,xmax,ymax

def generateRect(labeldicts, point, rectW,rectName):
    xmin = round(point[0]) - rectW
    ymin = round(point[1]) - rectW
    xmax = round(point[0]) + rectW
    ymax = round(point[1]) + rectW
    minx, miny, maxx, maxy = boundaryJudge(xmin, ymin, xmax, ymax, imgW, imgH)

    new_dict = {'name': rectName,
                'difficult': '0',
                'xmin': minx,
                'ymin': miny,
                'xmax': maxx,
                'ymax': maxy
                }
    labeldicts.append(new_dict)

if __name__ == '__main__':

    imgW = 480
    imgH = 480
    rectW = 8  #箭头顶点生成矩形框的宽度
    listJson = os.listdir(json_path)
    for i in range(0, len(listJson)):
        print(i)
        path = os.path.join(json_path, listJson[i])

        if os.path.isfile(path):
            data = json.load(open(path, 'r'))
            labeldicts = []

            for lineLabel in data["shapes"]:
                class_name = lineLabel["label"].strip()
                lineName = ""

                if class_name == "arrowPoint" and len(lineLabel["points"]) == 3:
                    ap0 = lineLabel["points"][0]
                    ap1 = lineLabel["points"][1]
                    ap2 = lineLabel["points"][2]

                    xmin = min(ap0[0], ap1[0], ap2[0])
                    xmax = max(ap0[0], ap1[0], ap2[0])
                    ymin = min(ap0[1], ap1[1], ap2[1])
                    ymax = max(ap0[1], ap1[1], ap2[1])

                    xmin = xmin - 1
                    ymin = ymin - 1
                    xmax = xmax + 1
                    ymax = ymax + 1
                    minx, miny, maxx, maxy = boundaryJudge(xmin, ymin, xmax, ymax, imgW, imgH)

                    if maxx - minx > 5 and maxy - miny > 5:
                        new_dict = {'name': "arrowRect",
                                    'difficult': '0',
                                    'xmin': minx,
                                    'ymin': miny,
                                    'xmax': maxx,
                                    'ymax': maxy
                                    }
                        labeldicts.append(new_dict)
                    # --------------------------------------single point----------start
                    generateRect(labeldicts, ap0, rectW, "arrowPointRect")
                    generateRect(labeldicts, ap1, rectW, "arrowPointRect")
                    generateRect(labeldicts, ap2, rectW, "arrowPointRect")
                    # --------------------------------------single point----------end

            write_xml(listJson[i].strip('.json'), annotations_path + listJson[i].strip('.json')+ '.xml', labeldicts,imgW,imgH)

3、目标检测训练       

随便找个目标检测模型训练即可,推荐使用yolov5,链接如下

github.comicon-default.png?t=N7T8https://github.com/ultralytics/yolov5目标检测模型输出的结果如下:

                                              

通过后处理操作,取箭头顶点矩形框的中心,则得到如下结果

                                             

 再通过一系列后处理操作(1、判断红色顶点是否属于箭头(蓝色矩形框),2找到属于矩形框的三个红点,3、三个端点两两生成三条直线,判断这三条直线的长度及角度),既可得到箭头的方向向量(如下图红色直线,方向顶点用圆点表示)

                                               

下一篇分享地面减速带检测方法

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值