目前已经有一些已经关于遥感影像解译的公开数据集,我们可以拿这些数据来做深度学习模型训练,但是在实际业务中,我们需要针对特定的需求制作自己的数据集,在这里记录一下做遥感影像数据集的一些方法和注意事项。
常见的图片标签工具大都是针对相机照片,如labelImg、PS等。但是在做大影像标注时会不太方便,如一景遥感影像的像素往往会几万乘几万,一种方法是先整景影像进行分割,如切割成512x512、1024x1024等大小,然后用上述工具进行标注,但是这样做会无法保证整景影像的标注一致性,一些大的目标会被分割在两个小块的图像上,不同的标注人员可能会将这两个部分标注成不同的目标,或者切割后的图片失去整体的上下文信息,例如在区分耕地和普通植被,或者颜色偏绿的水体时会在不同的分块图片上造成歧义,如果是在一整景完整的影像上进行标注就不会出现上述问题,标注人员可以根据整景影像的特点判断当前有歧义的位置,所以建议在自己做遥感影像标注的时候可以考虑使用ArcGIS或者QGIS进行标注。
考虑到GPU显存的限制,影像标注完成之后在送入模型训练之前需要对大的影像进行分块,一般采用的是滑动叠加窗口的方法进行分块。代码如下
分块代码
#!usr/bin/env python
# -*- coding: utf-8 -*-
"""
@Author : zhaoguanhua
@Email :
@Time : 2021/8/15 17:13
@File : clip_image.py
@Software: PyCharm
"""
import cv2 as cv
import os
import glob
import numpy as np
def clip_image_by_order(image_path,label,clip_dir):
"""
按照从左到右,从上到下,有重叠的裁剪图像
:param image_path: 大图像路径
:param label: 大图像标签路径
:param clip_dir: 切割后的小图像和标签存储路径
:return:
"""
image_array=cv2.imread(image_path,1)
label_array=cv2.imread(label,0)
(img_rows,img_cols,_)=image_array.shape
(label_rows,label_cols)=label_array.shape
assert (img_rows==label_rows) and (img_cols==label_cols),\
"{}:图像和标签尺寸不一致,请检查图像和标签:".format(image_path)
#图像名
image_name=os.path.basename(image_path).split(".")[0]
#创建切割图像、标签文件夹
clip_image_dir=os.path.join(clip_dir,"img")
os.makedirs(clip_image_dir,exist_ok=True)
clip_label_dir=os.path.join(clip_dir,"label")
os.makedirs(clip_label_dir,exist_ok=True)
lt_row=0 #起始行
while lt_row<img_rows:
lt_col=0 #起始列
if lt_row+clip_size>img_rows:
clip_height=img_rows-lt_row
else:
clip_height=clip_size
while lt_col<img_cols:
if lt_col+clip_size>img_cols:
clip_width=img_cols-lt_col
else:
clip_width=clip_size
#切割图片名
clip_name="{img_name}_{row}_{col}_size{size}.png".format(
img_name=image_name,row=lt_row,col=lt_col,size=clip_size)
#切割图像、标签存储路径
clip_image_path=os.path.join(clip_image_dir,clip_name)
clip_label_path=os.path.join(clip_label_dir,clip_name)
out_img_array=np.ones((clip_size,clip_size,3))*255
out_label_array=np.zeros((clip_size,clip_size))
out_img_array[:clip_height,:clip_width,:]=image_array[lt_row:lt_row+clip_height,lt_col:lt_col+clip_width,:]
out_label_array[:clip_height,:clip_width]=label_array[lt_row:lt_row+clip_height,lt_col:lt_col+clip_width]
cv2.imwrite(clip_image_path,out_img_array)
cv2.imwrite(clip_label_path,out_label_array)
lt_col+=slip_window
lt_row+=slip_window
if __name__ == '__main__':
root_dir=r""
image_dir=os.path.join(root_dir,"img")
label_dir=os.path.join(root_dir,"label")
clip_dir=os.path.join(root_dir,"clip")
os.makedirs(clip_dir,exist_ok=True)
image_names=os.listdir(image_dir)
#切割尺寸
clip_size=1024
#滑动窗口
slip_window=clip_size//2
for image_name in image_names:
print(image_name)
image_file=os.path.join(image_dir,image_name)
label_file=os.path.join(label_dir,image_name)
clip_image_by_order(image_file,label_file,clip_dir)