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后的数字越大,表示正样本的要求越严格。

相关推荐
人类群星闪耀时14 分钟前
大模型技术优化负载均衡:AI驱动的智能化运维
运维·人工智能·负载均衡
编码小哥14 分钟前
通过opencv加载、保存视频
人工智能·opencv
发呆小天才O.oᯅ21 分钟前
YOLOv8目标检测——详细记录使用OpenCV的DNN模块进行推理部署C++实现
c++·图像处理·人工智能·opencv·yolo·目标检测·dnn
lovelin+v1750304096643 分钟前
智能电商:API接口如何驱动自动化与智能化转型
大数据·人工智能·爬虫·python
rpa_top44 分钟前
RPA 助力电商:自动化商品信息上传,节省人力资源 —— 以影刀 RPA 为例【rpa.top】
大数据·前端·人工智能·自动化·rpa
视觉语言导航1 小时前
arXiv-2024 | STMR:语义拓扑度量表示引导的大模型推理无人机视觉语言导航
人工智能·具身智能
深度学习lover1 小时前
<项目代码>YOLO Visdrone航拍目标识别<目标检测>
python·yolo·目标检测·计算机视觉·visdrone航拍目标识别
咯咯咯伦2 小时前
AI神了,一键视频下载+翻译+配音+字幕!(整合包)
人工智能
愚者大大2 小时前
优化算法(SGD,RMSProp,Ada)
人工智能·算法·机器学习