Day14 - CV项目实战:SAR飞机检测识别

论文原文:

​​​​​​SAR-AIRcraft-1.0:高分辨率SAR飞机检测识别数据集 - 中国知网

第一排的7张图片,普通人肉眼很难看出对应的是第二排的飞机。

还有上图里标注的飞机,外行根本看不明白,为什么这些是,其他的不是。作为一个外行,问题似乎很严峻,从图里根本识别不出来哪里是飞机,也没法标注。其实,在面对各行业问题的时候,经常会遇到这种问题,感觉可能搞不定。但是没关系,很多东西是反直觉的,这个任务真正做起来不难。

首先,目标检测的标注是非常重要的。

如何标注数据?

很多专业数据我们看不懂,标不了,没关系,这个其实是给行业专家来标注的。

新建项目文件夹 CVProject / label_demo /images --->用来放所有的图片

新建项目文件 CVProject / label_demo / classes.txt --->用来放所有的类别

论文里一共有七个类别的数据,我们将其写入到classes.txt文件中。

目标检测有三种经典数据格式

1. VOC:
  • .xml
  • xmin, ymin, xmax, ymax
  • 左上角,右下角
  • 绝对坐标(像素值)
python 复制代码
from xml.etree import ElementTree

# 解析XML文件
tree = ElementTree.parse(source="0000001.xml")
# 获取XML文件的根元素
root = tree.getroot()

# 获取图像路径
img_path = root.find(path="path").text
print(img_path)  # 输出图像路径

# 获取图像的宽度和高度
img_width = int(root.find(path="size").find(path="width").text)
img_height = int(root.find(path="size").find(path="height").text)
print(img_height, img_width)  # 输出图像的高度和宽度

# 遍历所有目标对象
for obj in root.findall(path="object"):
    # 获取目标名称
    print(obj.find("name").text)
    # 获取边界框的坐标
    xmin = int(obj.find("bndbox").find("xmin").text)
    ymin = int(obj.find("bndbox").find("ymin").text)
    xmax = int(obj.find("bndbox").find("xmax").text)
    ymax = int(obj.find("bndbox").find("ymax").text)
    print(xmin, ymin, xmax, ymax)  # 输出边界框的坐标
    print("-" * 80)  # 分割线

# 定义标签到索引的映射
label2idx = {
    "A330": 0, 
    "A320/321": 1, 
    "A220": 2, 
    "ARJ21": 3, 
    "Boeing737": 4, 
    "Boeing787": 5, 
    "other": 6
}

# 定义索引到标签的映射
idx2label = {idx: label for label, idx in label2idx.items()}
print(idx2label)  # 输出索引到标签的映射
2. YOLO
  • .txt
  • cls_id, x_center, y_center, w, h
  • 类别id,框中心点x坐标,框中心点y坐标,框宽度,框高度
  • 类别id:跟标注的顺序一致即可,从0开始
  • 相对坐标,百分比(跟x有关的都除以图像的宽度,跟y有关的都除以图像的高度)

YOLO官网:https://docs.ultralytics.com

用产品的心态去做技术 ,基本上你能想到的,都帮你实现了。

python 复制代码
# 定义函数,将VOC格式转换为YOLO格式
def transfer_yolo(file_name="./0000001.xml"):

    # 解析XML文件
    tree = ElementTree.parse(source=file_name)
    # 获取XML文件的根元素
    root = tree.getroot()
    
    # 获取图像的宽度和高度
    img_width = int(root.find(path="size").find(path="width").text)
    img_height = int(root.find(path="size").find(path="height").text)
    
    # 打开输出文件,准备写入YOLO格式的数据
    with open(file=file_name.replace(".xml", ".txt"), mode="w", encoding="utf8") as f:
        # 遍历每个目标对象
        for obj in root.findall(path="object"):
            # 获取目标名称
            name = obj.find("name").text
            # 获取目标类别的索引
            cls_id = label2idx.get(name)
            
            # 获取边界框的坐标
            xmin = int(obj.find("bndbox").find("xmin").text)
            ymin = int(obj.find("bndbox").find("ymin").text)
            xmax = int(obj.find("bndbox").find("xmax").text)
            ymax = int(obj.find("bndbox").find("ymax").text)
            
            # 计算边界框的中心点坐标
            x_center = round(number=(xmin + xmax) / 2 / img_width, ndigits=6)
            y_center = round(number=(ymin + ymax) / 2 / img_height, ndigits=6)
            
            # 计算边界框的宽度和高度
            box_width = round(number=(xmax - xmin) / img_width, ndigits=6)
            box_height = round(number=(ymax - ymin) / img_height, ndigits=6)
            
            # 将YOLO格式的数据写入文件
            print(cls_id, x_center, y_center, box_width, box_height, sep=" ", end="\n", file=f)

# 调用函数进行转换
transfer_yolo()
3. COCO
  • .json
  • x, y, width, height
  • x:中心点的 x 坐标
  • y:中心点的 y 坐标
  • width:框的宽度
  • height:框的高度
  • 原始坐标(像素值)
python 复制代码
import json

# 打开JSON文件,模式为只读,编码为UTF-8
with open(file="./0000001.json", mode="r", encoding="utf8") as f:
    # 读取文件内容并解析为Python对象(通常是字典或列表)
    data = json.loads(s=f.read())

# 获取第一个对象(假设data是一个列表,其中包含多个对象)
objs = data[0]

# 获取第一个对象的所有键
keys = objs.keys()
print(keys)  # 输出所有键

# 获取图像信息
image_info = objs["image"]
print(image_info)  # 输出图像信息

# 遍历标注信息
for obj in objs["annotations"]:
    # 获取标注的标签
    label = obj["label"]
    # 获取标注的坐标
    coordinates = obj["coordinates"]
    print(label)  # 输出标签
    print(coordinates)  # 输出坐标

训练相关的指标

  • Epoch:训练轮次(把所有数据都使用一遍,称为一轮)
  • GPU_mem:GPU的显存占用情况
  • box_loss:框的误差的损失
  • cls_loss:类别损失
  • dfl_loss:框与框之间比较的损失
  • Instances:本批次有多少个目标
  • Size:训练的图像大小
  • Box:
    • P :Precision 精准率 = TP / (TP + FP)
      • 误报
      • 预测出的正框有多少是真正的正框
      • 上图示例中检测出的A330飞机里,只有83.1%是真正的A330飞机,相当于误报16.9%
      • 图像分类很强调ACC,为什么目标检测没有ACC了,因为目标检测是严重负样本很多,所有的背景都是负样本
    • R :Recall 召回
      • 漏检
      • 代表正样本挖掘的能力
      • 比如测试集里有100个A330,其中能找出88.4个是A330,相当于漏检11.6%
    • mAP
      • Mean Average Precision 全类平均准确率
      • 比如上图中all这行,mean表示7个类别的平均,AP表示平均准确率
      • mAP的核心考察的是Precision精准率,主要是防误报
      • mAP50,其中的50表示IoU,这就涉及到了什么是正样本,什么是负样本的问题
      • mAP_0.5, mAP@0.5, mAP_0.5:0.95

一个目标检测的问题,什么叫预测对了呢?

目标检测输出2个东西,一个是类别概率,另一个是外围框。

所以即要把类别预测正确,又把框套的恰到好处,这才叫预测对了,这也就是TP(True正样本)。

mAP50表示框的类别对了,且跟真实的框交并比大于等于0.5,就算预测正确。

mAP50是最低要求。

如何计算两个框的交并比呢?即正确的框和预测的框的交集除以它们的并集。结果大于等于0.5就认为框预测正确。

mAP75表示框的类别对了,且与真实的框的交并比大于等于75,才算是预测正确,否则也算假样本。

mAP50-95表示会从50到90取几个样。

mAP后的数字越大,表示正样本的要求越严格。

相关推荐
不如语冰2 分钟前
跟着问题学2——传统神经网络-多层感知机详解
人工智能·python·深度学习·神经网络·机器学习·ai·语言模型
电子手信15 分钟前
知识库管理系统:企业数字化转型的加速器
大数据·人工智能
weixin_4483505023 分钟前
十堰市数据治理:大数据治理在智慧城市中的应用探索
大数据·人工智能·自动化·智慧城市·数据治理·数据提取
ai产品老杨1 小时前
通过全球最前沿的技术解决视频拼接中时延带来的的应用缺陷,使得全景视频拼接能够真正得以大范围使用和推广的智慧地产开源了。
vue.js·人工智能·安全·开源·音视频
好玩的Matlab(NCEPU)1 小时前
卡尔曼滤波器
人工智能·算法
TJMtaotao1 小时前
YOLO-SLD: An Attention Mechanism-ImprovedYOLO for License Plate Detection
人工智能·yolo
cuisidong19971 小时前
‌DNN(深度神经网络)和CNN(卷积神经网络)区别
人工智能·cnn·dnn
蒙娜丽宁1 小时前
【人工智能】从零开始用Python实现逻辑回归模型:深入理解逻辑回归的原理与应用
人工智能·python·逻辑回归
学不会lostfound1 小时前
三、计算机视觉_04AlexNet、VggNet、ResNet设计思想
人工智能·计算机视觉·resnet·alexnet·vggnet
柳鲲鹏1 小时前
OpenCV:VideoWriter.write()导致内存不断增长(未解决)
javascript·人工智能·opencv