MMRotate:旋转框检测实现过程

2023-11-12

MMRotate:旋转框检测实现过程

MMRotate地址:https://github.com/open-mmlab/mmrotate

文档地址:https://mmrotate.readthedocs.io/en/latest/

 一、环境搭建

1.创建虚拟环境

conda create --name mmdet2 python=3.8 -y

激活虚拟环境:

conda activate openmmlab

2.安装pytorch、torchvision

根据自己的配置安装相应版本

pip install torch==1.7.1+cu101 torchvision==0.8.2+cu101 -f https://download.pytorch.org/whl/torch_stable.html

3.安装mmcv-full

下载mmcv-full 1.4.5
pip install mmcv-full==1.4.5 --user -i https://mirrors.aliyun.com/pypi/simple

 4.下载mmdet 2.22.0
pip install mmdet==2.22.0 --user -i https://mirrors.aliyun.com/pypi/simple

 5.下载mmrotate
git clone https://github.com/open-mmlab/mmrotate.git

 6.编译mmrotate

 cd  mmrotate

pip install -r requirements/build.txt  -i https://mirrors.aliyun.com/pypi/simple

python setup.py develop

 

 6.制作数据集

使用工具:rolabelimg

git clone GitHub - cgvict/roLabelImg: Label Rotated Rect On Images for training

安装相关依赖库:

pip install pyqt5-tools

pip install lxml

进入rolabelimg目录

pyrcc5 -o resources.py

resources.qrc python roLabelImg.py

进入rolabelimg方式:

./roLabelImg.py

切换旋转框模式

​ 

 旋转框标记

 标记完数据后需将xml改为dota格式,运行如下代码:

import os
import glob
import math
import xml.etree.ElementTree as ET
import json
from base64 import b64encode
from json import dumps
import cv2
def rotatePoint(xc, yc, xp, yp, theta):
    xoff = xp - xc
    yoff = yp - yc
    cosTheta = math.cos(theta)
    sinTheta = math.sin(theta)
    pResx = cosTheta * xoff + sinTheta * yoff
    pResy = - sinTheta * xoff + cosTheta * yoff
    return str(int(xc + pResx)), str(int(yc + pResy))
def get(root, name):
    return root.findall(name)
# 检查读取xml文件是否出错
def get_and_check(root, name, length):
    vars = root.findall(name)
    if len(vars) == 0:
        raise NotImplementedError('Can not fing %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 convert(xml_file, save_dir, name, data):
    tree = ET.parse(xml_file)  # 读取xml文件
    root = tree.getroot()
    size = get_and_check(root, 'size', 1)  # 读取xml中<>size<>字段中的内容
    img = cv2.imread(data)
     # 当标注中有多个目标时全部读取出来
    txtname = name + '.txt'
    txt_file = os.path.join(save_dir, txtname)
    category_list=[]
    with open(txt_file, "w+", encoding='UTF-8') as out_file:
        for obj in get(root, 'object'):
            # 定义图片的标注信
            category = get_and_check(obj, 'name', 1).text  # 读取当前目标的类别
            if category not in category_list:
                category_list.append(category)
            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)
            x0, y0 = rotatePoint(cx, cy, cx - w / 2, cy - h / 2, -angle)
            x1, y1 = rotatePoint(cx, cy, cx + w / 2, cy - h / 2, -angle)
            x2, y2 = rotatePoint(cx, cy, cx + w / 2, cy + h / 2, -angle)
            x3, y3 = rotatePoint(cx, cy, cx - w / 2, cy + h / 2, -angle)
            dict = {y0: x0, y1: x1, y2: x2, y3: x3}
            list = find_topLeftPopint(dict)
            if list[0] == x0:
                list_xy = [x0, y0, x1, y1, x2, y2, x3, y3]
            elif list[0] == x1:
                list_xy = [x1, y1, x2, y2,  x3, y3, x0, y0]
            elif list[0] == x2:
                list_xy = [x2, y2,  x3, y3, x0, y0, x1, y1]
            else:
                list_xy = [x3, y3, x0, y0, x1, y1, x2, y2]
                # 在原图上画矩形 看是否转换正确
            cv2.line(img, (int(list_xy[0]), int(list_xy[1])), (int(list_xy[2]), int(list_xy[3])), color=(255, 0, 0),thickness=3)
            cv2.line(img, (int(list_xy[2]), int(list_xy[3])), (int(list_xy[4]), int(list_xy[5])), color=(255, 0, 0),thickness=3)
            cv2.line(img, (int(list_xy[4]), int(list_xy[5])), (int(list_xy[6]), int(list_xy[7])), color=(255, 0, 0),thickness=3)
            cv2.line(img, (int(list_xy[6]), int(list_xy[7])), (int(list_xy[0]), int(list_xy[1])), color=(255, 0, 0),thickness=3)
            points = str(list_xy[0]) + " " + str(list_xy[1]) + " " + str(list_xy[2]) + " " + str(list_xy[3]) +" " + str(list_xy[4]) + " " + str(list_xy[5]) + " " + str(list_xy[6]) +" " + str(list_xy[7]) + " "
            points = points + category + " " + "0" + "\n"
            out_file.write(points)
            cv2.imwrite(os.path.join(saved_path, name + '.png'), img)
    return category_list 
def find_topLeftPopint(dict):
    dict_keys = sorted(dict.keys())  # y值
    temp = [dict[dict_keys[0]], dict[dict_keys[1]]]
    minx = min(temp)
    if minx == temp[0]:
        miny = dict_keys[0]
    else:
        miny = dict_keys[1]
    return [minx, miny]
def do_transformation(xml_dir, save_path, img):
    cnt = 0
    list1 = []
    for fname in os.listdir(xml_dir):
        name = fname.split(".")[0]  # 获取图片名字
        endwith = fname.split(".")
        path = os.path.join(xml_dir, fname)  # 文件路径
        for img_name in os.listdir(img):
            end = img_name.split('.')
            if name == end[0]:
                data = img + name + '.' + end[1]  # xml文件对应的图片路径
        list = convert(path, save_path, name, data)
    for i in list:
        if i not in list1:
           list1.append(i)
    print(list1)
        cnt += 1
if __name__ == '__main__':  
    data_path = "/home/work/mjt/xuanzhuan_train/data/"  # json文件夹路径
    saved_path = "/home/work/mjt/xuanzhuan_train/train_data"  # xml保存路径
    xml_path = "/home/work/mjt/xuanzhuan_train/resizexml"
    txt_path = saved_path + '/trainval1/annfiles'
    if not os.path.exists(txt_path):
        os.makedirs(txt_path)
    files = os.listdir(xml_path)
    files = [i.replace("\\", "/").split("/")[-1].split(".xml")[0] for i in files]
    print(files)
    img = "/home/work/mjt/xuanzhuan_train/data/"  # xml对应图片文件夹
    save_dota_path = "/home/work/mjt/xuanzhuan_train/dota/"  # 存放json文件夹
    if not os.path.exists(save_dota_path):
        os.makedirs(save_dota_path)
    do_transformation(xml_path, save_dota_path, img)

数据格式:

datasets

        --trainval

                --images #存放图片

                --annfiles #对应的txt文件(上图代码生成的)

        --test

                --images

                --annfiles

7.修改config文件

(1)下载预训练权重

    地址:mmrotate/model_zoo.md at main · open-mmlab/mmrotate · GitHubOpenMMLab Rotated Object Detection Toolbox and Benchmark - mmrotate/model_zoo.md at main · open-mmlab/mmrotatehttps://github.com/open-mmlab/mmrotate/blob/main/docs/zh_cn/model_zoo.md(2)修改./configs/rotated_faster_rcnn/rotated_faster_rcnn_r50_fpn_1x_data_le90.py

如下图修改文件中的num_classes

 (3)修改./mmrotate/datasets/dota.py 中的类别名称

修改文件中CLASSES

 (4)修改 ./configs/_base_/datasets/dotav1.py 文件

修改文件中的data_root、可根据训练集尺寸更img_scale

 (5)修改./configs/_base_/default_runtime.py文件

修改文件中的预训练模型

 (6)一些其他设置

 8.训练

修改./tool/train.py文件

 - -config: 使用的模型文件  ; - -work-dir:训练得到的模型及配置信息保存的路径。

9.测试

可用./tool/test.py进行测试,也可运行下面代码

from argparse import ArgumentParser
from mmdet.apis import inference_detector, init_detector, show_result_pyplot
import os
import time
import mmrotate
def parse_args():
    parser = ArgumentParser()
    parser.add_argument('img', help='Image file')
    parser.add_argument('config', help='Config file')
    parser.add_argument('checkpoint', help='Checkpoint file')
    parser.add_argument(
        '--device', default='cuda:0', help='Device used for inference')
    parser.add_argument(
        '--palette',
        default='dota',
        choices=['dota', 'sar', 'hrsc', 'hrsc_classwise', 'random'],
        help='Color palette used for visualization')
    parser.add_argument(
        '--score-thr', type=float, default=0.3, help='bbox score threshold')
    
    args = parser.parse_args()
    return args
def main(args):
    file_name = os.listdir(args.img)
    model = init_detector(args.config, args.checkpoint, device=args.device)
    for image in file_name:
        images = os.path.join(args.img, image)
        start = time.time()
        result = inference_detector(model, images)
        end = time.time()
        show_result_pyplot(
            model,
            images,
            result,
            palette=args.palette,
            score_thr=args.score_thr,
            out_file=os.path.join("/home/work/预言故障图/1111/旋转", image))
if __name__ == '__main__':
    args = parse_args()
    main(args)

配置运行参数,即配置文件及对应的模型 

 9.结果展示

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MMRotate:旋转框检测实现过程 的相关文章

  • 异常处理的范围规则是什么? [复制]

    这个问题在这里已经有答案了 我偶然发现了一个有趣的场景这个问题 https stackoverflow com q 69464430 6045800 考虑以下简单示例 try 1 0 error error except Exception
  • 使用输入按钮处理网站上的分页

    试图使用硒抓取这个网站 我的代码可以工作 但目前它只抓取第一页 该页面使用输入按钮作为浏览页面的一种方式 因此我想逐个单击每个按钮 但它不起作用 有没有人有任何其他方法来处理此类分页的导航 import requests from sele
  • 使用非负约束进行优化

    考虑以下功能 import numpy as np import scipy optimize as opt import math Periodic indexation def pl list i return list i len l
  • 在 Linux 上创建线程与进程的开销

    我试图回答在 python 中创建线程与进程有多少开销的问题 我修改了类似问题的代码 该问题基本上运行一个带有两个线程的函数 然后运行带有两个进程的相同函数并报告时间 import time sys NUM RANGE 100000000
  • PyPDF2 复制后返回空白 PDF

    def EncryptPDFFiles password directory pdfFiles success 0 Get all PDF files from a directory for folderName subFolders f
  • Boost Python:多态容器?

    我有一个方法 或函数 它返回对多态对象列表的引用 class A class B public A std list
  • 如何在Python中使用getopt/OPTARG?如果给出太多参数 (9),如何转移参数?

    如何在Python中使用getopt optarg 这是我如何做到这一点的示例 我通常使用相同的基本模板 import sys import getopt try opts args getopt getopt sys argv 1 m p
  • 从日志文件 python 创建 csv 标题

    我的日志文件每行都包含一些信息 如下所示 Info1 NewOrder key 123 Info3 10 Info5 abc Info3 10 Info1 OldOrder key 456 Info6 xyz Info1 NewOrder
  • python subprocess proc.stderr.read() 引入额外的行?

    我想运行一些命令并抓取输出到 stderr 的任何内容 我有两个版本的函数可以执行此操作 版本 1 def Getstatusoutput cmd Return status output of executing cmd in a she
  • python-click:添加修改其他参数行为的选项

    这个问题是关于click http click pocoo org 5 包裹 Click 是一个用于创建漂亮命令行的 Python 包 使用尽可能少的代码以可组合的方式进行接口 它是 命令行界面创建工具包 它具有高度可配置性 但带有开箱即用
  • 减少每日状态表以仅包含状态更改

    我有一个包含 10 万以上用户的大型每日状态表 5 7 亿行 目前它位于 MySQL 或 CSV 中 该表包含三列 user id status 和 date 理想情况下 我希望将表缩减为一个新表 其中包含每个状态期间的 user id s
  • 如何在 Pandas 中将多列乘以一列

    我想拥有 df income 1 income 2 df mtaz proportion 返回这些列乘以df mtaz proportion 这样我就可以设置 df mtaz income 1 mtaz income 2 df income
  • 在此异步设置中,我在哪里捕获 KeyboardInterrupt 异常

    我正在开发一个使用ccxt异步库 它要求通过显式调用该类的资源来释放某个类使用的所有资源 close 协程 我想退出程序ctrl c并等待异常中的关闭协程 然而 它永远不会被等待 该应用程序由模块组成harvesters strategie
  • kombu.exceptions.EncodeError:用户不可 JSON 序列化

    我有 django 1 11 5 应用程序和 celery 4 1 0 我一直收到 kombu exceptions EncodeError
  • 我们可以限制 luigi 任务的吞吐量吗?

    我们有一个 Luigi 任务 它向第三方服务请求一条信息 我们对该 API 调用每分钟可以执行的调用请求数量受到限制 有没有办法在每个任务的基础上指定调度程序每单位时间必须运行多少个此类任务 我们在任务中实施了自己的速率限制 我们的 API
  • 为什么 `Pool.map()` 多处理中的内存消耗急剧增加?

    我正在对 pandas 数据帧进行多重处理 方法是将其拆分为多个数据帧 这些数据帧存储为列表 并且 使用Pool map 我将数据帧传递给定义的函数 我的输入文件约为 300 mb 因此小数据帧大约为 75 mb 但是 当多处理运行时 内存
  • 如何在seaborn displot上绘制正态曲线

    distplot 已被弃用 取而代之的是 displot 之前的函数可以选择绘制正态曲线 import seaborn as sns import matplotlib pyplot as plt from scipy import sta
  • 在 django 视图中执行阻塞请求

    在我的 django 应用程序的一个视图中 我需要执行相对较长的网络 IO 操作 问题是其他请求必须等待该请求完成 即使它们与该请求无关 我做了一些研究并偶然发现了 Celery 但据我了解 它用于执行独立于请求的后台任务 所以我不能使用任
  • 如何使用 google.oauth2 python 库?

    我试图对谷歌机器学习项目的安全预测端点进行简单的休息调用 但它找不到 google oauth2 模块 这是我的代码 import urllib2 from google oauth2 import service account Cons
  • 通过 subprocess.communicate 在 python 脚本之间传输 pickled 对象输出

    我有两个 python 脚本 object generator py 它会腌制给定的对象并打印它 另一个脚本 object consumer py 通过 subprocess communicate 选择第一个脚本的输出 并尝试使用 pic

随机推荐

  • 在MDK5中,warning:  #550-D: variable "d" was set but never used 的理解以及解释

    1 warning 550 D variable d was set but never used描述 变量 d 定义但从未使用 或者是 虽然这个变量你使用了 但编译器认为变量d所在的语句没有意义 编译器把它优化了 解决 仔细衡量所定义的变
  • 想跳槽涨薪的必看!2021年你与字节跳动只差这份笔记,大厂内部资料

    说白了 哪一个行业不是吃青春饭呢 无论哪个行业 大部分的从业人员都是在拿青春赌明天 而且很残忍的一个事实是 没有人的工作是不可取代的 如果你辞职 老板极力挽留 那就说明 你是那帮取代你的候选人当中最便宜的 市场在逐渐成熟 程序员的前景确实灰
  • java获取当前路径的方法

    参考网址 https www cnblogs com franson 2016 p 5728280 html 面临问题 需要在linux系统中run jar文件 运行过程包括文件IO 由于txt文件在windows系统中和在linux中路径
  • 0-1背包问题由二维数组转换为一维数组的理解

    对于0 1背包问题的话 可以使用一维数组来表示 我们要知道每一行的数据其实是依赖于上一行的数据 并不依赖于本行的数据 所以无论正序或者逆序更新一行的数据都不会需要本行的数据 但是为什么用一维数组更新时就要用逆序呢 其实是因为用一维数组更新时
  • imx8烧写Linux系统,RT-Linux在IMX8上的使用

    By Toradex胡珊逢 Real time Linux 是指在普通 Linux 内核打上 PREEMPT RT补丁后使内核满足实时要求 下面我们将使用 Apalis iMX8QM 介绍如何开启 Linux 5 4 的实时功能 首先需要下
  • 200 行代码实现一个简单的区块链

    java 区块链开发与交流群 613121183 有兴趣的也可以加下哈 提供了不少区块链资料 以后有资料可以相会共享 区块链的基础概念很简单 一个分布式数据库 存储一个不断加长的 list list 中包含着许多有序的记录 然而 在通常情况
  • 数据仓库模型设计V2.0

    一 数仓建模的意义 数据模型就是数据组织和存储方法 它强调从业务 数据存取和使用角度合理存储数据 只有将数据有序的组织和存储起来之后 数据才能得到高性能 低成本 高效率 高质量的使用 高性能 良好的数据模型能够帮助我们快速查询所需要的数据
  • 什么是vps

    在上网冲浪的时候看到网友在说一个我不认识的词汇 vps 于是在此记录下 文章目录 一 介绍 1 概念 2 特性用途 二 VPS又称为机场 三 VPS的使用 1 如何获取VPS 2 VPS品牌 总结 一 介绍 1 概念 VPS Virtual
  • 物联网平台设备运维监控报警介绍——实践类

    物联网平台监控报警简介 物联网平台除了基础的设备接入上云以及物模型建模管理外 还提供了面向运维场景的监控报警功能 帮助客户了解业务的运行情况 进行相关的运维操作 本文重点介绍相关的监控可视化及规则报警通知功能 包括 自定义的可视化监控大盘
  • 时间序列预测——LSTM模型(附代码实现)

    目录 模型原理 模型实现 导入所需要的库 设置随机数种子 导入数据集 打印前五行数据进行查看 数据处理 归一化处理 查看归一化处理后的数据 将时间序列转换为监督学习问题 打印数据前五行 划分训练集和测试集 查看划分后的数据维度 搭建LSTM
  • 通过环境变量修改java版本不生效

    通过环境变量修改java版本不生效 环境变量指向的是Java1 8版本 但是在终端下查看Java version版本是10 0 2 本机依次安装了 jdk1 8 jdk1 6 和 jdk1 7 三个版本的 jdk 由于maven打包andr
  • 基于PaddleGAN项目人脸表情动作迁移学习(二)单人表情迁移

    学习目标 学习基于PaddleGAN实现的动作迁移模型 First order motion model First order motion model原理 First order motion model的任务是image animat
  • STM32——I2C通信理论基础(1)(学习笔记)

    STM32 I2C通信理论基础 硬件层 协议层 1 I2C基本读写过程 2 I2C通信的起始和停止信号 3 数据的有效性 4 响应 前言 我们在学习stm32的时候 要想学得更好 i2c协议的学习是必不可少的 现在很多的硬件 传感器等都是用
  • Vite2.0常见配置

    一 创建 1 创建 npm init vite latest my vue app template vue ts 查看 create vite 以获取每个模板的更多细节 vanilla vanilla ts vue vue ts reac
  • Win10-部署java环境教程

    一提到部署环境 不得不提到java环境 现如今java遍地走 python多如狗的世界里 如果不能在本地搭建一套java环境 都不好意思说自己是搞软件的 这里呢 给大家来分享一下 如何在一个新的机器上部署java环境 首先 java环境的配
  • FPGA零基础学习之Vivado-锁相环使用教程

    FPGA零基础学习之Vivado 锁相环使用教程 本系列将带来FPGA的系统性学习 从最基本的数字电路基础开始 最详细操作步骤 最直白的言语描述 手把手的 傻瓜式 讲解 让电子 信息 通信类专业学生 初入职场小白及打算进阶提升的职业开发者都
  • mybaties总结

    1 需要导入四个坐标 分别是mybatits junit log4j mysql connection java 2 连接数据库信息 配置mapper的位置 3 映射文件namespace对应的是接口全名 id是接口里面的方法名 resul
  • BUCK电路原理及PCB布局与布线注意事项

    1 BUCK架构 Buck架构 当开关闭合的时候 当开关断开的时候 根据伏秒平衡定理可得 Vin Vout DT Vout 1 D T gt Vin Vout D lt 1 在实际DCDC应用中 当Q1闭合的时候 在图1 a中 红线示出了当
  • Java面试——缓存

    一 什么是缓存 1 缓存就是数据交换的缓冲区 称作 Cache 当某一硬件要读取数据时 会首先从缓存汇总查询数据 有则直接执行 不存在时从内存中获取 由于缓存的数据比内存快的多 所以缓存的作用就是帮助硬件更快的运行 2 缓存往往使用的是RA
  • MMRotate:旋转框检测实现过程

    MMRotate 旋转框检测实现过程 MMRotate地址 https github com open mmlab mmrotate 文档地址 https mmrotate readthedocs io en latest 一 环境搭建 1