Python|遥感影像语义分割:数据集清洗
前言
在将遥感图像进行分割后,我们得到了label集与image集,但此时数据集的图片数目太多,因为我仅需要实现梯田的提取,所以存在大量的无用的数据,因此在label集中根据包含目标地物的比例对label集进行数据清洗,再根据label集删除image集中没有标签的数据。
代码实现
(1)删除label集中的所有目标地物占比小于给定阈值的图像
因为数据集存在大量冗余,因此我需要删除所有目标地物占比小于给定阈值的图像,实际上因为二分类的标签图像中的值仅有0和1,我可以直接使用countNonZero函数来解决这个问题,clean_label这个函数,输入两个参数,为图像和目标地物所占百分比,具体代码如下:
import cv2
import os
import glob
path = r'D:/Data_Clean/croplabel'
percent = 0.3
'''这里我要删除所有目标地物占比小于给定阈值的图像,实际上因为二分类的标签图像中的值仅有0和1,我可以直接使用countNonZero函数来解决这个问题
clean_label这个函数,输入两个参数,为图像和目标地物所占百分比'''
def clean_label(labelpath, percent):
path = labelpath
paths = glob.glob(os.path.join(path, '*.tif'))
img1 = cv2.imread(paths[0])
threshol = percent
imgshape = img1.shape
count = imgshape[0] * imgshape[1] * threshol
for file in paths:
img = cv2.imread(file, 0)
if cv2.countNonZero(img) <= count:
os.remove(file)
clean_label(path, percent)
(2)根据label文件删除image文件
在label集进行数据清洗之后,我们需要根据label集中的文件来删除image集中的图片,即删除image集中没有对应label的图像,代码如下:
import os
labelpath = r'D:\Data_Clean\imgs'
imgpath = r'D:\Data_Clean\masks'
def clean_image(labelpath,imgpath):
list1 = os.listdir(labelpath)
file_list1 = [] #label中的文件名列表 不带后缀
for i in list1:
file_list1.append(os.path.splitext(i)[0])
list2 = os.listdir(imgpath)
file_list2 = [] #image中的文件名列表 不带后缀
for i in list2:
file_list2.append(os.path.splitext(i)[0])
#找出没有标注的图片名称列表
b = [y for y in file_list2 if y not in file_list1]
#把这些列表加上扩展名 然后将其删除
path = imgpath
for i in b:
os.remove(os.path.join(path, i+'.tif'))
clean_image(labelpath,imgpath)
(3)转换图片格式
因为我的数据集中标签为png格式图片,但裁剪后得到的标签为tif格式图片,因此需要对标签的格式进行转换,代码如下:
import os
from PIL import Image as img
from tqdm import tqdm
#labelpath = 'labels/' # 待转换格式的图片所在文件夹
#labelpath2 = 'masks/' # 转换后的图片存储路径
def convert_image(path,path2):
files = os.listdir(path)
for n, filename in tqdm(enumerate(files), total=len(files)):
png = img.open(path + filename)
file_string = os.path.splitext(filename)[0]
temp = file_string.split('.') # 在 ‘.’ 处分割字符串
png.save(path2 + temp[0] + ".png") # 转换jpg格式就写 “.jpg”