通过Inception V3神经网络对遥感影像建筑区域进行提取

#整体思路

  • 训练数据测试数据获取

    通过LSV遥感影像下载平台对训练集测试集数据进行下载之后通过image_make.py对下载好的.tif影像进行格式转换,将其转换为.jpg图像,之后对其进行图像大小转换以及图像分割,通过接近二十多次的验证发现128*128像素大小的图像训练出来的模型对遥感影像的贴合度最好。下面是数据集转换的代码

from PIL import Image
import numpy as np
import tensorflow as tf
import os,shutil
import warnings
import matplotlib.pyplot as plt

# tif转jpg图像
def tif_to_jpg(tif_path,jpg_path):
    im=Image.open(tif_path)
    im.save(jpg_path)
    print('success turn file')

# jpg图像大小转换
def jpg_cut_shape(jpg_path):
    im=Image.open(jpg_path)
    heigh,weigh=im.size
    H=(int(heigh/128)+1)*128
    W=(int(weigh/128)+1)*128
    im=im.resize((H,W))
    im.save(jpg_path)
    print('success reshape file')
    return int(H/128),int(W/128)

# jpg图像切割
def jpg_cut_image(H,W,jpg_path,cut_dir,name):
    flag=0
    for i in range(H):
        for j in range(W):
            print("\rcutting:[{0:.3}%]".format(flag/H/W*100),end="")
            save_path=os.path.join(cut_dir+str(name)+'.jpg')
            shutil.copy(jpg_path,save_path)
            im=Image.open(save_path)
            im=im.crop((i*128,j*128,(i+1)*128,(j+1)*128))
            im.save(save_path)
            name+=1
            flag+=1
    print('\nsuccessful cut image')
    return name

if __name__ == "__main__":
    # tif图像保存位置
    tifpath='C:/file/tif/'
    # jpg图像保存位置
    jpgpath='C:/file/jpg/'
    # 切割后图像保存位置
    cut_dir='C:/file/chapter_3/data_prepare/pic/train/country/'
    Dir=os.listdir(tifpath)
    name=1
    for dir in Dir:
        tif_path=os.path.join(tifpath,dir)
        jpg_path=jpgpath+'a.jpg'
        print(tif_path,jpg_path)
        tif_to_jpg(tif_path, jpg_path)
        H,W=jpg_cut_shape(jpg_path)
        name=jpg_cut_image(H,W,jpg_path,cut_dir,name)
        print(name)

图像数据集tfrecord制作

  • TFRecord内部使用了“Protocol Buffer”二进制数据编码方案,它只占一个内存块,只需要一次性加载一个二进制文件的方式即可,简单,快速,尤其对大型训练数据很友好。而且当我们的训练数据量比较大的时候,可以将数据分成多个TFRecord文件,来提高处理效率,下面是将图像数据集转为tfrecord格式的代码,代码在Slim中已经写好了。通过运行命令在相应文件夹下生成以下三个文件
  • python data_convert.py -t pic/ --train-shards 1 --validation-shards 1 --num-threads 1 --dataset-name city_coun
    第一个文件为训练集.tfrecord 第二个文件为测试集tfrecord 第三个文件为标签文件
    第一个文件为训练集.tfrecord;第二个文件为测试集tfrecord;第三个文件为标签文件
    以下为生成tfrecord部分代码展示
# coding:utf-8
from __future__ import absolute_import
import argparse
import os
import logging
from src.tfrecord import main

# #获取命令行输入
def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument('-t', '--tensorflow-data-dir', default='pic/')
    parser.add_argument('--train-shards', default=2, type=int)
    parser.add_argument('--validation-shards', default=2, type=int)
    parser.add_argument('--num-threads', default=2, type=int)
    parser.add_argument('--dataset-name', default='satellite', type=str)
    return parser.parse_args()

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    args = parse_args()
    args.tensorflow_dir = args.tensorflow_data_dir
    args.train_directory = os.path.join(args.tensorflow_dir, 'train')
    args.validation_directory = os.path.join(args.tensorflow_dir, 'validation')
    args.output_directory = args.tensorflow_dir
    args.labels_file = os.path.join(args.tensorflow_dir, 'label.txt')
    if os.path.exists(args.labels_file) is False:
        logging.warning('Can\'t find label.txt. Now create it.')
        all_entries = os.listdir(args.train_directory)
        dirnames = []
        for entry in all_entries:
            if os.path.isdir(os.path.join(args.train_directory, entry)):
                dirnames.append(entry)
        with open(args.labels_file, 'w') as f:
            for dirname in dirnames:
                f.write(dirname + '\n')
    main(args)

训练阶段

-训练采用通过对Inception V3模型进行重新训练的方式训练模型,训练模型命令如下

python train_image_classifier.py \
  --train_dir=city_coun/train_dir \  # 训练tfrecord目录
  --dataset_name=city_coun \  # 模型存放目录
  --dataset_split_name=train \  # 训练分割
  --dataset_dir=city_coun/data \ # 数据存放
  --model_name=inception_v3 \ # 模型名称
  --checkpoint_path=city_coun/pretrained/inception_v3.ckpt \ # 模型训练后节点
  --checkpoint_exclude_scopes=InceptionV3/Logits,InceptionV3/AuxLogits \ # 抛弃最后一层并训练所有层
  --max_number_of_steps=5000 \ # 训练步数
  --batch_size=16 \ #每次训练喂入图像数
  --learning_rate=0.001 \ #初始学习率
  --learning_rate_decay_type=fixed \ # 学习率固定
  --save_interval_secs=1000 \ #每1000秒保存一次模型
  --save_summaries_secs=1000 \ # 每1000秒保存一次事件
  --log_every_n_steps=1 \ 每步都显示loss
  --optimizer=adam \ #adam优化器 
  --weight_decay=0.00004 # 正则化学习参数

训练过程图像以及生成的模型文件在这里插入图片描述
模型文件在这里插入图片描述

训练模型结果验证

-通过5000次迭代后得到训练模型.ckpt;.index ; meta文件对其精度进行测试,测试命令如下:


python eval_image_classifier.py \
  --checkpoint_path=city_coun/train_dir/model.ckpt-1674 \ # 数字为选用模型步数
  --eval_dir=city_coun/eval_dir \ #保存事件
  --dataset_name=city_coun \ # 保存目录
  --dataset_split_name=validation \ #验证集名称
  --dataset_dir=city_coun/data \ #事件写入
  --model_name=inception_v3 #模型名称

最终得到的精度如下为0.99达到预期精度后停止训练
在这里插入图片描述

模型应用

-首先通过以下命令将模型文件转化为.pb文件命令如下:

python export_inference_graph.py \
  --alsologtostderr \
  --model_name=inception_v3 \
  --output_file=city_coun/inception_v3_inf_graph.pb \
  --dataset_name city_coun


python freeze_graph.py \
  --input_graph slim/city_coun/inception_v3_inf_graph.pb \
  --input_checkpoint slim/city_coun/train_dir/model.ckpt-1605 \
  --input_binary true \
  --output_node_names InceptionV3/Predictions/Reshape_1 \
  --output_graph slim/city_coun/frozen_graph.pb


生成pb文件如下
在这里插入图片描述

通过pb文件对影像进行验证

-以下是验证代码

from PIL import Image
import numpy as np
import tensorflow as tf
import os,shutil
import warnings
import matplotlib.pyplot as plt

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
warnings.filterwarnings("ignore")

# tif转jpg
def tif_to_jpg(tif_path,jpg_path):
    im=Image.open(tif_path)
    im.save(jpg_path)
    print('success turn file')
# jpg大小转换
def jpg_cut_shape(jpg_path):
    im=Image.open(jpg_path)
    heigh,weigh=im.size
    H=(int(heigh/128)+1)*128
    W=(int(weigh/128)+1)*128
    im=im.resize((H,W))
    im.save(jpg_path)
    print('success reshape file')
    return int(H/128),int(W/128)
# 图像输入网络前处理
def preprocess_for_eval(image, height, width,central_fraction=0.875, scope=None):
  with tf.name_scope(scope, 'eval_image', [image, height, width]):
    if image.dtype != tf.float32:
      image = tf.image.convert_image_dtype(image, dtype=tf.float32)
    if central_fraction:
      image = tf.image.central_crop(image, central_fraction=central_fraction)
    if height and width:
      image = tf.expand_dims(image, 0)
      image = tf.image.resize_bilinear(image, [height, width],align_corners=False)
      image = tf.squeeze(image, [0])
    image = tf.subtract(image, 0.5)
    image = tf.multiply(image, 2.0)
    return image
# 还原计算图
def make_graph(pb_path):
    with tf.gfile.FastGFile(pb_path, 'rb') as f:
        graph_def = tf.GraphDef()
        graph_def.ParseFromString(f.read())
        tf.import_graph_def(graph_def, name='')
# 图像验证
def image_estimate(jpg_save_Dir):
    with tf.Session() as sess:
        num=len(os.listdir(jpg_save_Dir))
        list=[]
        for i in range(num):
            print("\rdeciding:[{0:.3}%]".format(i/num*100),end="")
            imgpath=jpg_save_Dir+str(i+1)+'.jpg'
            image_data = tf.gfile.FastGFile(imgpath, 'rb').read()
            image_data = tf.image.decode_jpeg(image_data)
            image_data = preprocess_for_eval(image_data, 299, 299)
            image_data = tf.expand_dims(image_data, 0)
            softmax_tensor = sess.graph.get_tensor_by_name('InceptionV3/Logits/SpatialSqueeze:0')
            image_in = sess.run(image_data)
            predictions = sess.run(softmax_tensor, {'input:0': image_in})
            if predictions[0][0] >= predictions[0][1]:
                list.append('city')
            else:
                list.append('country')
    print('success decide')
    return list
# 图像切割
def jpg_cut_image(H,W,jpg_path,cut_dir):
    name=1
    m='#'
    for i in range(H):
        for j in range(W):
            print("\rcutting:[{0:.3}%]".format(name/H/W*100),end="")
            save_path=os.path.join(cut_dir+str(name)+'.jpg')
            shutil.copy(jpg_path,save_path)
            im=Image.open(save_path)
            im=im.crop((i*128,j*128,(i+1)*128,(j+1)*128))
            im.save(save_path)
            name+=1
    print('\nsuccessful cut image')
    return 0
# 生成图像转化结果可视化
def make_pic(list,H,W,pic_path):
    im=Image.open(pic_path)
    flag=0
    pixTuple = (255, 0, 255, 15)
    for i in range(H):
        for j in range(W):
            print("\rmaking:[{0:.3}%]".format(flag/ H / W * 100), end="")
            if list[flag]== 'city':
                for x in range(i * 128, (i + 1) * 128):
                    for y in range(j * 128, (j + 1) * 128):
                        im.putpixel((x, y), pixTuple)
            else:
                pass
            flag += 1
    im.save(pic_path)
    print('Get result success')
    return 0
# 读取保存的分类文件
def read_list(list_path):
    fd=open(list_path)
    lines=fd.readlines()
    list1=[]
    for line in lines:
        list1.append(line.strip())
    print('successly read list')
    return list1
# 保存分类结果
def write_list(list,list_path):
    fd = open(list_path, 'w')
    for key in list:
        fd.write(key+'\n')
    print('successful write list')
    return 0
# 移除生成无效文件
def remove_file(path):
    Dir=os.listdir(path)
    for dir in Dir:
        file=os.path.join(path,dir)
        os.remove(file)
    print('successful remove files')

tif_path='C:/file/1.tif'
jpg_path='C:/file/1.jpg'
pb_path="C:/file/chapter_3/slim/city_coun/frozen_graph.pb"
jpg_save_path='C:/file/2.jpg'
cut_dir='C:/file/jpg/'
list_path='C:/file/1.txt'

if __name__ == "__main__":
    tif_to_jpg(tif_path, jpg_path)
    H,W=jpg_cut_shape(jpg_path)
    jpg_cut_image(H, W, jpg_path, cut_dir)
    make_graph(pb_path)
    list=image_estimate(cut_dir)
    write_list(list,list_path)
    list=read_list(list_path)
    make_pic(list,H,W,jpg_path)
    remove_file(cut_dir)

运行结果如下:
在这里插入图片描述
原图像
在这里插入图片描述
程序判断后图像
在这里插入图片描述
可以看到程序完美运行,精度较高。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值