【Keras】基于SegNet和U-Net的遥感图像语义分割(一)

数据集的处理:gen_data.py

代码:
https://github.com/fuyou123/Segmentation_Unet
【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第1张图片

数据集 链接:https://pan.baidu.com/s/1AmEKP5e4mtC1TjLeCLodLg 提取码:6sor

(说明:切割好的数据集:train、test 由于空间较大,下载会很慢。因此下载可以下载原图:unet-buildings,然后借助分割函数切割。
原图链接:链接:https://pan.baidu.com/s/1y0D-SiP9FKYce-oHvJ912w 提取码:ta8j )
【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第2张图片
接下来介绍如何对原数据集(unet_buildings)进行处理,处理函数为./unet/gen_dataset.py

src_img = cv2.imread('./data/src/' + image_sets[i])  # 3 channels
label_img = cv2.imread('./data/label/' + image_sets[i],cv2.IMREAD_GRAYSCALE)#single channel
X_height,X_width,_ = src_img.shape

【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第3张图片
其中单通道的Lable影像看上去是黑色的,其实不然。那是由于像素值的区间范围在0~4之间,看不出区别。但是可以通过专业软件看图,如Arcgis软件(对于它的说明,我的博客中有介绍):
【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第4张图片

 random_width = random.randint(0, X_width - img_w - 1)
 random_height = random.randint(0, X_height - img_h - 1)
 src_roi = src_img[random_height: random_height + img_h, random_width: random_width + img_w,:]
 label_roi = label_img[random_height: random_height + img_h, random_width: random_width + img_w]

我们现在拥有的是5张大尺寸的遥感图像,我们不能直接把这些图像送入网络进行训练,因为内存承受不了而且他们的尺寸也各不相同。因此,我们首先将他们做随机切割,切割的思想是,在红色框内随机生成x,y坐标(红点)作为切割小图(黄色框)的左上角位置。
【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第5张图片
然后对切割出来的256*256小图,做以下数据增强操作:

  1. 原图和label图都需要旋转:90度,180度,270度
    【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第6张图片
def rotate(xb,yb,angle):
    #cv2.getRotationMatrix2D(),这个函数需要三个参数,旋转中心,旋转角度,旋转后图像的缩放比例
    M_rotate = cv2.getRotationMatrix2D((img_w/2, img_h/2), angle, 1)
    #cv2.warpAffine()仿射变换,参数src - 输入图像  M - 变换矩阵(一般反映平移或旋转的关系)  dsize - 输出图像的大小  flags - 插值方法的组合 。。。
    xb = cv2.warpAffine(xb, M_rotate, (img_w, img_h))
    yb = cv2.warpAffine(yb, M_rotate, (img_w, img_h))
    return xb,yb
  1. 原图和label图都需要做沿y轴的镜像操作
    【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第7张图片
if np.random.random() < 0.25:
    # cv2.flip(),第二个参数:1水平翻转  0垂直翻转  -1水平垂直翻转
    xb = cv2.flip(xb, 1)  
    yb = cv2.flip(yb, 1)
  1. 原图做模糊操作
    【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第8张图片
 def blur(img):
    # cv2.blur(均值滤波),参数说明:img表示输入的图片, (3, 3) 表示进行均值滤波的方框大小
    # 均值滤波是用每个像素和它周围像素计算出来的平均值替换图像中每个像素
    img = cv2.blur(img, (3, 3));
    return img
  1. 原图做光照调整操作
    在某些情况下,一副图像中大部分像素的强度都集中在某一区域,而质量较高的图像中,像素的强度应该均衡的分布。为此,可将表示像素强度的直方图进行拉伸,将其平坦化。如下:
    【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第9张图片
    【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第10张图片
def gamma_transform(img, gamma):
    gamma_table = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)]
    gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
    return cv2.LUT(img, gamma_table)

def random_gamma_transform(img, gamma_vari):
    log_gamma_vari = np.log(gamma_vari)
    alpha = np.random.uniform(-log_gamma_vari, log_gamma_vari)
    gamma = np.exp(alpha)
    return gamma_transform(img, gamma)
  1. 原图做增加噪声操作(高斯噪声,椒盐噪声)
    【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第11张图片
 def add_noise(img):
    for i in range(200): #添加点噪声
        temp_x = np.random.randint(0,img.shape[0])
        temp_y = np.random.randint(0,img.shape[1])
        img[temp_x][temp_y] = 255  #255白色 
    return img

最终的结果:
【Keras】基于SegNet和U-Net的遥感图像语义分割(一)_第12张图片

给出遥感影像的一些数据集:
链接:https://pan.baidu.com/s/1eTQl_ggygF2NeNkh6ElV-w 提取码:ywdk
网址:https://www.zhihu.com/question/365151909 (里面也有)

个人说明:我写博客的目的,是为了方便自己做笔记。对于数据集中出现的标注问题,我暂时先不管它的,我关注的算法的原理实现与改进,为此很抱歉。

你可能感兴趣的:(图像语义分割)