| @@ -139,5 +139,16 @@ namespace Tensorflow | |||
| /// <returns></returns> | |||
| public Tensor shape(Tensor input, string name = null, TF_DataType out_type = TF_DataType.TF_INT32) | |||
| => array_ops.shape_internal(input, name, optimize: true, out_type: out_type); | |||
| /// <summary> | |||
| /// Unpacks the given dimension of a rank-`R` tensor into rank-`(R-1)` tensors. | |||
| /// </summary> | |||
| /// <param name="value"></param> | |||
| /// <param name="num"></param> | |||
| /// <param name="axis"></param> | |||
| /// <param name="name"></param> | |||
| /// <returns></returns> | |||
| public Tensor[] unstack(Tensor value, int? num = null, int axis = 0, string name = "unstack") | |||
| => array_ops.unstack(value, num: num, axis: axis, name: name); | |||
| } | |||
| } | |||
| @@ -40,6 +40,11 @@ namespace Tensorflow | |||
| 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); | |||
| public Tensor resize_images(Tensor images, Tensor size, ResizeMethod method = ResizeMethod.BILINEAR, | |||
| bool align_corners = false, bool preserve_aspect_ratio = false, string name = null) | |||
| => image_ops_impl.resize_images(images, size, method: method, | |||
| align_corners: align_corners, preserve_aspect_ratio: preserve_aspect_ratio, name: name); | |||
| public Tensor convert_image_dtype(Tensor image, TF_DataType dtype, bool saturate = false, string name = null) | |||
| => gen_image_ops.convert_image_dtype(image, dtype, saturate: saturate, name: name); | |||
| @@ -308,6 +308,18 @@ namespace Tensorflow | |||
| public static (Tensor, Tensor) unique(Tensor x, TF_DataType out_idx = TF_DataType.TF_INT32, string name = null) | |||
| => gen_array_ops.unique(x, out_idx: out_idx, name: name); | |||
| public static Tensor[] unstack(Tensor value, int? num = null, int axis = 0, string name = "unstack") | |||
| { | |||
| if(num == null) | |||
| { | |||
| value = ops.convert_to_tensor(value); | |||
| var value_shape = value.TensorShape; | |||
| num = value_shape.dims[axis]; | |||
| } | |||
| return gen_array_ops.unpack(value, num: num.Value, axis: axis, name: name); | |||
| } | |||
| public static Tensor where(Tensor condition, object x = null, object y = null, string name = null) | |||
| { | |||
| if( x == null && y == null) | |||
| @@ -248,6 +248,12 @@ namespace Tensorflow | |||
| return (_op.outputs[0], _op.outputs[1]); | |||
| } | |||
| public static Tensor[] unpack(Tensor value, int num, int axis = 0, string name = null) | |||
| { | |||
| var _op = _op_def_lib._apply_op_helper("Unpack", name, new { value, num, axis }); | |||
| return _op.outputs; | |||
| } | |||
| public static Tensor where() | |||
| { | |||
| throw new NotImplementedException("where"); | |||
| @@ -129,6 +129,22 @@ namespace Tensorflow | |||
| throw new NotImplementedException(""); | |||
| } | |||
| /// <summary> | |||
| /// Resize `images` to `size` using the specified `method`. | |||
| /// </summary> | |||
| /// <param name="images"></param> | |||
| /// <param name="size"></param> | |||
| /// <param name="method"></param> | |||
| /// <param name="align_corners"></param> | |||
| /// <param name="preserve_aspect_ratio"></param> | |||
| /// <param name="name"></param> | |||
| /// <returns></returns> | |||
| public static Tensor resize_images(Tensor images, Tensor size, ResizeMethod method = ResizeMethod.BILINEAR, | |||
| bool align_corners = false, bool preserve_aspect_ratio = false, string name = null) | |||
| { | |||
| throw new NotImplementedException(""); | |||
| } | |||
| /// <summary> | |||
| /// Resize `images` to `size` using nearest neighbor interpolation. | |||
| /// </summary> | |||
| @@ -146,4 +162,12 @@ namespace Tensorflow | |||
| half_pixel_centers: half_pixel_centers, | |||
| name: name); | |||
| } | |||
| public enum ResizeMethod | |||
| { | |||
| BILINEAR = 0, | |||
| NEAREST_NEIGHBOR = 1, | |||
| BICUBIC = 2, | |||
| AREA = 3 | |||
| } | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow | |||
| { | |||
| public class shape_utils | |||
| { | |||
| public static Tensor static_or_dynamic_map_fn(Func<Tensor, Tensor> fn, Tensor elems, TF_DataType dtype = TF_DataType.DtInvalid, | |||
| int parallel_iterations = 32, bool back_prop = true) | |||
| { | |||
| var outputs = tf.unstack(elems).Select(arg => fn(arg)).ToArray(); | |||
| throw new NotImplementedException(""); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,69 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow.Models.ObjectDetection.Core | |||
| { | |||
| public class Preprocessor | |||
| { | |||
| public static Tensor[] resize_to_range(ResizeToRangeArgs args) | |||
| { | |||
| var image = args.image; | |||
| var min_dimension = args.min_dimension; | |||
| var max_dimension = args.max_dimension; | |||
| var method = args.method; | |||
| var align_corners = args.align_corners; | |||
| if (image.NDims != 3) | |||
| throw new ValueError("Image should be 3D tensor"); | |||
| Func<Tensor, Tensor> _resize_landscape_image = (image1) => | |||
| { | |||
| return tf.image.resize_images(image1, | |||
| tf.stack(new[] { min_dimension, max_dimension }), | |||
| method: method, | |||
| align_corners: align_corners, | |||
| preserve_aspect_ratio: true); | |||
| }; | |||
| Func<Tensor, Tensor> _resize_portrait_image = (image1) => | |||
| { | |||
| return tf.image.resize_images(image1, | |||
| tf.stack(new[] { min_dimension, max_dimension }), | |||
| method: method, | |||
| align_corners: align_corners, | |||
| preserve_aspect_ratio: true); | |||
| }; | |||
| return tf_with(tf.name_scope("ResizeToRange", values: new { image, min_dimension }), delegate | |||
| { | |||
| Tensor new_image, new_size; | |||
| if (image.TensorShape.is_fully_defined()) | |||
| throw new NotImplementedException(""); | |||
| else | |||
| { | |||
| new_image = tf.cond( | |||
| tf.less(tf.shape(image)[0], tf.shape(image)[1]), | |||
| () => _resize_landscape_image(image), | |||
| () => _resize_portrait_image(image)); | |||
| new_size = tf.shape(new_image); | |||
| } | |||
| if (args.pad_to_max_dimension) | |||
| { | |||
| throw new NotImplementedException(""); | |||
| } | |||
| var result = new List<Tensor> { new_image }; | |||
| if (args.masks != null) | |||
| throw new NotImplementedException(""); | |||
| result.Add(new_size); | |||
| return result.ToArray(); | |||
| }); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,19 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.tensorflow.image_internal; | |||
| namespace Tensorflow.Models.ObjectDetection.Core | |||
| { | |||
| public class ResizeToRangeArgs | |||
| { | |||
| public Tensor image { get; set; } | |||
| public int[] masks { get; set; } | |||
| public int min_dimension { get; set; } | |||
| public int max_dimension { get; set; } | |||
| public ResizeMethod method {get;set;} | |||
| public bool align_corners { get; set; } | |||
| public bool pad_to_max_dimension { get; set; } | |||
| public int[] per_channel_pad_value { get; set; } | |||
| } | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Text; | |||
| using static Tensorflow.Binding; | |||
| namespace Tensorflow.Models.ObjectDetection | |||
| { | |||
| @@ -13,8 +14,23 @@ namespace Tensorflow.Models.ObjectDetection | |||
| _args = args; | |||
| } | |||
| public (Tensor, Tensor) preprocess(Tensor tensor) | |||
| /// <summary> | |||
| /// Feature-extractor specific preprocessing. | |||
| /// </summary> | |||
| /// <param name="inputs"></param> | |||
| /// <returns></returns> | |||
| public (Tensor, Tensor) preprocess(Tensor inputs) | |||
| { | |||
| tf_with(tf.name_scope("Preprocessor"), delegate | |||
| { | |||
| /*var outputs = shape_utils.static_or_dynamic_map_fn( | |||
| _image_resizer_fn, | |||
| elems: inputs, | |||
| dtype: new[] { tf.float32, tf.int32 }, | |||
| parallel_iterations: _parallel_iterations);*/ | |||
| }); | |||
| throw new NotImplementedException(""); | |||
| } | |||
| } | |||