diff --git a/src/TensorFlowNET.Core/APIs/tf.array.cs b/src/TensorFlowNET.Core/APIs/tf.array.cs
index f2402a6f..df8e69c3 100644
--- a/src/TensorFlowNET.Core/APIs/tf.array.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.array.cs
@@ -139,5 +139,16 @@ namespace Tensorflow
///
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);
+
+ ///
+ /// Unpacks the given dimension of a rank-`R` tensor into rank-`(R-1)` tensors.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor[] unstack(Tensor value, int? num = null, int axis = 0, string name = "unstack")
+ => array_ops.unstack(value, num: num, axis: axis, name: name);
}
}
diff --git a/src/TensorFlowNET.Core/APIs/tf.image.cs b/src/TensorFlowNET.Core/APIs/tf.image.cs
index 832010e5..57b8b093 100644
--- a/src/TensorFlowNET.Core/APIs/tf.image.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.image.cs
@@ -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);
diff --git a/src/TensorFlowNET.Core/Operations/array_ops.py.cs b/src/TensorFlowNET.Core/Operations/array_ops.py.cs
index 83a469dc..c52e2821 100644
--- a/src/TensorFlowNET.Core/Operations/array_ops.py.cs
+++ b/src/TensorFlowNET.Core/Operations/array_ops.py.cs
@@ -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)
diff --git a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs
index ea020599..3e9ce699 100644
--- a/src/TensorFlowNET.Core/Operations/gen_array_ops.cs
+++ b/src/TensorFlowNET.Core/Operations/gen_array_ops.cs
@@ -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");
diff --git a/src/TensorFlowNET.Core/Operations/image_ops_impl.cs b/src/TensorFlowNET.Core/Operations/image_ops_impl.cs
index 6cf9f77e..b7573b92 100644
--- a/src/TensorFlowNET.Core/Operations/image_ops_impl.cs
+++ b/src/TensorFlowNET.Core/Operations/image_ops_impl.cs
@@ -129,6 +129,22 @@ namespace Tensorflow
throw new NotImplementedException("");
}
+ ///
+ /// Resize `images` to `size` using the specified `method`.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ 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("");
+ }
+
///
/// Resize `images` to `size` using nearest neighbor interpolation.
///
@@ -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
+ }
}
diff --git a/src/TensorFlowNET.Core/Tensors/shape_utils.cs b/src/TensorFlowNET.Core/Tensors/shape_utils.cs
new file mode 100644
index 00000000..859d931b
--- /dev/null
+++ b/src/TensorFlowNET.Core/Tensors/shape_utils.cs
@@ -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 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("");
+ }
+ }
+}
diff --git a/src/TensorFlowNET.Models/ObjectDetection/Core/Preprocessor.cs b/src/TensorFlowNET.Models/ObjectDetection/Core/Preprocessor.cs
new file mode 100644
index 00000000..ac3cc805
--- /dev/null
+++ b/src/TensorFlowNET.Models/ObjectDetection/Core/Preprocessor.cs
@@ -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 _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 _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 { new_image };
+ if (args.masks != null)
+ throw new NotImplementedException("");
+
+ result.Add(new_size);
+
+ return result.ToArray();
+ });
+ }
+ }
+}
diff --git a/src/TensorFlowNET.Models/ObjectDetection/Core/ResizeToRangeArgs.cs b/src/TensorFlowNET.Models/ObjectDetection/Core/ResizeToRangeArgs.cs
new file mode 100644
index 00000000..2fe799a6
--- /dev/null
+++ b/src/TensorFlowNET.Models/ObjectDetection/Core/ResizeToRangeArgs.cs
@@ -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; }
+ }
+}
diff --git a/src/TensorFlowNET.Models/ObjectDetection/MetaArchitectures/FasterRCNNMetaArch.cs b/src/TensorFlowNET.Models/ObjectDetection/MetaArchitectures/FasterRCNNMetaArch.cs
index 083d4e4f..beb18198 100644
--- a/src/TensorFlowNET.Models/ObjectDetection/MetaArchitectures/FasterRCNNMetaArch.cs
+++ b/src/TensorFlowNET.Models/ObjectDetection/MetaArchitectures/FasterRCNNMetaArch.cs
@@ -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)
+ ///
+ /// Feature-extractor specific preprocessing.
+ ///
+ ///
+ ///
+ 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("");
}
}