Tiff图像处理4_Python

数据清洗、数据筛选

这个,跑深度学习网络,数据肯定是个重头戏,有没有一个比较好的数据集,基本决定了这个网络的上下限。但是在咱处理的这个领域,能直接用的数据不算特别多。所以数据清洗和筛选的用处就体现出来了。
目前,做的工作就是两点。后续可能会增加,那么就再添加内容吧。

第一个就是,消除图像中的nan值。
首先提一下,通过数据类型转换过后的图像,应该是不存在nan值的。会在转换的时候,将非法值,比如无穷值,nan值等,手动的设置成0或者别的数。这样处理过的数据,就不需要,也查不出来nan值了。
由于我之前是在,数据类型转换之前,就跑了网络,因此会提示我有除法错误。
python :invalid value encountered in true_divide。
也就是说,可能0和nan值的存在,会影响我网络的求导和反馈。当然,我调高了epoch之后,会一定程度上减少这个问题。所以没有细究到底是什么因素,是不是nan的原因,导致了这个error。但是我的数据中,确实存在挺多nan值的(图像的四周,黑色的都是nan值,包括Landsat7影像中丢失的条带,也是nan值)。至于如何判断是不是nan的话,打开ArcGIS,用那个查看信息的小蓝球,点一下对应像素点就知道了。
在这里插入图片描述

沿着这么个思路,第一想法就是,把有nan值的patch块找出来,丢掉,其他的保存起来(这里想的是,将没有nan的另存为,出于几个因素,第一个就是,走的每一步,我都想把数据留下来不想删掉。第二个就是,如果全部都在原图上面修改,如果出了啥问题,又得重头开始返工,不划算。第三个就是懒得写删除的代码),反正磁盘存储空间够大。

# 检测tif图中是否含有NULL(nan)值
def detection_NULL(img_path):
    im_data, im_geotrans, im_proj = readTiff(img_path)
    # print(im_data)
    contain_nan = (True in np.isnan(im_data))  # 判断是否含NULL
    print(contain_nan)  # 打印检测结果
    return contain_nan  # True表示有NULL,False表示没有NULL
# 移除含nan值的tif图,将不含nan值的tif图另存为
def remove_NULL_image(src_img_path, src_mask_path, des_img_path, des_mask_path):
    dirs = os.listdir(src_img_path)  # 逐个读取文件名
    i = 0
    over_No = 36180  # 需要检测的图像的总数,根据需要自行设置
    for file_name in dirs:
        file_path = src_img_path + "/" + file_name  # 源img路径
        if (detection_NULL(file_path)):  # 如果有NULL,就跳过,筛除掉
            k = 0  # 空操作
        else:  # 如果没有NULL,就另存为
            im_data, im_geotrans, im_proj = readTiff(file_path)
            # print(file_path)
            # print(im_data.shape)
            writeTiff(im_data, im_geotrans, im_proj, des_img_path + "/" + file_name)  # 保存至目标img路径
            mask_path = src_mask_path + "/" + file_name  # 源mask路径
            im_data, im_geotrans, im_proj = readTiff(mask_path)
            writeTiff(im_data, im_geotrans, im_proj, des_mask_path + "/" + file_name)  # 保存至目标mask路径
            # print(mask_path)
        print(i)
        i = i + 1
        if i == over_No:  # 终止条件
            break
    print("remove over")

因为训练网络的数据集,本来就已经挺娇贵了。但是真实的数据中肯定含有很多脏数据,所以筛选nan这一关,可能在后续某个地方,还是会用到,应该不会因为我先进行了类型转换,这玩意就没用了。

第二个就是,筛掉过多的背景数据。
这个是我跑完网络之后,和远在他国的师兄讨论了之后,给我的建议。好吧,说的直接点就是网络效果不堪入目。秉持着,要利用到所有的数据,因为做的是二分类,非黑即白的操作。如果是白的,那就是白的。如果不是白的,比如红的绿的紫的蓝的,那都得是黑的。我就觉得,对啊,那红的绿的紫的蓝的,不也应该进行训练吗,不然万一被分成了白的,岂不是训练不够彻底。所以我把所有的数据,都丢进去了。但是效果并不好,原因就在于,本来我的待分类的数据,占整个patch图的比例,就已经不多了。
在这里插入图片描述
如果还将大量的,mask为黑的数据,丢到网络里去训练。这样数据就会很不均匀。当然训练的效果就好不到哪里去。查阅资料,找到了几个解决办法。将小分类的数据,进行过采样,大量重复复制,或者进行旋转,平移,翻转等等操作。但是这个会导致,重复的数据过多,形成过拟合的问题。另一个办法就是,将大分类的数据,进行欠采样。这个的前提是,数据样本要足够多。对于咱这个数据,patch图都上万了,应该不会差数据。。。之前做图像去噪的时候,基准数据集才3k多张。所以果断选择了欠采样进行尝试。也就是将patch图进行筛选,只要黑色像素大于某个比例,就让他滚蛋,剩下留下的都是精英。这样网络的训练效果,应该会提升一个档次。

# 移除黑色像素较多的tif图,将满足要求的其他tif图另存为
def remove_BLACK_image(src_img_path, src_mask_path, des_img_path, des_mask_path):
    dirs = os.listdir(src_img_path)  # 逐个读取文件名
    i = 0
    over_No = 36180  # 需要检测的图像的总数,根据需要自行设置
    pixel_num = 256*256  # 图像总像素个数,根据需要自行设置
    for file_name in dirs:
        file_path = src_img_path + "/" + file_name  # 源img路径
        im_data, im_geotrans, im_proj = readTiff(file_path)
        black_image = (im_data[0,::] == 0) * (im_data[1,::] == 0) * (im_data[2,::] == 0)  # 找到R,G,B三通道像素值都为0,即黑像素点的所有点,记为true,也就是1。
        # 如果tif图是是n(n>3)通道,则按n继续乘下去往后写即可。0是黑,255是白
        if (black_image.sum() > (pixel_num * 0.1)): # 计算出现的黑色像素总和,如果黑色像素点过多,就筛除掉,0.1为根据实际情况自行设置的,可根据需求进行调节
            print(black_image.sum())  # 输出黑色像素个数,也可不输出,反正这是个空操作
        else:  # 否则,就另存为
            im_data, im_geotrans, im_proj = readTiff(file_path)
            # print(file_path)
            # print(im_data.shape)
            writeTiff(im_data, im_geotrans, im_proj, des_img_path + "/" + file_name)  # 保存至目标img路径
            mask_path = src_mask_path + "/" + file_name  # 源mask路径
            im_data, im_geotrans, im_proj = readTiff(mask_path)
            writeTiff(im_data, im_geotrans, im_proj, des_mask_path + "/" + file_name)  # 保存至目标mask路径
            # print(mask_path)
        print(i)
        i = i + 1
        if i == over_No:  # 终止条件
            break
    print("remove over")

根据代码可以看到,我这里是对img进行的操作,而不是对mask进行的操作。因为现在还比较仁慈,对img进行去黑的操作,目的是去除边缘和条带黑色像素(经过拉伸之后,边缘和丢失的条带都为黑)占比多的patch,保留了img中,原始的地形地貌。
如果是对mask进行筛选,则只会保留白色像素占比多的图像对。可能后续会进行这样的操作,对数据集做进一步的精细化。但是目前还没有的原因是,怕数据量不够大,所以先仁慈操作,看看效果如何再说。
和师兄讨论的结果是,大分类的数据,也就是背景数据,最好是不要超过小分类数据的3倍,不然效果可能会比较差。就当做一个经验知识记下来了。

另一个就是,在这里又学到了一个操作:

im_data[0,::] == 0

这样做可以对某一个band的这个二维矩阵中的所有值进行判断。如果是0,则这个值被标为true。省去了大量的用双for循环进行判断的时间。

读、写参考1,复制粘贴即可。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值