转自AI Studio,原文链接:基于S2ANet的十字路口无人机影像车辆旋转检测,可用于车辆行为研究 - 飞桨AI Studio

一、项目背景

  • 现如今,随着光学成像技术和计算机图像处理技术的发展,无人机获取的影像质量也在不断提高,由于其快速便捷、成像质量高、不影响地面的交通的特点而受到众多交通道路研究者青睐

  • 其中一个应用的地方就是使用无人机对复杂路口处进行观测,对车辆进行检测和追踪,研究车辆在复杂路段的行为,为自动驾驶的决策层助力

  • 本项目使用UAV-ROD数据集,基于PaddleDetection提供的旋转目标检测模型对路口影像中的车辆进行检测,检测的结果可用于后续的目标追踪与车辆行为的研究

  • 本项目的效果如下:

    • :视频展示进入项目后看不到

二、数据集介绍与处理

数据集介绍

  • 本项目使用数据集为UAV-ROD,是国科大提供的面向无人机的汽车数据集,带有定向边界框,ai studio数据集链接:UAV-ROD

  • 数据简介

    • UAV-ROD由1577张图像和30090个汽车类别实例组成,这些实例由定向边界框标注。训练集和测试集中的图像数分别为1150和427
    • 国科大使用无人机收集图像,无人机的飞行高度在30米到80米之间。
    • 图像场景包括城市道路、停车场、居民区、路边等
    • :在UAV-ROD中,θ表示车头方向的角度,并按顺时针方向增加。w和h分别代表定向框的宽度和高度
    • 在UAV-ROD数据集中,每张图像的平均对象数为19.08,其中每张图像的最大对象数为104

数据集处理

  • UAV-ROD数据集中带有角度信息的标注文件是每一张图像对应一个.xml文件,而PaddleDetection提供的S2ANet模型训练的数据加载模块是需要coco格式,因此需要进行数据的格式转换
  • 数据转换之后修改相应的配置文件即可
  • :UAV-ROD数据集中也有coco格式的.json文件,不过只标注了cx cy w h,并没有角度

In [1]

# 解压数据
!unzip -qo data/data129957/UAV_ROD_Data.zip -d .

In [2]

# 展示标注的真值
import cv2
import numpy as np
import os
import xml.etree.ElementTree as ET

pi = 3.1415926535

def xywht_to_xyxyxyxy(center_coordinate):
    bboxes = np.empty((0, 8),dtype=np.int32)
    for rect in center_coordinate:
        bbox = cv2.boxPoints(((rect[0], rect[1]), (rect[2], rect[3]), rect[4] * 180 / pi))
        bbox = np.int0(bbox)
        bbox = np.reshape(bbox, [-1, ])
        bboxes = np.vstack((bboxes, [bbox[0], bbox[1], bbox[2], bbox[3], bbox[4], bbox[5], bbox[6], bbox[7]]))
    return bboxes

def load_xml(xml_path):
    anno_file = os.path.join(xml_path)

    with open(anno_file) as f:
        tree = ET.parse(f)

    r = {
        "height": int(tree.findall("./size/height")[0].text),
        "width": int(tree.findall("./size/width")[0].text),
    }
    instances = []
    for obj in tree.findall("object"):
        cls = obj.find("name").text
        bbox = obj.find("robndbox")
        bbox = [float(bbox.find(x).text) for x in ["cx", "cy", "w", "h", "angle"]]
        instances.append(
            {"category": cls, "bbox": bbox}
        )
    r["annotations"] = instances
    return r

def test_one_img(img_path, xml_path):
    img = cv2.imread(img_path)
    dicts = load_xml(xml_path)
    rbbox = []
    anno = dicts['annotations']
    for a in anno:
        rbbox.append(a['bbox'])
    bbox = xywht_to_xyxyxyxy(rbbox)
   
    for b in bbox:
        p1 = (b[0], b[1])
        p2 = (b[2], b[3])
        p3 = (b[4], b[5])
        p4 = (b[6], b[7])
        cv2.line(img, p1, p2, (0, 255, 0), 3)
        cv2.line(img, p2, p3, (0, 0, 255), 3) # The red line indicates the heading direction
        cv2.line(img, p3, p4, (0, 255, 0), 3)
        cv2.line(img, p4, p1, (0, 255, 0), 3)
    return img
  • 可以看到,标注文件的角度是可以反算出车头的位置

In [3]

from PIL import Image
import matplotlib.pyplot as plt
%matplotlib inline

img_dir = r'UAV_ROD_Data/test/images'
xml_dir = r'UAV_ROD_Data/test/annotations'
l = "DJI_0005_000000.jpg"
img_path = os.path.join(img_dir, l)
xml_path = os.path.join(xml_dir, l.split('.')[0] + '.xml')
img = test_one_img(img_path, xml_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
image = Image.fromarray(img)
plt.figure(figsize=(20, 14))
plt.imshow(image), plt.axis('off')
(<matplotlib.image.AxesImage at 0x7f03926ffcd0>, (-0.5, 1919.5, 1079.5, -0.5))

<Figure size 1440x1008 with 1 Axes>
  • 数据格式转换,.xml转coco格式

In [4]

# xml数据格式转为COCO格式
import sys
import os
import json
import xml.etree.ElementTree as ET
import tqdm


START_BOUNDING_BOX_ID = 1
PRE_DEFINE_CATEGORIES = {}
# If necessary, pre-define category and its id
PRE_DEFINE_CATEGORIES = {"car": 1}


def get(root, name):
    vars = root.findall(name)
    return vars


def get_and_check(root, name, length):
    vars = root.findall(name)
    if len(vars) == 0:
        raise NotImplementedError('Can not find %s in %s.'%(name, root.tag))
    if length > 0 and len(vars) != length:
        raise NotImplementedError('The size of %s is supposed to be %d, but is %d.'%(name, length, len(vars)))
    if length == 1:
        vars = vars[0]
    return vars


def get_filename_as_int(filename):
    try:
        filename = os.path.splitext(filename)[0]
        name_list = filename.split('_')
        num = int(''.join(name_list[1:]))
        return num
    except:
        raise NotImplementedError('Filename %s is supposed to be an integer.'%(filename))


def convert(list_fp, xml_dir, json_file):
    json_dict = {"images":[], "type": "instances", "annotations": [],
                 "categories": []}
    categories = PRE_DEFINE_CATEGORIES
    bnd_id = START_BOUNDING_BOX_ID
    for line in tqdm.tqdm(list_fp):
        line = line.strip()
        #print("Processing %s"%(line))
        xml_f = os.path.join(xml_dir, line)
        tree = ET.parse(xml_f)
        root = tree.getroot()
        path = get(root, 'path')
        filename = get(root, 'filename')[0].text
        # if len(path) == 1:
        #     filename = os.path.basename(path[0].text)
        # elif len(path) == 0:
        #     filename = get_and_check(root, 'filename', 1).text
        # else:
        #     raise NotImplementedError('%d paths found in %s'%(len(path), line))
        ## The filename must be a number
        image_id = get_filename_as_int(filename)
        size = get_and_check(root, 'size', 1)
        width = int(get_and_check(size, 'width', 1).text)
        height = int(get_and_check(size, 'height', 1).text)
        image = {'file_name': filename, 'height': height, 'width': width,
                 'id':image_id}
        json_dict['images'].append(image)
        ## Cruuently we do not support segmentation
        #  segmented = get_and_check(root, 'segmented', 1).text
        #  assert segmented == '0'
        for obj in get(root, 'object'):
            category = get_and_check(obj, 'name', 1).text
            if category not in categories:
                new_id = len(categories)
                categories[category] = new_id
            category_id = categories[category]
            bbox = obj.find("robndbox")
            bbox = [float(bbox.find(x).text) for x in ["cx", "cy", "w", "h", "angle"]]
            bndbox = get_and_check(obj, 'robndbox', 1)
            cx = float(get_and_check(bndbox, 'cx', 1).text)
            cy = float(get_and_check(bndbox, 'cy', 1).text)
            w = float(get_and_check(bndbox, 'w', 1).text)
            h = float(get_and_check(bndbox, 'h', 1).text)
            angle = float(get_and_check(bndbox, 'angle', 1).text)

            ann = {'area': w*h, 'iscrowd': 0, 'image_id':
                   image_id, 'bbox':[cx, cy, w, h, angle],
                   'category_id': category_id, 'id': bnd_id, 'ignore': 0,
                   'segmentation': []}
            json_dict['annotations'].append(ann)
            bnd_id = bnd_id + 1

    for cate, cid in categories.items():
        cat = {'supercategory': 'none', 'id': cid, 'name': cate}
        json_dict['categories'].append(cat)
    json_fp = open(json_file, 'w')
    json_str = json.dumps(json_dict)
    json_fp.write(json_str)
    json_fp.close()
    #list_fp.close()

In [5]

# 生成训练集的json文件
xml_dir = r'UAV_ROD_Data/train/annotations'
list_fp = [f for f in os.listdir(xml_dir) if f.endswith('.xml')]

!mkdir UAV_ROD_Data/train/annotation_json

convert(list_fp, xml_dir, 'UAV_ROD_Data/train/annotation_json/train.json')
100%|██████████| 1150/1150 [00:00<00:00, 1517.27it/s]

In [6]

# 生成测试集的json文件
xml_dir = r'UAV_ROD_Data/test/annotations'
list_fp = [f for f in os.listdir(xml_dir) if f.endswith('.xml')]

!mkdir UAV_ROD_Data/test/annotation_json

convert(list_fp, xml_dir, 'UAV_ROD_Data/test/annotation_json/valid.json')
100%|██████████| 427/427 [00:00<00:00, 1014.45it/s]

In [7]

# 转换数据集名称
!mv UAV_ROD_Data UAV_coco

三、环境与训练配置文件准备

环境依赖的安装

  • 克隆PaddleDetection仓库,安装对应的依赖和旋转IOU计算的OP

In [8]

# 从码云上克隆仓库
!git clone https://gitee.com/paddlepaddle/PaddleDetection.git
正克隆到 'PaddleDetection'...
remote: Enumerating objects: 23165, done.
remote: Counting objects: 100% (3635/3635), done.
remote: Compressing objects: 100% (1765/1765), done.
remote: Total 23165 (delta 2580), reused 2667 (delta 1863), pack-reused 19530
接收对象中: 100% (23165/23165), 261.63 MiB | 12.68 MiB/s, 完成.
处理 delta 中: 100% (17129/17129), 完成.
检查连接... 完成。
正在检出文件: 100% (1852/1852), 完成.

In [ ]

# 安装依赖
%cd ~/PaddleDetection/
!pip install -r requirements.txt

In [ ]

# 安装旋转框IOU计算OP,耗时不到一分钟,输出ok即为成功安装
%cd ppdet/ext_op
!python3.7 setup.py install
!python3.7 test.py

配置文件的准备

  • 主要包括数据、模型、优化、训练四个.yml文件的准备与修改(均已经写好放置于work/UAV 文件夹下):
    • 数据文件:针对UAV-ROD数据集的配置,在work文件夹下UAV_coco.yml
    • 模型优化文件:修改了学习率,PaddleDetection提供的是8卡训练的学习率配置,修改为原来的1/8训练,在work/UAV/base/s2anet_optimizer_2x.yml
    • 模型文件,修改了类别,num_class=1,在work/UAV/base/s2anet.yml
    • 训练文件,S2ANet训练UAV-ROD模型,类别改为1,在work/UAV/s2anet_alignconv_2x_uav.yml

In [11]

%cd ~
!cp work/UAV_coco.yml PaddleDetection/configs/datasets/
!cp -r work/UAV PaddleDetection/configs/
/home/aistudio

四、模型的训练、评估与预测

训练模型并预测

In [12]

# 将数据移动到对应的文件夹
!mv UAV_coco PaddleDetection/dataset/

In [ ]

# 训练,这里没有加载预训练模型进行训练
%cd /home/aistudio/PaddleDetection/
!export CUDA_VISIBLE_DEVICES=0
!python3.7 tools/train.py -c configs/UAV/s2anet_alignconv_2x_uav.yml

In [ ]

# 模型评估,这里有个问题,就是没法跳出循环,因为在aistudio上debug比较难,所以目前还没寻找到原因,暂且跳过
# %cd /home/aistudio/PaddleDetection/
# !python3.7 tools/eval.py -c configs/UAV/s2anet_alignconv_2x_uav.yml \
#     -o weights=../work/weights/model_final.pdparams 

In [ ]

基于S2ANet的十字路口无人机影像车辆旋转检测,可用于车辆行为研究

一、项目背景

  • 现如今,随着光学成像技术和计算机图像处理技术的发展,无人机获取的影像质量也在不断提高,由于其快速便捷、成像质量高、不影响地面的交通的特点而受到众多交通道路研究者青睐

  • 其中一个应用的地方就是使用无人机对复杂路口处进行观测,对车辆进行检测和追踪,研究车辆在复杂路段的行为,为自动驾驶的决策层助力

  • 本项目使用UAV-ROD数据集,基于PaddleDetection提供的旋转目标检测模型对路口影像中的车辆进行检测,检测的结果可用于后续的目标追踪与车辆行为的研究

  • 本项目的效果如下:

    • :视频展示进入项目后看不到

二、数据集介绍与处理

数据集介绍

  • 本项目使用数据集为UAV-ROD,是国科大提供的面向无人机的汽车数据集,带有定向边界框,ai studio数据集链接:UAV-ROD

  • 数据简介

    • UAV-ROD由1577张图像和30090个汽车类别实例组成,这些实例由定向边界框标注。训练集和测试集中的图像数分别为1150和427
    • 国科大使用无人机收集图像,无人机的飞行高度在30米到80米之间。
    • 图像场景包括城市道路、停车场、居民区、路边等
    • :在UAV-ROD中,θ表示车头方向的角度,并按顺时针方向增加。w和h分别代表定向框的宽度和高度
    • 在UAV-ROD数据集中,每张图像的平均对象数为19.08,其中每张图像的最大对象数为104

数据集处理

  • UAV-ROD数据集中带有角度信息的标注文件是每一张图像对应一个.xml文件,而PaddleDetection提供的S2ANet模型训练的数据加载模块是需要coco格式,因此需要进行数据的格式转换
  • 数据转换之后修改相应的配置文件即可
  • :UAV-ROD数据集中也有coco格式的.json文件,不过只标注了cx cy w h,并没有角度

In [1]

# 解压数据
!unzip -qo data/data129957/UAV_ROD_Data.zip -d .

In [2]

# 展示标注的真值
import cv2
import numpy as np
import os
import xml.etree.ElementTree as ET

pi = 3.1415926535

def xywht_to_xyxyxyxy(center_coordinate):
    bboxes = np.empty((0, 8),dtype=np.int32)
    for rect in center_coordinate:
        bbox = cv2.boxPoints(((rect[0], rect[1]), (rect[2], rect[3]), rect[4] * 180 / pi))
        bbox = np.int0(bbox)
        bbox = np.reshape(bbox, [-1, ])
        bboxes = np.vstack((bboxes, [bbox[0], bbox[1], bbox[2], bbox[3], bbox[4], bbox[5], bbox[6], bbox[7]]))
    return bboxes

def load_xml(xml_path):
    anno_file = os.path.join(xml_path)

    with open(anno_file) as f:
        tree = ET.parse(f)

    r = {
        "height": int(tree.findall("./size/height")[0].text),
        "width": int(tree.findall("./size/width")[0].text),
    }
    instances = []
    for obj in tree.findall("object"):
        cls = obj.find("name").text
        bbox = obj.find("robndbox")
        bbox = [float(bbox.find(x).text) for x in ["cx", "cy", "w", "h", "angle"]]
        instances.append(
            {"category": cls, "bbox": bbox}
        )
    r["annotations"] = instances
    return r

def test_one_img(img_path, xml_path):
    img = cv2.imread(img_path)
    dicts = load_xml(xml_path)
    rbbox = []
    anno = dicts['annotations']
    for a in anno:
        rbbox.append(a['bbox'])
    bbox = xywht_to_xyxyxyxy(rbbox)
   
    for b in bbox:
        p1 = (b[0], b[1])
        p2 = (b[2], b[3])
        p3 = (b[4], b[5])
        p4 = (b[6], b[7])
        cv2.line(img, p1, p2, (0, 255, 0), 3)
        cv2.line(img, p2, p3, (0, 0, 255), 3) # The red line indicates the heading direction
        cv2.line(img, p3, p4, (0, 255, 0), 3)
        cv2.line(img, p4, p1, (0, 255, 0), 3)
    return img
  • 可以看到,标注文件的角度是可以反算出车头的位置

In [3]

from PIL import Image
import matplotlib.pyplot as plt
%matplotlib inline

img_dir = r'UAV_ROD_Data/test/images'
xml_dir = r'UAV_ROD_Data/test/annotations'
l = "DJI_0005_000000.jpg"
img_path = os.path.join(img_dir, l)
xml_path = os.path.join(xml_dir, l.split('.')[0] + '.xml')
img = test_one_img(img_path, xml_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
image = Image.fromarray(img)
plt.figure(figsize=(20, 14))
plt.imshow(image), plt.axis('off')
(<matplotlib.image.AxesImage at 0x7f03926ffcd0>, (-0.5, 1919.5, 1079.5, -0.5))

<Figure size 1440x1008 with 1 Axes>
  • 数据格式转换,.xml转coco格式

In [4]

# xml数据格式转为COCO格式
import sys
import os
import json
import xml.etree.ElementTree as ET
import tqdm


START_BOUNDING_BOX_ID = 1
PRE_DEFINE_CATEGORIES = {}
# If necessary, pre-define category and its id
PRE_DEFINE_CATEGORIES = {"car": 1}


def get(root, name):
    vars = root.findall(name)
    return vars


def get_and_check(root, name, length):
    vars = root.findall(name)
    if len(vars) == 0:
        raise NotImplementedError('Can not find %s in %s.'%(name, root.tag))
    if length > 0 and len(vars) != length:
        raise NotImplementedError('The size of %s is supposed to be %d, but is %d.'%(name, length, len(vars)))
    if length == 1:
        vars = vars[0]
    return vars


def get_filename_as_int(filename):
    try:
        filename = os.path.splitext(filename)[0]
        name_list = filename.split('_')
        num = int(''.join(name_list[1:]))
        return num
    except:
        raise NotImplementedError('Filename %s is supposed to be an integer.'%(filename))


def convert(list_fp, xml_dir, json_file):
    json_dict = {"images":[], "type": "instances", "annotations": [],
                 "categories": []}
    categories = PRE_DEFINE_CATEGORIES
    bnd_id = START_BOUNDING_BOX_ID
    for line in tqdm.tqdm(list_fp):
        line = line.strip()
        #print("Processing %s"%(line))
        xml_f = os.path.join(xml_dir, line)
        tree = ET.parse(xml_f)
        root = tree.getroot()
        path = get(root, 'path')
        filename = get(root, 'filename')[0].text
        # if len(path) == 1:
        #     filename = os.path.basename(path[0].text)
        # elif len(path) == 0:
        #     filename = get_and_check(root, 'filename', 1).text
        # else:
        #     raise NotImplementedError('%d paths found in %s'%(len(path), line))
        ## The filename must be a number
        image_id = get_filename_as_int(filename)
        size = get_and_check(root, 'size', 1)
        width = int(get_and_check(size, 'width', 1).text)
        height = int(get_and_check(size, 'height', 1).text)
        image = {'file_name': filename, 'height': height, 'width': width,
                 'id':image_id}
        json_dict['images'].append(image)
        ## Cruuently we do not support segmentation
        #  segmented = get_and_check(root, 'segmented', 1).text
        #  assert segmented == '0'
        for obj in get(root, 'object'):
            category = get_and_check(obj, 'name', 1).text
            if category not in categories:
                new_id = len(categories)
                categories[category] = new_id
            category_id = categories[category]
            bbox = obj.find("robndbox")
            bbox = [float(bbox.find(x).text) for x in ["cx", "cy", "w", "h", "angle"]]
            bndbox = get_and_check(obj, 'robndbox', 1)
            cx = float(get_and_check(bndbox, 'cx', 1).text)
            cy = float(get_and_check(bndbox, 'cy', 1).text)
            w = float(get_and_check(bndbox, 'w', 1).text)
            h = float(get_and_check(bndbox, 'h', 1).text)
            angle = float(get_and_check(bndbox, 'angle', 1).text)

            ann = {'area': w*h, 'iscrowd': 0, 'image_id':
                   image_id, 'bbox':[cx, cy, w, h, angle],
                   'category_id': category_id, 'id': bnd_id, 'ignore': 0,
                   'segmentation': []}
            json_dict['annotations'].append(ann)
            bnd_id = bnd_id + 1

    for cate, cid in categories.items():
        cat = {'supercategory': 'none', 'id': cid, 'name': cate}
        json_dict['categories'].append(cat)
    json_fp = open(json_file, 'w')
    json_str = json.dumps(json_dict)
    json_fp.write(json_str)
    json_fp.close()
    #list_fp.close()

In [5]

# 生成训练集的json文件
xml_dir = r'UAV_ROD_Data/train/annotations'
list_fp = [f for f in os.listdir(xml_dir) if f.endswith('.xml')]

!mkdir UAV_ROD_Data/train/annotation_json

convert(list_fp, xml_dir, 'UAV_ROD_Data/train/annotation_json/train.json')
100%|██████████| 1150/1150 [00:00<00:00, 1517.27it/s]

In [6]

# 生成测试集的json文件
xml_dir = r'UAV_ROD_Data/test/annotations'
list_fp = [f for f in os.listdir(xml_dir) if f.endswith('.xml')]

!mkdir UAV_ROD_Data/test/annotation_json

convert(list_fp, xml_dir, 'UAV_ROD_Data/test/annotation_json/valid.json')
100%|██████████| 427/427 [00:00<00:00, 1014.45it/s]

In [7]

# 转换数据集名称
!mv UAV_ROD_Data UAV_coco

三、环境与训练配置文件准备

环境依赖的安装

  • 克隆PaddleDetection仓库,安装对应的依赖和旋转IOU计算的OP

In [8]

# 从码云上克隆仓库
!git clone https://gitee.com/paddlepaddle/PaddleDetection.git
正克隆到 'PaddleDetection'...
remote: Enumerating objects: 23165, done.
remote: Counting objects: 100% (3635/3635), done.
remote: Compressing objects: 100% (1765/1765), done.
remote: Total 23165 (delta 2580), reused 2667 (delta 1863), pack-reused 19530
接收对象中: 100% (23165/23165), 261.63 MiB | 12.68 MiB/s, 完成.
处理 delta 中: 100% (17129/17129), 完成.
检查连接... 完成。
正在检出文件: 100% (1852/1852), 完成.

In [ ]

# 安装依赖
%cd ~/PaddleDetection/
!pip install -r requirements.txt

In [ ]

# 安装旋转框IOU计算OP,耗时不到一分钟,输出ok即为成功安装
%cd ppdet/ext_op
!python3.7 setup.py install
!python3.7 test.py

配置文件的准备

  • 主要包括数据、模型、优化、训练四个.yml文件的准备与修改(均已经写好放置于work/UAV 文件夹下):
    • 数据文件:针对UAV-ROD数据集的配置,在work文件夹下UAV_coco.yml
    • 模型优化文件:修改了学习率,PaddleDetection提供的是8卡训练的学习率配置,修改为原来的1/8训练,在work/UAV/base/s2anet_optimizer_2x.yml
    • 模型文件,修改了类别,num_class=1,在work/UAV/base/s2anet.yml
    • 训练文件,S2ANet训练UAV-ROD模型,类别改为1,在work/UAV/s2anet_alignconv_2x_uav.yml

In [11]

%cd ~
!cp work/UAV_coco.yml PaddleDetection/configs/datasets/
!cp -r work/UAV PaddleDetection/configs/
/home/aistudio

四、模型的训练、评估与预测

训练模型并预测

In [12]

# 将数据移动到对应的文件夹
!mv UAV_coco PaddleDetection/dataset/

In [ ]

# 训练,这里没有加载预训练模型进行训练
%cd /home/aistudio/PaddleDetection/
!export CUDA_VISIBLE_DEVICES=0
!python3.7 tools/train.py -c configs/UAV/s2anet_alignconv_2x_uav.yml

In [ ]

# 模型评估,这里有个问题,就是没法跳出循环,因为在aistudio上debug比较难,所以目前还没寻找到原因,暂且跳过
# %cd /home/aistudio/PaddleDetection/
# !python3.7 tools/eval.py -c configs/UAV/s2anet_alignconv_2x_uav.yml \
#     -o weights=../work/weights/model_final.pdparams 

In [ ]

 # 数据预测,使用的权重为事先保存好的权重,位置在work/weights
 # 可以使用自己训练得到的权重,修改weights后的路径即可
 # infer_dir 为自己要预测的图像所在文件夹位置
%cd /home/aistudio/PaddleDetection/
!python3.7 tools/infer.py -c configs/UAV/s2anet_alignconv_2x_uav.yml -o weights=../work/weights/model_final.pdparams \
                        --infer_dir=../work/inputs --draw_threshold=0.5 --output_dir=../work/outputs

展示预测结果

In [15]

import matplotlib.pyplot as plt
from PIL import Image
%matplotlib inline
image = Image.open('../work/outputs/DJI_0005_000000.jpg')
plt.figure(figsize=(20, 14))
plt.imshow(image), plt.axis('off')
(<matplotlib.image.AxesImage at 0x7f038188be50>, (-0.5, 1919.5, 1079.5, -0.5))

<Figure size 1440x1008 with 1 Axes>

五、总结

不足之处

  • 数据层面:UAV-ROD数据标注了所有车辆为car这一类型,没有进一步细分,如果遇到公交车、卡车等大型车会影响准确率
  • 模型后处理层面:标注角度时,UAV-ROD数据集使用车头方向判断,而PaddleDetection则是通过长和宽判断角度,所以输出的结果不能显示出车头方向

下一步工作

  • 个人第一次接触PaddleDetection,下一步会学习有关目标追踪的内容,应用到这个项目的输出结果中
 # 数据预测,使用的权重为事先保存好的权重,位置在work/weights
 # 可以使用自己训练得到的权重,修改weights后的路径即可
 # infer_dir 为自己要预测的图像所在文件夹位置
%cd /home/aistudio/PaddleDetection/
!python3.7 tools/infer.py -c configs/UAV/s2anet_alignconv_2x_uav.yml -o weights=../work/weights/model_final.pdparams \
                        --infer_dir=../work/inputs --draw_threshold=0.5 --output_dir=../work/outputs

展示预测结果

In [15]

import matplotlib.pyplot as plt
from PIL import Image
%matplotlib inline
image = Image.open('../work/outputs/DJI_0005_000000.jpg')
plt.figure(figsize=(20, 14))
plt.imshow(image), plt.axis('off')
(<matplotlib.image.AxesImage at 0x7f038188be50>, (-0.5, 1919.5, 1079.5, -0.5))

<Figure size 1440x1008 with 1 Axes>

五、总结

不足之处

  • 数据层面:UAV-ROD数据标注了所有车辆为car这一类型,没有进一步细分,如果遇到公交车、卡车等大型车会影响准确率
  • 模型后处理层面:标注角度时,UAV-ROD数据集使用车头方向判断,而PaddleDetection则是通过长和宽判断角度,所以输出的结果不能显示出车头方向

下一步工作

  • 个人第一次接触PaddleDetection,下一步会学习有关目标追踪的内容,应用到这个项目的输出结果中
Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐