| import os |
| import sys |
|
|
| import numpy as np |
| import tensorflow as tf |
|
|
| from ..core.input import read_png_image, Input |
|
|
|
|
| def _read_flow(filenames, num_epochs=None): |
| """Given a list of filenames, constructs a reader op for ground truth flow files.""" |
| filename_queue = tf.train.string_input_producer(filenames, |
| shuffle=False, capacity=len(filenames), num_epochs=num_epochs) |
| reader = tf.WholeFileReader() |
| _, value = reader.read(filename_queue) |
| value = tf.reshape(value, [1]) |
| value_width = tf.substr(value, 4, 4) |
| value_height = tf.substr(value, 8, 4) |
| width = tf.reshape(tf.decode_raw(value_width, out_type=tf.int32), []) |
| height = tf.reshape(tf.decode_raw(value_height, out_type=tf.int32), []) |
|
|
| value_flow = tf.substr(value, 12, 8 * 436 * 1024) |
| flow = tf.decode_raw(value_flow, out_type=tf.float32) |
|
|
| return tf.reshape(flow, [436, 1024, 2]) |
|
|
|
|
| def _read_binary(filenames, num_epochs=None): |
| """Given a list of filenames, constructs a reader op for ground truth binary files.""" |
| filename_queue = tf.train.string_input_producer(filenames, |
| shuffle=False, capacity=len(filenames), num_epochs=num_epochs) |
| reader = tf.WholeFileReader() |
| _, value = reader.read(filename_queue) |
| value_decoded = tf.image.decode_png(value, channels=1) |
| return tf.cast(value_decoded, tf.float32) |
|
|
|
|
| def _get_filenames(parent_dir, ignore_last=False): |
| filenames = [] |
| for sub_name in sorted(os.listdir(parent_dir)): |
| sub_dir = os.path.join(parent_dir, sub_name) |
| sub_filenames = os.listdir(sub_dir) |
| sub_filenames.sort() |
| if ignore_last: |
| sub_filenames = sub_filenames[:-1] |
| for filename in sub_filenames: |
| filenames.append(os.path.join(sub_dir, filename)) |
|
|
| return filenames |
|
|
|
|
| class SintelInput(Input): |
| def __init__(self, data, batch_size, dims, *, |
| num_threads=1, normalize=True): |
| super().__init__(data, batch_size, dims, num_threads=num_threads, |
| normalize=normalize) |
|
|
| def _preprocess_flow(self, t, channels): |
| height, width = self.dims |
| |
| return tf.reshape(self._resize_crop_or_pad(t), [height, width, channels]) |
|
|
| def _input_images(self, image_dir): |
| """Assumes that paired images are next to each other after ordering the |
| files. |
| """ |
| image_dir = os.path.join(self.data.current_dir, image_dir) |
|
|
| filenames_1 = [] |
| filenames_2 = [] |
|
|
| for sub_name in sorted(os.listdir(image_dir)): |
| sub_dir = os.path.join(image_dir, sub_name) |
| sub_filenames = os.listdir(sub_dir) |
| sub_filenames.sort() |
| for i in range(len(sub_filenames) - 1): |
| filenames_1.append(os.path.join(sub_dir, sub_filenames[i])) |
| filenames_2.append(os.path.join(sub_dir, sub_filenames[i + 1])) |
|
|
| input_1 = read_png_image(filenames_1, 1) |
| input_2 = read_png_image(filenames_2, 1) |
| image_1 = self._preprocess_image(input_1) |
| image_2 = self._preprocess_image(input_2) |
| return tf.shape(input_1), image_1, image_2 |
|
|
| def _input_flow(self): |
| flow_dir = os.path.join(self.data.current_dir, 'sintel/training/flow') |
| invalid_dir = os.path.join(self.data.current_dir, 'sintel/training/invalid') |
| occ_dir = os.path.join(self.data.current_dir, 'sintel/training/occlusions') |
| flow_files = _get_filenames(flow_dir) |
| invalid_files = _get_filenames(invalid_dir, ignore_last=True) |
| occ_files = _get_filenames(occ_dir) |
|
|
| assert len(flow_files) == len(invalid_files) == len(occ_files) |
|
|
| flow = self._preprocess_flow(_read_flow(flow_files, 1), 2) |
| invalid = self._preprocess_flow(_read_binary(invalid_files), 1) |
| occ = self._preprocess_flow(_read_binary(occ_files), 1) |
|
|
| flow_occ = flow |
| flow_noc = flow * (1 - occ) |
| mask_occ = (1 - invalid) |
| mask_noc = mask_occ * (1 - occ) |
|
|
| return flow_occ, mask_occ, flow_noc, mask_noc |
|
|
| def _input_train(self, image_dir): |
| input_shape, im1, im2 = self._input_images(image_dir) |
| flow_occ, mask_occ, flow_noc, mask_noc = self._input_flow() |
| return tf.train.batch( |
| [im1, im2, input_shape, flow_occ, mask_occ, flow_noc, mask_noc], |
| batch_size=self.batch_size, |
| num_threads=self.num_threads, |
| allow_smaller_final_batch=True) |
|
|
| def input_train_clean(self): |
| return self._input_train('sintel/training/clean') |
|
|
| def input_train_final(self): |
| return self._input_train('sintel/training/final') |
|
|
| def input_test_clean(self): |
| input_shape, im1, im2 = self._input_images('sintel/test/clean') |
| return tf.train.batch( |
| [im1, im2, input_shape], |
| batch_size=self.batch_size, |
| num_threads=self.num_threads, |
| allow_smaller_final_batch=True) |
|
|
| def input_test_final(self): |
| input_shape, im1, im2 = self._input_images('sintel/test/final') |
| return tf.train.batch( |
| [im1, im2, input_shape], |
| batch_size=self.batch_size, |
| num_threads=self.num_threads, |
| allow_smaller_final_batch=True) |
|
|