@@ -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(""); | |||
} | |||
} | |||