diff --git a/src/TensorFlowNET.Core/APIs/tf.image.cs b/src/TensorFlowNET.Core/APIs/tf.image.cs index 57b8b093..9263338d 100644 --- a/src/TensorFlowNET.Core/APIs/tf.image.cs +++ b/src/TensorFlowNET.Core/APIs/tf.image.cs @@ -37,6 +37,22 @@ namespace Tensorflow fancy_upscaling: fancy_upscaling, try_recover_truncated: try_recover_truncated, acceptable_fraction: acceptable_fraction, dct_method: dct_method); + /// + /// Extracts crops from the input image tensor and resizes them using bilinear sampling or nearest neighbor sampling (possibly with aspect ratio change) to a common output size specified by crop_size. This is more general than the crop_to_bounding_box op which extracts a fixed size slice from the input image and does not allow resizing or aspect ratio change. + /// Returns a tensor with crops from the input image at positions defined at the bounding box locations in boxes.The cropped boxes are all resized(with bilinear or nearest neighbor interpolation) to a fixed size = [crop_height, crop_width].The result is a 4 - D tensor[num_boxes, crop_height, crop_width, depth].The resizing is corner aligned. In particular, if boxes = [[0, 0, 1, 1]], the method will give identical results to using tf.image.resize_bilinear() or tf.image.resize_nearest_neighbor() (depends on the method argument) with align_corners = True. + /// + /// A Tensor. Must be one of the following types: uint8, uint16, int8, int16, int32, int64, half, float32, float64. A 4-D tensor of shape [batch, image_height, image_width, depth]. Both image_height and image_width need to be positive. + /// A Tensor of type float32. A 2-D tensor of shape [num_boxes, 4]. The i-th row of the tensor specifies the coordinates of a box in the box_ind[i] image and is specified in normalized coordinates [y1, x1, y2, x2]. A normalized coordinate value of y is mapped to the image coordinate at y * (image_height - 1), so as the [0, 1] interval of normalized image height is mapped to [0, image_height - 1] in image height coordinates. We do allow y1 > y2, in which case the sampled crop is an up-down flipped version of the original image. The width dimension is treated similarly. Normalized coordinates outside the [0, 1] range are allowed, in which case we use extrapolation_value to extrapolate the input image values. + /// A Tensor of type int32. A 1-D tensor of shape [num_boxes] with int32 values in [0, batch). The value of box_ind[i] specifies the image that the i-th box refers to. + /// A Tensor of type int32. A 1-D tensor of 2 elements, size = [crop_height, crop_width]. All cropped image patches are resized to this size. The aspect ratio of the image content is not preserved. Both crop_height and crop_width need to be positive. + /// An optional string from: "bilinear", "nearest". Defaults to "bilinear". A string specifying the sampling method for resizing. It can be either "bilinear" or "nearest" and default to "bilinear". Currently two sampling methods are supported: Bilinear and Nearest Neighbor. + /// An optional float. Defaults to 0. Value used for extrapolation, when applicable. + /// A name for the operation (optional). + /// + public Tensor crop_and_resize(Tensor image, Tensor boxes, Tensor box_ind, Tensor crop_size, string method = "bilinear", float extrapolation_value = 0f, string name = null) => + image_ops_impl.crop_and_resize(image, boxes, box_ind, crop_size, method, extrapolation_value, name); + + public Tensor resize_bilinear(Tensor images, Tensor size, bool align_corners = false, string name = null) => gen_image_ops.resize_bilinear(images, size, align_corners: align_corners, name: name); diff --git a/src/TensorFlowNET.Core/Operations/image_ops_impl.cs b/src/TensorFlowNET.Core/Operations/image_ops_impl.cs index fd252790..c09fd0ab 100644 --- a/src/TensorFlowNET.Core/Operations/image_ops_impl.cs +++ b/src/TensorFlowNET.Core/Operations/image_ops_impl.cs @@ -109,27 +109,17 @@ namespace Tensorflow throw new NotImplementedException(); } - /// - /// Extracts crops from the input image tensor and resizes them using bilinear sampling or nearest neighbor sampling (possibly with aspect ratio change) to a common output size specified by crop_size. - /// This is more general than the crop_to_bounding_box op which extracts a fixed size slice from the input image and does not allow resizing or aspect ratio change. - /// Returns a tensor with crops from the input image at positions defined at the bounding box locations in boxes. - /// The cropped boxes are all resized(with bilinear or nearest neighbor interpolation) to a fixed size = [crop_height, crop_width]. - /// The result is a 4 - D tensor[num_boxes, crop_height, crop_width, depth]. - /// The resizing is corner aligned. In particular, if boxes = [[0, 0, 1, 1]], the method will give identical results to using tf.image.resize_bilinear() or tf.image.resize_nearest_neighbor() (depends on the method argument) with align_corners = True. - /// - /// A 4-D tensor of shape [batch, image_height, image_width, depth]. Both image_height and image_width need to be positive. - /// A 2-D tensor of shape [num_boxes, 4]. The i-th row of the tensor specifies the coordinates of a box in the box_ind[i] image and is specified in normalized coordinates [y1, x1, y2, x2]. A normalized coordinate value of y is mapped to the image coordinate at y * (image_height - 1), so as the [0, 1] interval of normalized image height is mapped to [0, image_height - 1] in image height coordinates. We do allow y1 > y2, in which case the sampled crop is an up-down flipped version of the original image. The width dimension is treated similarly. Normalized coordinates outside the [0, 1] range are allowed, in which case we use extrapolation_value to extrapolate the input image values. - /// A 1-D tensor of shape [num_boxes] with int32 values in [0, batch). The value of box_ind[i] specifies the image that the i-th box refers to. - /// A 1-D tensor of 2 elements, size = [crop_height, crop_width]. All cropped image patches are resized to this size. The aspect ratio of the image content is not preserved. Both crop_height and crop_width need to be positive. - /// A 4-D tensor of shape [num_boxes, crop_height, crop_width, depth]. - public static Tensor CropAndResize(Tensor image, Tensor boxes, Tensor box_ind, Tensor crop_size) + + public static Tensor crop_and_resize(Tensor image, Tensor boxes, Tensor box_ind, Tensor crop_size, string method, float extrapolation_value, string name) { - var _op = gen_nn_ops._op_def_lib._apply_op_helper("CropAndResize", name: null, args: new + var _op = gen_nn_ops._op_def_lib._apply_op_helper("CropAndResize", name: name, args: new { image, boxes, box_ind, - crop_size + crop_size, + method, + extrapolation_value }); return _op.outputs[0]; diff --git a/test/TensorFlowNET.UnitTest/img_test/TestCrop.cs b/test/TensorFlowNET.UnitTest/img_test/TestCrop.cs index 51ab2cd3..115c74db 100644 --- a/test/TensorFlowNET.UnitTest/img_test/TestCrop.cs +++ b/test/TensorFlowNET.UnitTest/img_test/TestCrop.cs @@ -33,18 +33,19 @@ namespace TensorFlowNET.UnitTest.img_test { sess.run(init); - var cropped = image_ops_impl.CropAndResize(image, box, boxInd, cropSize1_1); + var cropped = tf.image.crop_and_resize(image, box, boxInd, cropSize1_1); var result = sess.run(cropped); // check if cropped to 1x1 center was succesfull result.size.Should().Be(1); result[0, 0, 0, 0].Should().Be(4f); - cropped = image_ops_impl.CropAndResize(image2, box, boxInd, cropSize2_2); + cropped = tf.image.crop_and_resize(image2, box, boxInd, cropSize2_2); result = sess.run(cropped); // check if flipped and no cropping occured result.size.Should().Be(16); result[0, 0, 0, 0].Should().Be(12f); + } }