Browse Source

fix image resize.

v0.20-tensorflow2.3
Oceania2018 Haiping 5 years ago
parent
commit
2431f840dd
6 changed files with 54 additions and 23 deletions
  1. +4
    -0
      src/TensorFlowNET.Core/APIs/tf.array.cs
  2. +1
    -1
      src/TensorFlowNET.Core/APIs/tf.image.cs
  3. +6
    -0
      src/TensorFlowNET.Core/Eager/EagerTensor.cs
  4. +29
    -16
      src/TensorFlowNET.Core/Operations/image_ops_impl.cs
  5. +1
    -1
      src/TensorFlowNET.Core/Tensors/Tensor.cs
  6. +13
    -5
      test/TensorFlowNET.UnitTest/ImageTest.cs

+ 4
- 0
src/TensorFlowNET.Core/APIs/tf.array.cs View File

@@ -29,6 +29,10 @@ namespace Tensorflow
/// A convenient alias for None, useful for indexing arrays.
/// </summary>
public Slice newaxis = Slice.NewAxis;
/// <summary>
/// A convenient alias for ...
/// </summary>
public Slice ellipsis = Slice.Ellipsis;

/// <summary>
/// BatchToSpace for N-D tensors of type T.


+ 1
- 1
src/TensorFlowNET.Core/APIs/tf.image.cs View File

@@ -209,7 +209,7 @@ namespace Tensorflow
name, sorted_input, canonicalized_coordinates, tile_size);

public Tensor resize(Tensor image, TensorShape size)
=> image_ops_impl.resize_images(image, tf.constant(size));
=> image_ops_impl.resize_images_v2(image, size);

public Tensor resize_bilinear(Tensor images, Tensor size, bool align_corners = false, bool half_pixel_centers = false, string name = null)
=> gen_image_ops.resize_bilinear(images, size, align_corners: align_corners, half_pixel_centers: half_pixel_centers, name: name);


+ 6
- 0
src/TensorFlowNET.Core/Eager/EagerTensor.cs View File

@@ -19,6 +19,12 @@ namespace Tensorflow.Eager

public override int rank => c_api.TFE_TensorHandleNumDims(EagerTensorHandle, tf.Status.Handle);

public override void set_shape(TensorShape shape)
{
if (!shape.is_compatible_with(this.shape))
throw new ValueError($"Tensor's shape is not compatible.");
}

public static int GetRank(IntPtr handle)
{
var tfe_tensor_handle = c_api.TFE_EagerTensorHandle(handle);


+ 29
- 16
src/TensorFlowNET.Core/Operations/image_ops_impl.cs View File

@@ -672,10 +672,8 @@ or rank = 4. Had rank = {0}", rank));
internal static Tensor _resize_images_common(Tensor images, Func<Tensor, Tensor, Tensor> resizer_fn,
Tensor size, bool preserve_aspect_ratio, string name, bool skip_resize_if_same)
{
using (ops.name_scope(name, "resize", new [] {images, size}))
return tf_with(ops.name_scope(name, "resize", new [] {images, size}), delegate
return tf_with(ops.name_scope(name, "resize", new[] {images, size}), delegate
{
images = ops.convert_to_tensor(images, name: "images");
if (images.TensorShape.ndim == Unknown)
throw new ValueError("\'images\' contains no shape.");
bool is_batch = true;
@@ -688,18 +686,6 @@ or rank = 4. Had rank = {0}", rank));

var (height, width) = (images.dims[1], images.dims[2]);

try
{
size = ops.convert_to_tensor(size, dtypes.int32, name: "size");
}
catch (Exception ex)
{
if (ex is TypeError || ex is ValueError)
throw new ValueError("\'size\' must be a 1-D int32 Tensor");
else
throw;
}

if (!size.TensorShape.is_compatible_with(new [] {2}))
throw new ValueError(@"\'size\' must be a 1-D Tensor of 2 elements:
new_height, new_width");
@@ -756,7 +742,7 @@ new_height, new_width");
images = resizer_fn(images, size);

// images.set_shape(new TensorShape(new int[] { -1, new_height_const, new_width_const, -1 }));
images.set_shape(new TensorShape(new int[] { Unknown, new_height_const, new_width_const, Unknown }));
if (!is_batch)
images = array_ops.squeeze(images, axis: new int[] {0});
@@ -2163,6 +2149,33 @@ new_height, new_width");
});
}

/// <summary>
/// Resize `images` to `size` using the specified `method`.
/// </summary>
/// <param name="images"></param>
/// <param name="size"></param>
/// <param name="method"></param>
/// <param name="preserve_aspect_ratio"></param>
/// <param name="antialias"></param>
/// <param name="name"></param>
/// <returns></returns>
public static Tensor resize_images_v2(Tensor images, TensorShape size, string method = ResizeMethod.BILINEAR,
bool preserve_aspect_ratio = false,
bool antialias = false,
string name = null)
{
Func<Tensor, Tensor, Tensor> resize_fn = (images, size) =>
{
if (method == ResizeMethod.BILINEAR)
return gen_image_ops.resize_bilinear(images, size, half_pixel_centers: true);
throw new NotImplementedException("");
};
return _resize_images_common(images, resize_fn, ops.convert_to_tensor(size),
preserve_aspect_ratio: preserve_aspect_ratio,
skip_resize_if_same: false,
name: name);
}

/// <summary>
/// Resize `images` to `size` using nearest neighbor interpolation.
/// </summary>


+ 1
- 1
src/TensorFlowNET.Core/Tensors/Tensor.cs View File

@@ -149,7 +149,7 @@ namespace Tensorflow
/// <summary>
/// Updates the shape of this tensor.
/// </summary>
public void set_shape(TensorShape shape)
public virtual void set_shape(TensorShape shape)
{
this.shape = shape.rank >= 0 ? shape.dims : null;
}


+ 13
- 5
test/TensorFlowNET.UnitTest/ImageTest.cs View File

@@ -4,6 +4,7 @@ using NumSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Tensorflow;
@@ -35,9 +36,10 @@ namespace TensorFlowNET.UnitTest.Basics
Assert.AreEqual(img.name, "decode_image/cond_jpeg/Merge:0");
}

[TestMethod, Ignore]
[TestMethod]
public void resize_image()
{
tf.enable_eager_execution();
var image = tf.constant(new int[5, 5]
{
{1, 0, 0, 0, 0 },
@@ -46,10 +48,16 @@ namespace TensorFlowNET.UnitTest.Basics
{0, 0, 0, 1, 0 },
{0, 0, 0, 0, 1 }
});
//image = image[tf.newaxis, ..., tf.newaxis];

var img = tf.image.resize(contents, (3, 5));
Assert.AreEqual(img.name, "decode_image/cond_jpeg/Merge:0");
image = image[tf.newaxis, tf.ellipsis, tf.newaxis];
image = tf.image.resize(image, (3, 5));
image = image[0, tf.ellipsis, 0];
Assert.IsTrue(Enumerable.SequenceEqual(new float[] { 0.6666667f, 0.3333333f, 0, 0, 0 },
image[0].ToArray<float>()));
Assert.IsTrue(Enumerable.SequenceEqual(new float[] { 0, 0, 1, 0, 0 },
image[1].ToArray<float>()));
Assert.IsTrue(Enumerable.SequenceEqual(new float[] { 0, 0, 0, 0.3333335f, 0.6666665f },
image[2].ToArray<float>()));
tf.compat.v1.disable_eager_execution();
}

[TestMethod]


Loading…
Cancel
Save