def generate_from_meta(meta_data_path,
                       pano_data_dir,
                       pano_height=1024,
                       pano_width=2048,
                       output_height=512,
                       output_width=512):
  """Generate the stereo image dataset from Matterport3D using the meta data.

  Example call:
    ds = generate_from_meta(
      meta_data_path='matterport3d/saved_meta/R90_fov90/test_meta/',
      pano_data_dir='matterport3d/pano/')

  Args:
    meta_data_path: (string) the path to the meta data files.
    pano_data_dir: (string) the path to the panorama images of the Matterport3D.
    pano_height: (int) the height dimension of the panorama images.
    pano_width: (int) the width dimension of the panorama images.
    output_height: (int) the height dimension of the output perspective images.
    output_width: (int) the width dimension of the output perspective images.

  Returns:
    Tensorflow Dataset.
  """

  def load_text(file_path, n_lines=200):
    """Load text data from a file."""
    return tf.data.Dataset.from_tensor_slices(
        tf.data.experimental.get_single_element(
            tf.data.TextLineDataset(file_path).batch(n_lines)))

  def load_single_image(filename):
    """Load a single image given the filename."""
    image = tf.image.decode_jpeg(tf.read_file(filename), 3)
    image = tf.image.convert_image_dtype(image, tf.float32)
    image.set_shape([pano_height, pano_width, 3])
    return image

  def string_to_matrix(s, shape):
    """Decode strings to matrices tensor."""
    m = tf.reshape(
        tf.stack([tf.decode_csv(s, [0.0] * np.prod(shape))], 0), shape)
    m.set_shape(shape)
    return m

  def decode_line(line):
    """Decode text lines."""
    DataPair = collections.namedtuple(
        'DataPair', ['src_img', 'trt_img', 'fov', 'rotation', 'translation'])

    splitted = tf.decode_csv(line, ['']*10, field_delim=' ')

    img1 = load_single_image(pano_data_dir+splitted[0]+'/'+splitted[1]+'.jpeg')
    img2 = load_single_image(pano_data_dir+splitted[0]+'/'+splitted[2]+'.jpeg')
    fov = string_to_matrix(splitted[3], [1])
    r1 = string_to_matrix(splitted[4], [3, 3])
    t1 = string_to_matrix(splitted[5], [3])
    r2 = string_to_matrix(splitted[6], [3, 3])
    t2 = string_to_matrix(splitted[7], [3])
    sampled_r1 = string_to_matrix(splitted[8], [3, 3])
    sampled_r2 = string_to_matrix(splitted[9], [3, 3])

    r_c2_to_c1 = tf.matmul(sampled_r1, sampled_r2, transpose_a=True)
    t_c1 = tf.squeeze(tf.matmul(sampled_r1,
                                tf.expand_dims(tf.nn.l2_normalize(t2-t1), -1),
                                transpose_a=True))

    sampled_rotation = tf.matmul(tf.stack([sampled_r1, sampled_r2], 0),
                                 tf.stack([r1, r2], 0), transpose_a=True)

    sampled_views = transformation.rectilinear_projection(
        tf.stack([img1, img2], 0),
        [output_height, output_width],
        fov,
        tf.matrix_transpose(sampled_rotation))
    src_img, trt_img = sampled_views[0], sampled_views[1]
    return DataPair(src_img, trt_img, fov, r_c2_to_c1, t_c1)

  # meta_data_path has slash '/' at the end.
  ds = tf.data.Dataset.list_files(meta_data_path+'*')
  ds = ds.flat_map(load_text)
  ds = ds.map(decode_line)
  return ds