diff --git a/data/img001.bmp b/data/img001.bmp
new file mode 100644
index 00000000..86cfa972
Binary files /dev/null and b/data/img001.bmp differ
diff --git a/src/TensorFlowNET.Core/APIs/tf.array.cs b/src/TensorFlowNET.Core/APIs/tf.array.cs
index 4d9c3da5..2b49a92b 100644
--- a/src/TensorFlowNET.Core/APIs/tf.array.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.array.cs
@@ -174,6 +174,20 @@ namespace Tensorflow
return array_ops.reverse(tensor, axis, name: name);
}
+
+ ///
+ /// Reverses specific dimensions of a tensor.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Tensor reverse_v2(Tensor tensor, int[] axis, string name = null)
+ => gen_array_ops.reverse_v2(tensor, ops.convert_to_tensor(axis), name: name);
+
+ public Tensor reverse_v2(Tensor tensor, Tensor axis, string name = null)
+ => gen_array_ops.reverse_v2(tensor, axis, name: name);
+
///
/// Returns the rank of a tensor.
///
diff --git a/src/TensorFlowNET.Core/APIs/tf.image.cs b/src/TensorFlowNET.Core/APIs/tf.image.cs
index ac9cbc60..41ef5296 100644
--- a/src/TensorFlowNET.Core/APIs/tf.image.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.image.cs
@@ -339,6 +339,13 @@ namespace Tensorflow
=> image_ops_impl.decode_image(contents, channels: channels, dtype: dtype,
name: name, expand_animations: expand_animations);
+ public Tensor encode_png(Tensor contents, string name = null)
+ => image_ops_impl.encode_png(contents, name: name);
+
+ public Tensor encode_jpeg(Tensor contents, string name = null)
+ => image_ops_impl.encode_jpeg(contents, name: name);
+
+
///
/// Convenience function to check if the 'contents' encodes a JPEG image.
///
diff --git a/src/TensorFlowNET.Core/APIs/tf.io.cs b/src/TensorFlowNET.Core/APIs/tf.io.cs
index be1e86e6..4cb18070 100644
--- a/src/TensorFlowNET.Core/APIs/tf.io.cs
+++ b/src/TensorFlowNET.Core/APIs/tf.io.cs
@@ -16,6 +16,7 @@
using System.Collections.Generic;
using Tensorflow.IO;
+using Tensorflow.Operations;
namespace Tensorflow
{
@@ -46,6 +47,12 @@ namespace Tensorflow
public Tensor[] restore_v2(Tensor prefix, string[] tensor_names,
string[] shape_and_slices, TF_DataType[] dtypes, string name = null)
=> ops.restore_v2(prefix, tensor_names, shape_and_slices, dtypes, name: name);
+
+ public void write_file(string filename, Tensor conentes, string name = null)
+ => write_file(Tensorflow.ops.convert_to_tensor(filename, TF_DataType.TF_STRING), conentes, name);
+
+ public void write_file(Tensor filename, Tensor conentes, string name = null)
+ => gen_ops.write_file(filename, conentes, name);
}
public GFile gfile = new GFile();
diff --git a/src/TensorFlowNET.Core/Operations/gen_ops.cs b/src/TensorFlowNET.Core/Operations/gen_ops.cs
index 5fa4c97d..ed756740 100644
--- a/src/TensorFlowNET.Core/Operations/gen_ops.cs
+++ b/src/TensorFlowNET.Core/Operations/gen_ops.cs
@@ -39083,13 +39083,14 @@ namespace Tensorflow.Operations
///
/// creates directory if not existing.
///
- public static Operation write_file(Tensor filename, Tensor contents, string name = "WriteFile")
+ public static Tensor write_file(Tensor filename, Tensor contents, string name = "WriteFile")
{
var dict = new Dictionary();
dict["filename"] = filename;
dict["contents"] = contents;
var op = tf.OpDefLib._apply_op_helper("WriteFile", name: name, keywords: dict);
- return op;
+ op.run();
+ return op.output;
}
///
diff --git a/src/TensorFlowNET.Core/Operations/image_ops_impl.cs b/src/TensorFlowNET.Core/Operations/image_ops_impl.cs
index 318b8b14..0c827b7f 100644
--- a/src/TensorFlowNET.Core/Operations/image_ops_impl.cs
+++ b/src/TensorFlowNET.Core/Operations/image_ops_impl.cs
@@ -2047,6 +2047,22 @@ new_height, new_width");
});
}
+ public static Tensor encode_jpeg(Tensor contents, string name = null)
+ {
+ return tf_with(ops.name_scope(name, "encode_jpeg"), scope =>
+ {
+ return gen_ops.encode_jpeg(contents, name:name);
+ });
+ }
+
+ public static Tensor encode_png(Tensor contents, string name = null)
+ {
+ return tf_with(ops.name_scope(name, "encode_png"), scope =>
+ {
+ return gen_ops.encode_png(contents, name: name);
+ });
+ }
+
public static Tensor is_jpeg(Tensor contents, string name = null)
{
return tf_with(ops.name_scope(name, "is_jpeg"), scope =>
diff --git a/test/TensorFlowNET.Graph.UnitTest/ImageTest.cs b/test/TensorFlowNET.Graph.UnitTest/ImageTest.cs
index d671b609..6a430443 100644
--- a/test/TensorFlowNET.Graph.UnitTest/ImageTest.cs
+++ b/test/TensorFlowNET.Graph.UnitTest/ImageTest.cs
@@ -4,6 +4,7 @@ using System.Linq;
using Tensorflow;
using static Tensorflow.Binding;
using System;
+using System.IO;
namespace TensorFlowNET.UnitTest
{
@@ -164,5 +165,32 @@ namespace TensorFlowNET.UnitTest
Assert.AreEqual(result.size, 16ul);
Assert.AreEqual(result[0, 0, 0, 0], 12f);
}
+
+ [TestMethod]
+ public void ImageSaveTest()
+ {
+ var imgPath = TestHelper.GetFullPathFromDataDir("img001.bmp");
+ var jpegImgPath = TestHelper.GetFullPathFromDataDir("img001.jpeg");
+ var pngImgPath = TestHelper.GetFullPathFromDataDir("img001.png");
+
+ File.Delete(jpegImgPath);
+ File.Delete(pngImgPath);
+
+ var contents = tf.io.read_file(imgPath);
+ var bmp = tf.image.decode_image(contents);
+ Assert.AreEqual(bmp.name, "decode_image/DecodeImage:0");
+
+ var jpeg = tf.image.encode_jpeg(bmp);
+ tf.io.write_file(jpegImgPath, jpeg);
+ Assert.IsTrue(File.Exists(jpegImgPath));
+
+ var png = tf.image.encode_png(bmp);
+ tf.io.write_file(pngImgPath, png);
+ Assert.IsTrue(File.Exists(pngImgPath));
+
+ // 如果要测试图片正确性,可以注释下面两行代码
+ File.Delete(jpegImgPath);
+ File.Delete(pngImgPath);
+ }
}
}
diff --git a/test/TensorFlowNET.UnitTest/ManagedAPI/ArrayOpsTest.cs b/test/TensorFlowNET.UnitTest/ManagedAPI/ArrayOpsTest.cs
index 675689bb..5b538d26 100644
--- a/test/TensorFlowNET.UnitTest/ManagedAPI/ArrayOpsTest.cs
+++ b/test/TensorFlowNET.UnitTest/ManagedAPI/ArrayOpsTest.cs
@@ -4,6 +4,163 @@ using Tensorflow;
using static Tensorflow.Binding;
using System.Linq;
+namespace TensorFlowNET.UnitTest.ManagedAPI
+{
+ [TestClass]
+ public class ArrayOpsTest : EagerModeTestBase
+ {
+ ///
+ /// https://www.tensorflow.org/api_docs/python/tf/slice
+ ///
+ [TestMethod]
+ public void Slice()
+ {
+ // Tests based on example code in TF documentation
+ var input_array = tf.constant(np.array(new int[] { 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6 }).reshape((3, 2, 3)));
+ var indices = tf.constant(np.array(new int[] { 0, 2 }));
+
+ var r1 = array_ops.slice(input_array, ops.convert_n_to_tensor(new object[] { 1, 0, 0 }), ops.convert_n_to_tensor(new object[] { 1, 1, 3 }));
+ Assert.AreEqual(new Shape(1, 1, 3), r1.shape);
+ var r1np = r1.numpy();
+ Assert.AreEqual(r1np[0, 0, 0], 3);
+ Assert.AreEqual(r1np[0, 0, 1], 3);
+ Assert.AreEqual(r1np[0, 0, 2], 3);
+
+
+ var r2 = array_ops.slice(input_array, ops.convert_n_to_tensor(new object[] { 1, 0, 0 }), ops.convert_n_to_tensor(new object[] { 1, 2, 3 }));
+ Assert.AreEqual(new Shape(1, 2, 3), r2.shape);
+ var r2np = r2.numpy();
+ Assert.AreEqual(r2np[0, 0, 0], 3);
+ Assert.AreEqual(r2np[0, 0, 1], 3);
+ Assert.AreEqual(r2np[0, 0, 2], 3);
+ Assert.AreEqual(r2np[0, 1, 0], 4);
+ Assert.AreEqual(r2np[0, 1, 1], 4);
+ Assert.AreEqual(r2np[0, 1, 2], 4);
+
+ var r3 = array_ops.slice(input_array, ops.convert_n_to_tensor(new object[] { 1, 0, 0 }), ops.convert_n_to_tensor(new object[] { 2, 1, 3 }));
+ Assert.AreEqual(new Shape(2, 1, 3), r3.shape);
+ var r3np = r3.numpy();
+ Assert.AreEqual(r3np[0, 0, 0], 3);
+ Assert.AreEqual(r3np[0, 0, 1], 3);
+ Assert.AreEqual(r3np[0, 0, 2], 3);
+ Assert.AreEqual(r3np[1, 0, 0], 5);
+ Assert.AreEqual(r3np[1, 0, 1], 5);
+ Assert.AreEqual(r3np[1, 0, 2], 5);
+ }
+
+ ///
+ /// https://www.tensorflow.org/api_docs/python/tf/gather
+ ///
+ [TestMethod]
+ public void Gather()
+ {
+ var input_array = tf.constant(np.arange(12).reshape((3, 4)).astype(np.float32));
+ var indices = tf.constant(np.array(new int[] { 0, 2 }));
+
+ var result = array_ops.gather(input_array, indices);
+ Assert.AreEqual(new Shape(2, 4), result.shape);
+ Assert.AreEqual(result.numpy()[0, 0], 0.0f);
+ Assert.AreEqual(result.numpy()[0, 1], 1.0f);
+ Assert.AreEqual(result.numpy()[1, 3], 11.0f);
+
+ // Tests based on example code in Python doc string for tf.gather()
+
+ var p1 = tf.random.normal(new Shape(5, 6, 7, 8));
+ var i1 = tf.random_uniform(new Shape(10, 11), maxval: 7, dtype: tf.int32);
+ var r1 = tf.gather(p1, i1, axis: 2);
+ Assert.AreEqual(new Shape(5, 6, 10, 11, 8), r1.shape);
+
+ var p2 = tf.random.normal(new Shape(4, 3));
+ var i2 = tf.constant(new int[,] { { 0, 2 } });
+ var r2 = tf.gather(p2, i2, axis: 0);
+ Assert.AreEqual(new Shape(1, 2, 3), r2.shape);
+
+ var r3 = tf.gather(p2, i2, axis: 1);
+ Assert.AreEqual(new Shape(4, 1, 2), r3.shape);
+ }
+
+ ///
+ /// https://www.tensorflow.org/api_docs/python/tf/TensorArray
+ ///
+ [TestMethod]
+ public void TensorArray()
+ {
+ var ta = tf.TensorArray(tf.float32, size: 0, dynamic_size: true, clear_after_read: false);
+ ta.write(0, 10);
+ ta.write(1, 20);
+ ta.write(2, 30);
+ Assert.AreEqual(ta.read(0).numpy(), 10f);
+ Assert.AreEqual(ta.read(1).numpy(), 20f);
+ Assert.AreEqual(ta.read(2).numpy(), 30f);
+ }
+
+ ///
+ ///
+ ///
+ [TestMethod]
+ public void Reverse()
+ {
+ /*
+ * python run get test data code:
+
+import tensorflow as tf
+
+data=[[1, 2, 3], [4, 5, 6], [7,8,9]]
+
+data2 = tf.constant(data)
+
+print('test data shaper:', data2.shape)
+print('test data:', data2)
+
+axis = [-2,-1,0,1]
+for i in axis:
+ print('')
+ print('axis:', i)
+ ax = tf.constant([i])
+ datar = tf.reverse(data2, ax)
+ datar2 = array_ops.reverse(data2, ax)
+ print(datar)
+ print(datar2)
+
+ * */
+ var inputData = np.array(new int[,] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } });
+ var expectedOutput = new[] {
+ // np.array(new int[,] { { 7, 8, 9 }, { 4, 5, 6 }, { 1, 2, 3 } }),
+ np.array(new int[,] { { 3, 2, 1 }, { 6, 5, 4 }, { 9, 8, 7 } }),
+ np.array(new int[,] { { 7, 8, 9 }, { 4, 5, 6 }, { 1, 2, 3 } }),
+ np.array(new int[,] { { 3, 2, 1 }, { 6, 5, 4 }, { 9, 8, 7 } })
+ };
+
+ var axes = new int [] {
+ -1,
+ 0,
+ 1 };
+ for (var i = 0; i < axes.Length; i++)
+ {
+ var axis = axes[i];
+ var expected = tf.constant(expectedOutput[i]).numpy();
+
+ var inputTensor = tf.constant(inputData);
+ var axisTrensor = tf.constant(new[] { axis });
+
+ var outputTensor = tf.reverse_v2(inputTensor, axisTrensor);
+ var npout = outputTensor.numpy();
+ Assert.IsTrue(Enumerable.SequenceEqual(npout, expected), $"axis:{axis}");
+
+ var outputTensor2 = tf.reverse_v2(inputTensor, new[] { axis } );
+ var npout2 = outputTensor2.numpy();
+ Assert.IsTrue(Enumerable.SequenceEqual(npout2, expected), $"axis:{axis}");
+
+ }
+ }
+ }
+}
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Tensorflow.NumPy;
+using Tensorflow;
+using static Tensorflow.Binding;
+using System.Linq;
+
namespace TensorFlowNET.UnitTest.ManagedAPI
{
[TestClass]