语义分割实现地表建筑物识别1

本文介绍了通过遥感技术获取的航拍图像进行语义分割,以识别地表建筑的具体像素位置。首先,理解了图像分类、目标检测和语义分割的区别。接着,详细阐述了语义分割任务,包括数据的RLE编码和解码,以及数据预处理和模型训练的步骤。通过实例展示了如何读取和可视化数据,同时提供了建筑物像素的统计分析,如无建筑物像素比例、建筑物像素占比和平均区域大小。最后,给出了进一步优化模型的策略,如数据增强、使用更强模型和模型集成等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过对遥感技术获取的航拍图进行计算机视觉识别可以获取植被面积、建筑物检测等地表覆盖信息,是一项高效且意义重大的任务。本次任务是根据航拍图识别图片中的地表建筑具体像素位置。

知识准备——简述语义分割与其他视觉任务的区别

目前,我了解到的计算机视觉的任务包括图像分类(分辨猫狗)、目标检测(定位)、语义分割(地表建筑物识别)。
他们之间的关系可以在第12章视觉和语音找到解释,简而言之就是:

  • 图像分类是训练集包含K个类别的N个训练样本,学习各类特征获得一个分类器,最后用于预测新图像的类标签。重点是一个图对应一个标签
  • 目标检测是针对图像中的符合类别特征的多个对象进行定位的问题。像是在汽车检测中,必须使用边界框检测所给定图像中的所有汽车。
  • 语义分割是在图像按像素组聚类的基础上,进行语义标记。
  • 实例分割是在像素级识别对象轮廓的任务。是在语义分割的基础上给出属于各个实例的像素的行为。

赛题理解

赛题任务

  1. 赛题目标:通过地标建筑物识别入门语义分割的解题流程和模型
  2. 数据说明:图片是航拍图jpg,数据标签是图像像素类别(无建筑和有建筑)RLE编码字符串。
  3. 评价函数:
    在这里插入图片描述

解题思路

  • 步骤1:使用FCN模型跑通具体模型训练过程,并对结果进行预测提交
  • 步骤2:在现有基础上加入数据扩增方法,并划分验证集以监督模型精度;
  • 步骤3:使用更加强大模型结构(如Unet 和PSPNet)或尺寸更大的输入完成训练;
  • 步骤4:训练多个模型完成模型集成操作;

课后习题

1. RLE解码与编码

1.1 理解RLE编码过程

RLE(run-length encoding)算法的基本思路是对于连续重复数据块以【块数】+【数据块】的形式表达,从而达到节省存储空间的目的。RLE算法参考

RLE
'aaaaabccc'
5a1b3c

在语义分割任务中,RLE编码是对图片中连续的黑、白像素以不同的码字(0/1)进行编码,生成压缩的字符串形式。RLE解码则相反,将RLE字符串解析成图像掩膜(mask)。

import numpy as np

def rle_encode(im):
    '''将图片编码为rle格式'''
    pixels = im.flatten(order='F')
    pixels = np.concatenate([[0],pixels,[0]])
    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
    runs[1::2] -= runs[::2]
    return ' '.join(str(x) for x in runs)

def rle_decode(mask_rle,shape=(512,512)):
    '''将rle格式进行解码为图片'''
    if mask_rle is np.nan:
        return None
    s = mask_rle.split()
    starts,lengths = [np.asarray(x,dtype=int) for x in (s[0:][::2],s[1:][::2])]
    starts -= 1
    ends = starts + lengths
    img = np.zeros(shape[0]*shape[1],dtype=np.uint8)
    for lo,hi in zip(starts,ends):
        img[lo:hi] = 1
    return img.reshape(shape,order='F')
1.2 赛题数据读取并可视化
import cv2
import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt 
import albumentations as A

def add_mask2image_binary(img_path, mask=None):
    # Add binary masks to images 带掩膜效果的图片
    if img_path.endswith('.jpg') and mask is not None: 
        img = cv2.imread(img_path)
        masked = cv2.add(img, np.zeros(np.shape(img), dtype=np.uint8), mask=mask)  #将image的相素值和mask像素值相加得到结果
        # cv2图片格式转为RGB显示
        fig,ax = plt.subplots(1,2)
        ax[0].imshow(img[:,:,::-1])
        ax[1].imshow(masked[:,:,::-1])

train_mask = pd.read_csv('./train_mask.csv',sep='\t',names=['name','mask'])

for i in range(len(train_mask)):
    img_path = './train/'+train_mask['name'].iloc[i]
    img = cv2.imread(img_path)
    mask = rle_decode(train_mask['mask'].iloc[i])
    add_mask2image_binary(img_path, mask)
    if i > 3:
        break

在这里插入图片描述

2. 图片建筑物像素统计

  1. 统计所有图片整图中没有任何建筑物像素占所有训练集图片的比例
  2. 统计所有图片中建筑物像素占所有相似度的比例
  3. 统计所有图片中建筑物区域平均区域大小
def rle_mask_stats(x):
    if x is np.nan:
        return (None,None,None)
    mask = rle_decode(x) 
    return (mask.sum()/(mask.shape[0]*mask.shape[1]), mask.sum(),mask.shape[0]*mask.shape[1])

train_mask[['mask_01','mask_02','mask_03']] = train_mask['mask'].apply(rle_mask_stats).apply(pd.Series)
train_mask['mask_01'].hist(bins=500)

print('统计所有图片整图中没有任何建筑物像素占所有训练集图片的比例>>>')
print('1%%为没有任何建筑物阈值>>>%.3f'%train_mask['mask_01'].le(0.01).mean())
print('5%%为没有任何建筑物阈值>>>%.3f'%train_mask['mask_01'].le(0.05).mean())
print('10%%为没有任何建筑物阈值>>>%.3f'%train_mask['mask_01'].le(0.1).mean())

print('统计所有图片中建筑物像素占比比例>>>',train_mask['mask_01'].describe())
print('统计所有图片中建筑物区域平均区域大小>>>',train_mask['mask_02'].mean(),train_mask['mask_01'].mean())

参考

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值