def call(self, inputs, training=None, mask=None): (source_image, kp_driving_value, kp_driving_jacobian_inv, kp_source_value, kp_source_jacobian) = inputs # Encoding (downsampling) part out = self.first(source_image) for i in range(self.num_down_blocks): down_block = getattr(self, f'down_block{i}') out = down_block(out) # Transforming feature representation according to deformation and occlusion deformation, occlusion_map = self.dense_motion_network( (source_image, kp_driving_value, kp_driving_jacobian_inv, kp_source_value, kp_source_jacobian)) # out [B, 64, 64, 256] # deformation [B, 64, 64, 2] out = self.deform_input(out, deformation) # B, 64, 64, 256 if out.shape[1] != occlusion_map.shape[1] or out.shape[ 2] != occlusion_map.shape[2]: occlusion_map = resize_bilinear(occlusion_map, (out.shape[1:3])) out = out * occlusion_map # Decoding part out = self.bottleneck(out) # B, 64, 64, 256 for i in range(self.num_up_blocks): up_block = getattr(self, f'up_block{i}') out = up_block(out) # B, 256, 256, 64 out = self.final(out) # B, 256, 256, 3 out = tf.nn.sigmoid(out) return out
def build_model_for_train(self, oversample_ratio=1, important_ratio=0.6): out = self.semantic_segment_model.output coarse = out[-1] # 最后一层的输出为粗分类层 points = get_uncertain_pt_coords_randomness( coarse, batch_size=self.batch_size, oversample_ratio=oversample_ratio, important_ratio=important_ratio, ) fine = [] for mid_output in out: _, mid_output_H, mid_output_W, _ = mid_output.shape fine.append( grid_nd_sample( mid_output, _point_scale2img(points, mid_output_H, mid_output_W))) fine_concated = tf.keras.layers.concatenate(fine, axis=-1) coarse_selected_points = fine[-1] rend = self._mask_point_head(num_classes=self.num_classes, fine_gained_feature=fine_concated) rend_and_coords = tf.keras.layers.concatenate( [coarse_selected_points, rend, points], axis=-1, name='rend_and_coords') coarse = gen_image_ops.resize_bilinear(coarse, size=(512, 512), align_corners=True, name='coarse') # coarse = tf.keras.layers.Lambda(lambda x:gen_image_ops.resize_bilinear(x, size=(512, 512), align_corners=True, ) # ,name='coarse') # coarse = tf.keras.layers.Activation(activation='sigmoid',name='coarse')(coarse) model = tf.keras.Model(inputs=self.semantic_segment_model.inputs, outputs=[coarse, rend_and_coords]) return model
def deform_input(self, inp, deformation): _, h_old, w_old, _ = deformation.shape # B, 64, 64, 2 _, h, w, _ = inp.shape if h_old != h or w_old != w: # deformation = deformation.permute(0, 3, 1, 2) deformation = resize_bilinear(deformation, size=(h, w)) deformation = tf.transpose(deformation, [0, 3, 1, 2]) return bilinear_sampler(inp, deformation[:, 0, :, :], deformation[:, 1, :, :])
def build_model_for_infer(self, weights_path=None, batch_size=1): self.semantic_segment_model.load_weights(weights_path, by_name=True) self.mask_point_head_model.load_weights(weights_path, by_name=True) inputs = self.semantic_segment_model.inputs out = self.semantic_segment_model.output mask_logit = out[-1] # fine_gained_features = out[:-1] # origin_output = resize_bilinear(mask_logit, (512, 512), align_corners=True, # ) # _, H, W, C = mask_logit.shape ResizeShape_list = [128, 256, 512, 1024, 2048] grid_rate = [0.10, 0.09, 0.08, 0.07, 0.05] for subdivision_step, (size, rate) in enumerate( zip(ResizeShape_list, grid_rate)): ResizeShape = (size, size) # ResizeShape = list(map(lambda a: int(a) * 2, mask_logit.shape[1:3])) mask_logit = resize_bilinear(mask_logit, ResizeShape, align_corners=True, name='upsampleing') # R, sH, sW, C = map(int, mask_logit.shape) R, sH, sW, C = mask_logit.shape R = batch_size uncertainty_map = _uncertainty(mask_logit, cls=0) point_indices, point_coords = get_uncertain_point_coords_on_grid( uncertainty_map, # self.num_subdivision_points rate=rate, batch_size=batch_size) point_coords = point_coords[..., ::-1] # coarse_coords = _point_scale2img(point_coords, sH, sW) # local feat # coarse_features = _grid_nd_sample(mask_logit, coarse_coords, batch_dims=1) # show_points_image(mask_logit, coarse_coords) fine_gained_feature = [] for mid_output in out: _, fine_H, fine_W, _ = mid_output.shape fine_gained_feature_coords = _point_scale2img( point_coords, fine_H, fine_W) fine_gained_feature.append( _grid_nd_sample(mid_output, fine_gained_feature_coords, batch_dims=1)) fine_gained_feature = tf.concat(fine_gained_feature, axis=-1) point_logits = self.mask_point_head_model(fine_gained_feature) inds = tf.cast(point_coords * tf.constant((sH, sW), tf.float32), tf.int32) expdim = tf.tile( tf.range(0, R, dtype=tf.int32)[..., None], [1, inds.shape[1]])[..., None] inds = tf.concat([expdim, inds], -1) mask_logit = tf.tensor_scatter_nd_update(mask_logit, indices=inds, updates=point_logits) model = tf.keras.models.Model(inputs=inputs, outputs=mask_logit) return model
def _assertForwardOpMatchesExpected(self, image_np, target_shape, expected=None): if expected is None: self.fail("expected must be specified") with self.test_session() as sess, self.test_scope(): image = array_ops.placeholder(image_np.dtype) resized = gen_image_ops.resize_bilinear( image, target_shape, align_corners=True) out = sess.run(resized, {image: image_np[np.newaxis, :, :, np.newaxis]}) self.assertAllClose(expected[np.newaxis, :, :, np.newaxis], out)
def inference(self, inputs, weights_path, batch_size=1): self.semantic_segment_model.load_weights(weights_path, by_name=True) self.mask_point_head_model.load_weights(weights_path, by_name=True) # inputs = self.semantic_segment_model.inputs out = self.semantic_segment_model(inputs) mask_logit = out[-1] ResizeShape_list = [128, 256, 320, 480, 512] for subdivision_step, size in enumerate(ResizeShape_list): ResizeShape = (size, size) # ResizeShape = list(map(lambda a: int(a) * 2, mask_logit.shape[1:3])) mask_logit = resize_bilinear(mask_logit, ResizeShape, align_corners=True, name='upsampleing') # R, sH, sW, C = map(int, mask_logit.shape) R, sH, sW, C = mask_logit.shape R = batch_size uncertainty_map = _uncertainty(mask_logit, cls=0) point_indices, point_coords = get_uncertain_point_coords_on_grid( uncertainty_map, # self.num_subdivision_points 5000, batch_size=batch_size) point_coords = point_coords[..., ::-1] coarse_coords = _point_scale2img(point_coords, sH, sW) # local feat # coarse_features = _grid_nd_sample(mask_logit, coarse_coords, batch_dims=1) show_points_image(mask_logit, coarse_coords) fine_gained_feature = [] for mid_output in out: _, fine_H, fine_W, _ = mid_output.shape fine_gained_feature_coords = _point_scale2img( point_coords, fine_H, fine_W) fine_gained_feature.append( _grid_nd_sample(mid_output, fine_gained_feature_coords, batch_dims=1)) fine_gained_feature = tf.concat(fine_gained_feature, axis=-1) point_logits = self.mask_point_head_model(fine_gained_feature) inds = tf.cast(point_coords * tf.constant((sH, sW), tf.float32), tf.int32) expdim = tf.tile( tf.range(0, R, dtype=tf.int32)[..., None], [1, inds.shape[1]])[..., None] inds = tf.concat([expdim, inds], -1) mask_logit = tf.tensor_scatter_nd_update(mask_logit, indices=inds, updates=point_logits) return mask_logit
def testNonAlignCorners3x2To6x4Batch2(self): input_data = [[[64, 32], [32, 64], [50, 100]], [[32, 16], [16, 32], [25, 50]]] expected_data = [[[64.0, 48.0, 32.0, 32.0], [48.0, 48.0, 48.0, 48.0], [32.0, 48.0, 64.0, 64.0], [41.0, 61.5, 82.0, 82.0], [50.0, 75.0, 100.0, 100.0], [50.0, 75.0, 100.0, 100.0]], [[32.0, 24.0, 16.0, 16.0], [24.0, 24.0, 24.0, 24.0], [16.0, 24.0, 32.0, 32.0], [20.5, 30.75, 41.0, 41.0], [25.0, 37.5, 50.0, 50.0], [25.0, 37.5, 50.0, 50.0]]] for dtype in self.float_types: input_image = np.array(input_data, dtype=dtype) expected = np.array(expected_data, dtype=dtype) with self.session() as sess, self.test_scope(): image = array_ops.placeholder(input_image.dtype) resized = gen_image_ops.resize_bilinear( image, [6, 4], align_corners=False) out = sess.run(resized, {image: input_image[:, :, :, np.newaxis]}) self.assertAllClose(expected[:, :, :, np.newaxis], out)
def testNonAlignCorners3x2To6x4Batch2(self): input_data = [[[64, 32], [32, 64], [50, 100]], [[32, 16], [16, 32], [25, 50]]] expected_data = [[[64.0, 48.0, 32.0, 32.0], [48.0, 48.0, 48.0, 48.0], [32.0, 48.0, 64.0, 64.0], [41.0, 61.5, 82.0, 82.0], [50.0, 75.0, 100.0, 100.0], [50.0, 75.0, 100.0, 100.0]], [[32.0, 24.0, 16.0, 16.0], [24.0, 24.0, 24.0, 24.0], [16.0, 24.0, 32.0, 32.0], [20.5, 30.75, 41.0, 41.0], [25.0, 37.5, 50.0, 50.0], [25.0, 37.5, 50.0, 50.0]]] for dtype in self.float_types: input_image = np.array(input_data, dtype=dtype) expected = np.array(expected_data, dtype=dtype) with self.cached_session() as sess, self.test_scope(): image = array_ops.placeholder(input_image.dtype) resized = gen_image_ops.resize_bilinear( image, [6, 4], align_corners=False) out = sess.run(resized, {image: input_image[:, :, :, np.newaxis]}) self.assertAllClose(expected[:, :, :, np.newaxis], out)
def resize_and_pad(image, offset_height, offset_width, height, width, target_height, target_width): # written by X, no back propagation through roi, but anyway if len(image.get_shape()) == 3: image = array_ops.expand_dims(image, 0) batch_size, _, _, depth = _ImageDimensions(image) resized = gen_image_ops.resize_bilinear(image, [height, width]) after_padding_width = target_width - offset_width - width after_padding_height = target_height - offset_height - height paddings = array_ops.reshape( array_ops.pack([ 0, 0, offset_height, after_padding_height, offset_width, after_padding_width, 0, 0 ]), [4, 2]) padded = array_ops.pad(resized, paddings) padded_shape = [ None if _is_tensor(i) else i for i in [batch_size, target_height, target_width, depth] ] padded.set_shape(padded_shape) return padded
def forward_step(self, out, source_image, kp_new_value, kp_new_jacobian, kp_source_value, kp_source_jacobian): dense_motion = self.dense_motion_network.forward_step( source_image, kp_new_value, kp_new_jacobian, kp_source_value, kp_source_jacobian) occlusion_map = dense_motion['occlusion_map'] deformation = dense_motion['deformation'] out = self.deform_input(out, deformation) occlusion_map = resize_bilinear(occlusion_map, (out.shape[1:3])) out = out * occlusion_map # Decoding part out = self.bottleneck(out) # B, 64, 64, 256 for i in range(len(self.num_up_blocks)): up_block = getattr(self, f'up_block{i}') out = up_block(out) # B, 256, 256, 64 out = self.final(out) # B, 256, 256, 3 out = tf.nn.sigmoid(out) return out
def resize_images(images, new_height, new_width, method=ResizeMethod.BILINEAR, align_corners=False): """Resize `images` to `new_width`, `new_height` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `new_width`, `new_height`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.] (https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.] (https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.] (https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. new_height: integer. new_width: integer. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. align_corners: bool. If true, exactly align all 4 cornets of the input and output. Defaults to `false`. Only implemented for bilinear interpolation method so far. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if len(images.get_shape()) == 3: is_batch = False images = array_ops.expand_dims(images, 0) _, height, width, depth = _ImageDimensions(images) if width == new_width and height == new_height: if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, [new_height, new_width], align_corners=align_corners) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor(images, [new_height, new_width]) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, [new_height, new_width]) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, [new_height, new_width]) else: raise ValueError('Resize method is not implemented.') if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images
def resize_images(images, new_height, new_width, method=ResizeMethod.BILINEAR, align_corners=False): """Resize `images` to `new_width`, `new_height` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `new_width`, `new_height`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.] (https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.] (https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.] (https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. new_height: integer. new_width: integer. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. align_corners: bool. If true, exactly align all 4 corners of the input and output. Defaults to `false`. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ images = ops.convert_to_tensor(images, name='images') if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if len(images.get_shape()) == 3: is_batch = False images = array_ops.expand_dims(images, 0) _, height, width, depth = _ImageDimensions(images) # Handle tensor-valued sizes as well as Python integers. try: new_width = ops.convert_to_tensor(new_width, dtypes.int32, name='new_width') new_width.get_shape().assert_has_rank(0) except (TypeError, ValueError): raise ValueError('new_width must be a scalar integer') try: new_height = ops.convert_to_tensor(new_height, dtypes.int32, name='new_height') new_height.get_shape().assert_has_rank(0) except (TypeError, ValueError): raise ValueError('new_height must be a scalar integer') new_width_const = tensor_util.constant_value(new_width) new_height_const = tensor_util.constant_value(new_height) # If we can determine that the height and width will be unmodified by this # transformation, we avoid performing the resize. if all(x is not None for x in [new_width_const, width, new_height_const, height]) and ( width == new_width_const and height == new_height_const): if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images new_size = array_ops.pack([new_height, new_width]) if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, new_size, align_corners=align_corners) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor(images, new_size, align_corners=align_corners) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, new_size, align_corners=align_corners) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, new_size, align_corners=align_corners) else: raise ValueError('Resize method is not implemented.') # NOTE(mrry): The shape functions for the resize ops cannot unpack # the packed values in `new_size`, so set the shape here. images.set_shape([None, new_height_const, new_width_const, None]) if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images
def resize_images(images, new_height, new_width, method=ResizeMethod.BILINEAR, align_corners=False): """Resize `images` to `new_width`, `new_height` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `new_width`, `new_height`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.] (https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.] (https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.] (https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. new_height: integer. new_width: integer. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. align_corners: bool. If true, exactly align all 4 corners of the input and output. Defaults to `false`. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ images = ops.convert_to_tensor(images, name='images') if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if len(images.get_shape()) == 3: is_batch = False images = array_ops.expand_dims(images, 0) _, height, width, depth = _ImageDimensions(images) # Handle tensor-valued sizes as well as Python integers. try: new_width = ops.convert_to_tensor(new_width, dtypes.int32, name='new_width') new_width.get_shape().assert_has_rank(0) except (TypeError, ValueError): raise ValueError('new_width must be a scalar integer') try: new_height = ops.convert_to_tensor(new_height, dtypes.int32, name='new_height') new_height.get_shape().assert_has_rank(0) except (TypeError, ValueError): raise ValueError('new_height must be a scalar integer') new_width_const = tensor_util.constant_value(new_width) new_height_const = tensor_util.constant_value(new_height) # If we can determine that the height and width will be unmodified by this # transformation, we avoid performing the resize. if all(x is not None for x in [new_width_const, width, new_height_const, height]) and ( width == new_width_const and height == new_height_const): if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images new_size = array_ops.pack([new_height, new_width]) if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, new_size, align_corners=align_corners) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor( images, new_size, align_corners=align_corners) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, new_size, align_corners=align_corners) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, new_size, align_corners=align_corners) else: raise ValueError('Resize method is not implemented.') # NOTE(mrry): The shape functions for the resize ops cannot unpack # the packed values in `new_size`, so set the shape here. images.set_shape([None, new_height_const, new_width_const, None]) if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images
def resize_images(images, size, method=ResizeMethod.BILINEAR, align_corners=False): """Resize `images` to `size` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `size`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.](https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.](https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.](https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. size: A 1-D int32 Tensor of 2 elements: `new_height, new_width`. The new size for the images. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. align_corners: bool. If true, exactly align all 4 corners of the input and output. Defaults to `false`. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if `size` has invalid shape or type. ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ images = ops.convert_to_tensor(images, name='images') if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if images.get_shape().ndims == 3: is_batch = False images = array_ops.expand_dims(images, 0) elif images.get_shape().ndims != 4: raise ValueError('\'images\' must have either 3 or 4 dimensions.') _, height, width, _ = images.get_shape().as_list() try: size = ops.convert_to_tensor(size, dtypes.int32, name='size') except (TypeError, ValueError): raise ValueError('\'size\' must be a 1-D int32 Tensor') if not size.get_shape().is_compatible_with([2]): raise ValueError('\'size\' must be a 1-D Tensor of 2 elements: ' 'new_height, new_width') size_const_as_shape = tensor_util.constant_value_as_shape(size) new_height_const = size_const_as_shape[0].value new_width_const = size_const_as_shape[1].value # If we can determine that the height and width will be unmodified by this # transformation, we avoid performing the resize. if all(x is not None for x in [new_width_const, width, new_height_const, height]) and ( width == new_width_const and height == new_height_const): if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, size, align_corners=align_corners) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor(images, size, align_corners=align_corners) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, size, align_corners=align_corners) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, size, align_corners=align_corners) else: raise ValueError('Resize method is not implemented.') # NOTE(mrry): The shape functions for the resize ops cannot unpack # the packed values in `new_size`, so set the shape here. images.set_shape([None, new_height_const, new_width_const, None]) if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images
def resize_images(images, new_height, new_width, method=ResizeMethod.BILINEAR): """Resize `images` to `new_width`, `new_height` using the specified `method`. Resized images will be distorted if their original aspect ratio is not the same as `new_width`, `new_height`. To avoid distortions see [`resize_image_with_crop_or_pad`](#resize_image_with_crop_or_pad). `method` can be one of: * <b>`ResizeMethod.BILINEAR`</b>: [Bilinear interpolation.] (https://en.wikipedia.org/wiki/Bilinear_interpolation) * <b>`ResizeMethod.NEAREST_NEIGHBOR`</b>: [Nearest neighbor interpolation.] (https://en.wikipedia.org/wiki/Nearest-neighbor_interpolation) * <b>`ResizeMethod.BICUBIC`</b>: [Bicubic interpolation.] (https://en.wikipedia.org/wiki/Bicubic_interpolation) * <b>`ResizeMethod.AREA`</b>: Area interpolation. Args: images: 4-D Tensor of shape `[batch, height, width, channels]` or 3-D Tensor of shape `[height, width, channels]`. new_height: integer. new_width: integer. method: ResizeMethod. Defaults to `ResizeMethod.BILINEAR`. Raises: ValueError: if the shape of `images` is incompatible with the shape arguments to this function ValueError: if an unsupported resize method is specified. Returns: If `images` was 4-D, a 4-D float Tensor of shape `[batch, new_height, new_width, channels]`. If `images` was 3-D, a 3-D float Tensor of shape `[new_height, new_width, channels]`. """ if images.get_shape().ndims is None: raise ValueError('\'images\' contains no shape.') # TODO(shlens): Migrate this functionality to the underlying Op's. is_batch = True if len(images.get_shape()) == 3: is_batch = False images = array_ops.expand_dims(images, 0) _, height, width, depth = _ImageDimensions(images) if width == new_width and height == new_height: if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images if method == ResizeMethod.BILINEAR: images = gen_image_ops.resize_bilinear(images, [new_height, new_width]) elif method == ResizeMethod.NEAREST_NEIGHBOR: images = gen_image_ops.resize_nearest_neighbor(images, [new_height, new_width]) elif method == ResizeMethod.BICUBIC: images = gen_image_ops.resize_bicubic(images, [new_height, new_width]) elif method == ResizeMethod.AREA: images = gen_image_ops.resize_area(images, [new_height, new_width]) else: raise ValueError('Resize method is not implemented.') if not is_batch: images = array_ops.squeeze(images, squeeze_dims=[0]) return images