首先看util.py

part1

从文件读取数据

def read_data(path):
     with h5py.File(path, 'r') as hf:
         data = np.array(hf.get('data'))
         label = np.array(hf.get('label'))
        return data, label

规整图片的边界

先看代码

def modcrop(image, scale=3):
  if len(image.shape) == 3:
    h, w, _ = image.shape
    h = h - np.mod(h, scale)  #mod的作用是取余数,这里返回的是h除以scale后得到的余数
    w = w - np.mod(w, scale)  #同上
    image = image[0:h, 0:w, :]
  else:
    h, w = image.shape
    h = h - np.mod(h, scale)
    w = w - np.mod(w, scale)
    image = image[0:h, 0:w]
  return image

这个分为两部分一个是处理三维的,也就是彩色的,一个是处理灰色的,也就是两维的,这个说法是错误的。
对于这个代码的处理都是灰色的,如果你传入的是三维的图片,也就是你传入的是彩色的话,我们会将只去它的一个通道。如果是二维的,也就是灰色的,就不需要执行上面的步骤了,因为这个时候只有一个通道
我们以彩色图片为例子

if len(image.shape) == 3:
    h, w, _ = image.shape
    h = h - np.mod(h, scale)
    w = w - np.mod(w, scale)  #同上
    image = image[0:h, 0:w, :]

我们这个是为图片缩小三倍做准备,但是我们又担心它可能无法被三整除,所以一上来要先减去余数,以后做除法的时候可以整除,对图片的长和宽都进行这样的操作

读取图片

def imread(path, is_grayscale=True):
  if is_grayscale:
    return scipy.misc.imread(path, flatten=True, mode='YCbCr').astype(np.float)
  else:
    return scipy.misc.imread(path, mode='YCbCr').astype(np.float)

根据路径读取图片,当然这里有一个选项,第一个选项是针对三维的彩色图像的,第二个选项是针对二维的灰色图像的

预处理图片

def preprocess(path, scale=3):#定义预处理函数
  image = imread(path, is_grayscale=True)
  label_ = modcrop(image, scale)  #对图像进行缩放操作

  # Must be normalized
  image = image / 255.
  label_ = label_ / 255. #归一化操作

  input_ = scipy.ndimage.interpolation.zoom(label_, (1./scale), prefilter=False)  #先把labei即清晰的原图变模糊,没有使用预滤波
  input_ = scipy.ndimage.interpolation.zoom(input_, (scale/1.), prefilter=False)  #再把变模糊的图像放大,没有使用预滤波

  return input_, label_

首先是调用我们读取图片的函数,上面已经解释过了,默认是灰色的,然后就是将图片变得可以被scale整除,接下来进行归一化的操作,这个在吴恩达的作业中这样操作过。

 input_ = scipy.ndimage.interpolation.zoom(label_, (1./scale), prefilter=False) 
 input_ = scipy.ndimage.interpolation.zoom(input_, (scale/1.), prefilter=False)  

input_:图像应用双三次插值(低分辨率),选变模糊然后在放大
标签_:原始分辨率图像(高分辨率)
经过双两次差值的计算之后,这个时候的图片就是灰色的,低分辨率的图片了
input和label分别表示输入的图片和输出的图片

选择数据集

def prepare_data(sess, dataset):
  if FLAGS.is_train:
    filenames = os.listdir(dataset)
    data_dir = os.path.join(os.getcwd(), dataset)   #路径拼接
    data = glob.glob(os.path.join(data_dir, "*.bmp")) #路径查询匹配,返回所有匹配的文件路径列表
  else:
    data_dir = os.path.join(os.sep, (os.path.join(os.getcwd(), dataset)), "Set5")
    data = glob.glob(os.path.join(data_dir, "*.bmp"))
  return data

是选择数据集还是选择测试集

制作数据

def make_data(sess, data, label):
   if FLAGS.is_train:
    savepath = os.path.join(os.getcwd(), 'checkpoint/train.h5')#如果是训练的话,拼接存储的文件路径
 #os.getcwd()表示当前进程的工作路径 
  else:
    savepath = os.path.join(os.getcwd(), 'checkpoint/test.h5')

  with h5py.File(savepath, 'w') as hf:
    hf.create_dataset('data', data=data)
    hf.create_dataset('label', data=label)

创建一个h5格式的数据集

part2

分割大图片

def input_setup(sess, config):
  # Load data path
  if config.is_train:
    data = prepare_data(sess, dataset="Train")
  else:
    data = prepare_data(sess, dataset="Test")

  sub_input_sequence = []
  sub_label_sequence = []
  padding = abs(config.image_size - config.label_size) / 2 # 6

  if config.is_train: 
    for i in range(len(data)):#一幅图作为一个data
      input_, label_ = preprocess(data[i], config.scale)#得到data[]的LR和HR图input_和label_
      if len(input_.shape) == 3:
        h, w, _ = input_.shape
      else:
        h, w = input_.shape
      #把input_和label_分割成若干自图sub_input和sub_label
      for x in range(0, h-config.image_size+1, config.stride):
        for y in range(0, w-config.image_size+1, config.stride):
          sub_input = input_[x:x+config.image_size, y:y+config.image_size] # [33 x 33]
          sub_label = label_[x+padding:x+padding+config.label_size, y+padding:y+padding+config.label_size] # [21 x 21]
          sub_input = sub_input.reshape([config.image_size, config.image_size, 1])#按image size大小重排 因此 imgae_size应为33 而label_size应为21
          sub_label = sub_label.reshape([config.label_size, config.label_size, 1])
          sub_input_sequence.append(sub_input)#在sub_input_sequence末尾加sub_input中元素 但考虑为空
          sub_label_sequence.append(sub_label)
  else:
        #测试
        input_, label_ = preprocess(data[0], config.scale)#测试图片
        if len(input_.shape) == 3:
          h, w, _ = input_.shape
        else:
          h, w = input_.shape
        nx = 0 #后注释
        ny = 0 #后注释
        #自图需要进行合并操作
        for x in range(0, h-config.image_size+1, config.stride): #x从0到h-33+1 步长stride(21)
          nx += 1
          ny = 0
          for y in range(0, w-config.image_size+1, config.stride):#y从0到w-33+1 步长stride(21)
            ny += 1
            #分块sub_input=input_[x:x+33,y:y+33]  sub_label=label_[x+6,x+6+21, y+6,y+6+21]
            sub_input = input_[x:x+config.image_size, y:y+config.image_size] # [33 x 33]
            sub_label = label_[x+padding:x+padding+config.label_size, y+padding:y+padding+config.label_size] # [21 x 21] 
            sub_input = sub_input.reshape([config.image_size, config.image_size, 1])  
            sub_label = sub_label.reshape([config.label_size, config.label_size, 1])
            sub_input_sequence.append(sub_input)
            sub_label_sequence.append(sub_label)
  # 上面的部分和训练是一样的
  arrdata = np.asarray(sub_input_sequence) # [?, 33, 33, 1]
  arrlabel = np.asarray(sub_label_sequence) # [?, 21, 21, 1]
  make_data(sess, arrdata, arrlabel)#存成h5格式
  if not config.is_train:
    return nx, ny 

代码量过多,分为几部分来看

  if config.is_train:
    data = prepare_data(sess, dataset="Train")
  else:
    data = prepare_data(sess, dataset="Test")

  sub_input_sequence = []
  sub_label_sequence = []
  padding = abs(config.image_size - config.label_size) / 2 # 6

根据选项取不同的数据集,然后取一个padding。
两个分支的内容大致相同,只不过取的数据集是不同的

 if config.is_train:
    for i in range(len(data)):#一幅图作为一个data
      input_, label_ = preprocess(data[i], config.scale)#得到data[]的LR和HR图input_和label_
      if len(input_.shape) == 3:
        h, w, _ = input_.shape
      else:
        h, w = input_.shape
      #把input_和label_分割成若干自图sub_input和sub_label
      for x in range(0, h-config.image_size+1, config.stride):
        for y in range(0, w-config.image_size+1, config.stride):
          sub_input = input_[x:x+config.image_size, y:y+config.image_size] # [33 x 33]
          sub_label = label_[x+padding:x+padding+config.label_size, y+padding:y+padding+config.label_size] # [21 x 21]
          sub_input = sub_input.reshape([config.image_size, config.image_size, 1])#按image size大小重排 因此 imgae_size应为33 而label_size应为21
          sub_label = sub_label.reshape([config.label_size, config.label_size, 1])
          sub_input_sequence.append(sub_input)#在sub_input_sequence末尾加sub_input中元素 但考虑为空
          sub_label_sequence.append(sub_label)

data是一个数组,data[i]看做是一幅画,首先是调用

input_, label_ = preprocess(data[i], config.scale)#得到data[]的LR和HR图input_和label_

这样我们就可以取得当前这张图的低分辨率的图片和高分辨率的图片,然后获取到它的长,宽,高,
然后就是不断的分割这张图了

for x in range(0, h-config.image_size+1, config.stride):
        for y in range(0, w-config.image_size+1, config.stride):

根据for循环可以知道,这个是按照一定的步长来分割的

         sub_input = input_[x:x+config.image_size, y:y+config.image_size]
         sub_label = label_[x+padding:x+padding+config.label_size, y+padding:y+padding+config.label_size]

分割图片

         sub_input = sub_input.reshape([config.image_size, config.image_size, 1])
         sub_label = sub_label.reshape([config.label_size, config.label_size, 1])
         sub_input_sequence.append(sub_input)#在sub_input_sequence末尾加sub_input中元素 但考虑为空
         sub_label_sequence.append(sub_label)

拼接图片

def merge(images, size):
  h, w = images.shape[1], images.shape[2] #觉得下标应该是0,1
  #h, w = images.shape[0], images.shape[1]
  img = np.zeros((h*size[0], w*size[1], 1))
  for idx, image in enumerate(images):
    i = idx % size[1]
    j = idx // size[1]
    img[j*h:j*h+h, i*w:i*w+w, :] = image
  return img