Add object detection example and some other minor fixestags/v0.9
@@ -62,6 +62,7 @@ StyleCopReport.xml | |||||
*_p.c | *_p.c | ||||
*_i.h | *_i.h | ||||
*.ilk | *.ilk | ||||
*.meta | |||||
*.obj | *.obj | ||||
*.iobj | *.iobj | ||||
*.pch | *.pch | ||||
@@ -1,4 +1,5 @@ | |||||
# TensorFlow.NET | # TensorFlow.NET | ||||
TensorFlow.NET provides a .NET Standard binding for [TensorFlow](https://www.tensorflow.org/). It aims to implement the complete Tensorflow API in CSharp which allows .NET developers to develop, train and deploy Machine Learning models with the cross-platform .NET Standard framework. | |||||
TensorFlow.NET (TF.NET) provides a .NET Standard binding for [TensorFlow](https://www.tensorflow.org/). It aims to implement the complete Tensorflow API in CSharp which allows .NET developers to develop, train and deploy Machine Learning models with the cross-platform .NET Standard framework. | TensorFlow.NET (TF.NET) provides a .NET Standard binding for [TensorFlow](https://www.tensorflow.org/). It aims to implement the complete Tensorflow API in CSharp which allows .NET developers to develop, train and deploy Machine Learning models with the cross-platform .NET Standard framework. | ||||
[](https://gitter.im/sci-sharp/community) | [](https://gitter.im/sci-sharp/community) | ||||
@@ -9,8 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Examples", "t | |||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\TensorFlowNET.Core\TensorFlowNET.Core.csproj", "{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\TensorFlowNET.Core\TensorFlowNET.Core.csproj", "{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}" | ||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NumSharp.Core", "..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj", "{DE97EAD7-B92C-4112-9690-91C40A97179E}" | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|Any CPU = Debug|Any CPU | Debug|Any CPU = Debug|Any CPU | ||||
@@ -29,10 +27,6 @@ Global | |||||
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.Build.0 = Debug|Any CPU | {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.ActiveCfg = Release|Any CPU | {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.Build.0 = Release|Any CPU | {FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
{DE97EAD7-B92C-4112-9690-91C40A97179E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||||
{DE97EAD7-B92C-4112-9690-91C40A97179E}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||||
{DE97EAD7-B92C-4112-9690-91C40A97179E}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||||
{DE97EAD7-B92C-4112-9690-91C40A97179E}.Release|Any CPU.Build.0 = Release|Any CPU | |||||
EndGlobalSection | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -23,8 +23,9 @@ logistic回归通过函数S将ax+b对应到一个隐状态p,p = S(ax+b),然 | |||||
将t换成ax+b,可以得到逻辑回归模型的参数形式: | 将t换成ax+b,可以得到逻辑回归模型的参数形式: | ||||
P(x;a,b) = 1 / (1 + e^(-ax+b)) | P(x;a,b) = 1 / (1 + e^(-ax+b)) | ||||
 | |||||
sigmoid函数的图像 | |||||
 | |||||
sigmoid函数的图像 | |||||
By the function of the function S, we can limit the output value to the interval [0, 1], | By the function of the function S, we can limit the output value to the interval [0, 1], | ||||
p(x) can then be used to represent the probability p(y=1|x), the probability that y is divided into 1 group when an x occurs. | p(x) can then be used to represent the probability p(y=1|x), the probability that y is divided into 1 group when an x occurs. | ||||
@@ -20,9 +20,32 @@ namespace Tensorflow | |||||
foreach (var op_def in op_list.Op) | foreach (var op_def in op_list.Op) | ||||
_registered_ops[op_def.Name] = op_def; | _registered_ops[op_def.Name] = op_def; | ||||
if (!_registered_ops.ContainsKey("NearestNeighbors")) | |||||
_registered_ops["NearestNeighbors"] = op_NearestNeighbors(); | |||||
} | } | ||||
return _registered_ops; | return _registered_ops; | ||||
} | } | ||||
/// <summary> | |||||
/// Doesn't work because the op can't be found on binary | |||||
/// </summary> | |||||
/// <returns></returns> | |||||
private static OpDef op_NearestNeighbors() | |||||
{ | |||||
var def = new OpDef | |||||
{ | |||||
Name = "NearestNeighbors" | |||||
}; | |||||
def.InputArg.Add(new ArgDef { Name = "points", Type = DataType.DtFloat }); | |||||
def.InputArg.Add(new ArgDef { Name = "centers", Type = DataType.DtFloat }); | |||||
def.InputArg.Add(new ArgDef { Name = "k", Type = DataType.DtInt64 }); | |||||
def.OutputArg.Add(new ArgDef { Name = "nearest_center_indices", Type = DataType.DtInt64 }); | |||||
def.OutputArg.Add(new ArgDef { Name = "nearest_center_distances", Type = DataType.DtFloat }); | |||||
return def; | |||||
} | |||||
} | } | ||||
} | } |
@@ -335,7 +335,7 @@ namespace Tensorflow.Operations | |||||
ret.Enter(); | ret.Enter(); | ||||
foreach (var nested_def in proto.NestedContexts) | foreach (var nested_def in proto.NestedContexts) | ||||
from_control_flow_context_def(nested_def, import_scope: import_scope); | |||||
throw new NotImplementedException(""); | |||||
ret.Exit(); | ret.Exit(); | ||||
return ret; | return ret; | ||||
} | } | ||||
@@ -3,8 +3,7 @@ using System.Collections.Generic; | |||||
using System.Linq; | using System.Linq; | ||||
using System.Text; | using System.Text; | ||||
using Tensorflow.Operations.ControlFlows; | using Tensorflow.Operations.ControlFlows; | ||||
using static Tensorflow.ControlFlowContextDef; | |||||
namespace Tensorflow.Operations | namespace Tensorflow.Operations | ||||
{ | { | ||||
/// <summary> | /// <summary> | ||||
@@ -185,23 +184,6 @@ namespace Tensorflow.Operations | |||||
return null; | return null; | ||||
} | } | ||||
/// <summary> | |||||
/// Deserializes `context_def` into the appropriate ControlFlowContext. | |||||
/// </summary> | |||||
/// <param name="context_def">ControlFlowContextDef proto</param> | |||||
/// <param name="import_scope">Name scope to add</param> | |||||
/// <returns>A ControlFlowContext subclass</returns> | |||||
protected ControlFlowContext from_control_flow_context_def(ControlFlowContextDef context_def, string import_scope = "") | |||||
{ | |||||
switch (context_def.CtxtCase) | |||||
{ | |||||
case CtxtOneofCase.CondCtxt: | |||||
return new CondContext().from_proto(context_def.CondCtxt, import_scope: import_scope); | |||||
} | |||||
throw new NotImplementedException($"Unknown ControlFlowContextDef field: {context_def.CtxtCase}"); | |||||
} | |||||
public object to_proto() | public object to_proto() | ||||
{ | { | ||||
throw new NotImplementedException(); | throw new NotImplementedException(); | ||||
@@ -1,34 +0,0 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace Tensorflow | |||||
{ | |||||
/// <summary> | |||||
/// Convert to other datatype implicitly | |||||
/// </summary> | |||||
public partial class Operation | |||||
{ | |||||
public static implicit operator Operation(IntPtr handle) => new Operation(handle); | |||||
public static implicit operator IntPtr(Operation op) => op._handle; | |||||
public static implicit operator Tensor(Operation op) => op.output; | |||||
public override string ToString() | |||||
{ | |||||
return _handle == IntPtr.Zero ? "tf.Operation Undefined" : $"tf.Operation '{name}' type={OpType}"; | |||||
} | |||||
public override bool Equals(object obj) | |||||
{ | |||||
switch (obj) | |||||
{ | |||||
case IntPtr val: | |||||
return val == _handle; | |||||
case Operation val: | |||||
return val._handle == _handle; | |||||
} | |||||
return base.Equals(obj); | |||||
} | |||||
} | |||||
} |
@@ -248,6 +248,27 @@ namespace Tensorflow | |||||
s.Check(); | s.Check(); | ||||
return NodeDef.Parser.ParseFrom(buffer); | return NodeDef.Parser.ParseFrom(buffer); | ||||
} | } | ||||
} | |||||
public override string ToString() | |||||
{ | |||||
return _handle == IntPtr.Zero ? "tf.Operation Undefined" : $"tf.Operation '{name}' type={OpType}"; | |||||
} | |||||
public static implicit operator Operation(IntPtr handle) => new Operation(handle); | |||||
public static implicit operator IntPtr(Operation op) => op._handle; | |||||
public override bool Equals(object obj) | |||||
{ | |||||
switch (obj) | |||||
{ | |||||
case IntPtr val: | |||||
return val == _handle; | |||||
case Operation val: | |||||
return val._handle == _handle; | |||||
} | |||||
return base.Equals(obj); | |||||
} | } | ||||
/// <summary> | /// <summary> | ||||
@@ -27,11 +27,6 @@ namespace Tensorflow | |||||
return Enumerable.Range(0, end); | return Enumerable.Range(0, end); | ||||
} | } | ||||
protected IEnumerable<int> range(int start, int end) | |||||
{ | |||||
return Enumerable.Range(start, end); | |||||
} | |||||
public static T New<T>(object args) where T : IPyClass | public static T New<T>(object args) where T : IPyClass | ||||
{ | { | ||||
var instance = Activator.CreateInstance<T>(); | var instance = Activator.CreateInstance<T>(); | ||||
@@ -204,12 +204,6 @@ namespace Tensorflow | |||||
switch (tensor.dtype) | switch (tensor.dtype) | ||||
{ | { | ||||
case TF_DataType.TF_BOOL: | |||||
var bools = new bool[tensor.size]; | |||||
for (ulong i = 0; i < tensor.size; i++) | |||||
bools[i] = *(bool*)(offset + (int)(tensor.itemsize * i)); | |||||
nd = np.array(bools).reshape(ndims); | |||||
break; | |||||
case TF_DataType.TF_STRING: | case TF_DataType.TF_STRING: | ||||
var bytes = tensor.Data(); | var bytes = tensor.Data(); | ||||
// wired, don't know why we have to start from offset 9. | // wired, don't know why we have to start from offset 9. | ||||
@@ -217,6 +211,12 @@ namespace Tensorflow | |||||
var str = UTF8Encoding.Default.GetString(bytes, 9, bytes[8]); | var str = UTF8Encoding.Default.GetString(bytes, 9, bytes[8]); | ||||
nd = np.array(str).reshape(); | nd = np.array(str).reshape(); | ||||
break; | break; | ||||
case TF_DataType.TF_UINT8: | |||||
var _bytes = new byte[tensor.size]; | |||||
for (ulong i = 0; i < tensor.size; i++) | |||||
_bytes[i] = *(byte*)(offset + (int)(tensor.itemsize * i)); | |||||
nd = np.array(_bytes).reshape(ndims); | |||||
break; | |||||
case TF_DataType.TF_INT16: | case TF_DataType.TF_INT16: | ||||
var shorts = new short[tensor.size]; | var shorts = new short[tensor.size]; | ||||
for (ulong i = 0; i < tensor.size; i++) | for (ulong i = 0; i < tensor.size; i++) | ||||
@@ -10,9 +10,9 @@ namespace Tensorflow | |||||
/// </summary> | /// </summary> | ||||
public class _ElementFetchMapper : _FetchMapper | public class _ElementFetchMapper : _FetchMapper | ||||
{ | { | ||||
private Func<List<NDArray>, object> _contraction_fn; | |||||
private Func<List<object>, object> _contraction_fn; | |||||
public _ElementFetchMapper(object[] fetches, Func<List<NDArray>, object> contraction_fn) | |||||
public _ElementFetchMapper(object[] fetches, Func<List<object>, object> contraction_fn) | |||||
{ | { | ||||
var g = ops.get_default_graph(); | var g = ops.get_default_graph(); | ||||
ITensorOrOperation el = null; | ITensorOrOperation el = null; | ||||
@@ -31,7 +31,7 @@ namespace Tensorflow | |||||
/// </summary> | /// </summary> | ||||
/// <param name="values"></param> | /// <param name="values"></param> | ||||
/// <returns></returns> | /// <returns></returns> | ||||
public override NDArray build_results(List<NDArray> values) | |||||
public override NDArray build_results(List<object> values) | |||||
{ | { | ||||
NDArray result = null; | NDArray result = null; | ||||
@@ -42,7 +42,7 @@ namespace Tensorflow | |||||
public NDArray build_results(BaseSession session, NDArray[] tensor_values) | public NDArray build_results(BaseSession session, NDArray[] tensor_values) | ||||
{ | { | ||||
var full_values = new List<NDArray>(); | |||||
var full_values = new List<object>(); | |||||
if (_final_fetches.Count != tensor_values.Length) | if (_final_fetches.Count != tensor_values.Length) | ||||
throw new InvalidOperationException("_final_fetches mismatch tensor_values"); | throw new InvalidOperationException("_final_fetches mismatch tensor_values"); | ||||
@@ -24,7 +24,19 @@ namespace Tensorflow | |||||
{ | { | ||||
var type = values[0].GetType(); | var type = values[0].GetType(); | ||||
var nd = new NDArray(type, values.Count); | var nd = new NDArray(type, values.Count); | ||||
nd.SetData(values.ToArray()); | |||||
switch (type.Name) | |||||
{ | |||||
case "Single": | |||||
nd.SetData(values.Select(x => (float)x).ToArray()); | |||||
break; | |||||
case "NDArray": | |||||
NDArray[] arr = values.Select(x => (NDArray)x).ToArray(); | |||||
nd = new NDArray(arr); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
return nd; | return nd; | ||||
} | } | ||||
@@ -57,8 +57,4 @@ More math/ linalg APIs.</PackageReleaseNotes> | |||||
<Folder Include="Keras\Initializers\" /> | <Folder Include="Keras\Initializers\" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | |||||
<ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" /> | |||||
</ItemGroup> | |||||
</Project> | </Project> |
@@ -67,7 +67,8 @@ namespace Tensorflow | |||||
case "Double": | case "Double": | ||||
Marshal.Copy(nd1.Data<double>(), 0, dotHandle, nd.size); | Marshal.Copy(nd1.Data<double>(), 0, dotHandle, nd.size); | ||||
break; | break; | ||||
//case "Byte": | |||||
case "Byte": | |||||
Marshal.Copy(nd1.Data<byte>(), 0, dotHandle, nd.size); | |||||
/*var bb = nd.Data<byte>(); | /*var bb = nd.Data<byte>(); | ||||
var bytes = Marshal.AllocHGlobal(bb.Length); | var bytes = Marshal.AllocHGlobal(bb.Length); | ||||
Marshal.Copy(bb, 0, bytes, bb.Length); | Marshal.Copy(bb, 0, bytes, bb.Length); | ||||
@@ -195,6 +195,7 @@ namespace Tensorflow | |||||
case "Double": | case "Double": | ||||
return TF_DataType.TF_DOUBLE; | return TF_DataType.TF_DOUBLE; | ||||
case "Byte": | case "Byte": | ||||
return TF_DataType.TF_UINT8; | |||||
case "String": | case "String": | ||||
return TF_DataType.TF_STRING; | return TF_DataType.TF_STRING; | ||||
default: | default: | ||||
@@ -2,7 +2,6 @@ | |||||
using System.Collections.Generic; | using System.Collections.Generic; | ||||
using System.Linq; | using System.Linq; | ||||
using System.Text; | using System.Text; | ||||
using Tensorflow.Operations; | |||||
namespace Tensorflow | namespace Tensorflow | ||||
{ | { | ||||
@@ -116,9 +115,6 @@ namespace Tensorflow | |||||
case List<ITensorOrOperation> values: | case List<ITensorOrOperation> values: | ||||
foreach (var element in values) ; | foreach (var element in values) ; | ||||
break; | break; | ||||
case List<CondContext> values: | |||||
foreach (var element in values) ; | |||||
break; | |||||
default: | default: | ||||
throw new NotImplementedException("_build_internal.check_collection_list"); | throw new NotImplementedException("_build_internal.check_collection_list"); | ||||
} | } | ||||
@@ -0,0 +1,169 @@ | |||||
using Newtonsoft.Json; | |||||
using NumSharp; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Text; | |||||
using Tensorflow; | |||||
using TensorFlowNET.Examples.Utility; | |||||
using System.Drawing; | |||||
using System.Drawing.Drawing2D; | |||||
using System.Linq; | |||||
namespace TensorFlowNET.Examples | |||||
{ | |||||
public class ObjectDetection : Python, IExample | |||||
{ | |||||
public int Priority => 7; | |||||
public bool Enabled { get; set; } = true; | |||||
public string Name => "Image Recognition"; | |||||
public float MIN_SCORE = 0.5f; | |||||
string modelDir = "ssd_mobilenet_v1_coco_2018_01_28"; | |||||
string imageDir = "images"; | |||||
string pbFile = "frozen_inference_graph.pb"; | |||||
string labelFile = "mscoco_label_map.pbtxt"; | |||||
string picFile = "input.jpg"; | |||||
public bool Run() | |||||
{ | |||||
//buildOutputImage(null); | |||||
// read in the input image | |||||
var imgArr = ReadTensorFromImageFile(Path.Join(imageDir, "input.jpg")); | |||||
var graph = new Graph().as_default(); | |||||
graph.Import(Path.Join(modelDir, pbFile)); | |||||
var tensorNum = graph.OperationByName("num_detections").outputs[0]; | |||||
var tensorBoxes = graph.OperationByName("detection_boxes").outputs[0]; | |||||
var tensorScores = graph.OperationByName("detection_scores").outputs[0]; | |||||
var tensorClasses = graph.OperationByName("detection_classes").outputs[0]; | |||||
var imgTensor = graph.OperationByName("image_tensor").outputs[0]; | |||||
Tensor[] outTensorArr = new Tensor[] { tensorNum, tensorBoxes, tensorScores, tensorClasses }; | |||||
with(tf.Session(graph), sess => | |||||
{ | |||||
var results = sess.run(outTensorArr, new FeedItem(imgTensor, imgArr)); | |||||
NDArray[] resultArr = results.Data<NDArray>(); | |||||
buildOutputImage(resultArr); | |||||
}); | |||||
return true; | |||||
} | |||||
public void PrepareData() | |||||
{ | |||||
if (!Directory.Exists(modelDir)) | |||||
Directory.CreateDirectory(modelDir); | |||||
if (!File.Exists(Path.Join(modelDir, "ssd_mobilenet_v1_coco.tar.gz"))) | |||||
{ | |||||
// get model file | |||||
string url = "http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2018_01_28.tar.gz"; | |||||
Utility.Web.Download(url, modelDir, "ssd_mobilenet_v1_coco.tar.gz"); | |||||
} | |||||
if (!File.Exists(Path.Join(modelDir, "frozen_inference_graph.pb"))) | |||||
{ | |||||
Utility.Compress.ExtractTGZ(Path.Join(modelDir, "ssd_mobilenet_v1_coco.tar.gz"), "./"); | |||||
} | |||||
// download sample picture | |||||
if (!Directory.Exists(imageDir)) | |||||
Directory.CreateDirectory(imageDir); | |||||
if (!File.Exists(Path.Join(imageDir, "input.jpg"))) | |||||
{ | |||||
string url = $"https://github.com/tensorflow/models/raw/master/research/object_detection/test_images/image2.jpg"; | |||||
Utility.Web.Download(url, imageDir, "input.jpg"); | |||||
} | |||||
// download the pbtxt file | |||||
if (!File.Exists(Path.Join(modelDir, "mscoco_label_map.pbtxt"))) | |||||
{ | |||||
string url = $"https://github.com/tensorflow/models/blob/master/research/object_detection/data/mscoco_label_map.pbtxt"; | |||||
Utility.Web.Download(url, modelDir, "mscoco_label_map.pbtxt"); | |||||
} | |||||
} | |||||
private NDArray ReadTensorFromImageFile(string file_name) | |||||
{ | |||||
return with(tf.Graph().as_default(), graph => | |||||
{ | |||||
var file_reader = tf.read_file(file_name, "file_reader"); | |||||
var decodeJpeg = tf.image.decode_jpeg(file_reader, channels: 3, name: "DecodeJpeg"); | |||||
var casted = tf.cast(decodeJpeg, TF_DataType.TF_UINT8); | |||||
var dims_expander = tf.expand_dims(casted, 0); | |||||
return with(tf.Session(graph), sess => sess.run(dims_expander)); | |||||
}); | |||||
} | |||||
private void buildOutputImage(NDArray[] resultArr) | |||||
{ | |||||
// get pbtxt items | |||||
PbtxtItems pbTxtItems = PbtxtParser.ParsePbtxtFile(Path.Join(modelDir, "mscoco_label_map.pbtxt")); | |||||
// get bitmap | |||||
Bitmap bitmap = new Bitmap(Path.Join(imageDir, "input.jpg")); | |||||
float[] scores = resultArr[2].Data<float>(); | |||||
for (int i=0; i<scores.Length; i++) | |||||
{ | |||||
float score = scores[i]; | |||||
if (score > MIN_SCORE) | |||||
{ | |||||
//var boxes = resultArr[1].Data<float[,,]>(); | |||||
float[] boxes = resultArr[1].Data<float>(); | |||||
float top = boxes[i * 4] * bitmap.Height; | |||||
float left = boxes[i * 4 + 1] * bitmap.Width; | |||||
float bottom = boxes[i * 4 + 2] * bitmap.Height; | |||||
float right = boxes[i * 4 + 3] * bitmap.Width; | |||||
Rectangle rect = new Rectangle() | |||||
{ | |||||
X = (int)left, | |||||
Y = (int)top, | |||||
Width = (int)(right - left), | |||||
Height = (int)(bottom - top) | |||||
}; | |||||
float[] ids = resultArr[3].Data<float>(); | |||||
string name = pbTxtItems.items.Where(w => w.id == (int)ids[i]).Select(s=>s.display_name).FirstOrDefault(); | |||||
drawObjectOnBitmap(bitmap, rect, score, name); | |||||
} | |||||
} | |||||
bitmap.Save(Path.Join(imageDir, "output.jpg")); | |||||
} | |||||
private void drawObjectOnBitmap(Bitmap bmp, Rectangle rect, float score, string name) | |||||
{ | |||||
using (Graphics graphic = Graphics.FromImage(bmp)) | |||||
{ | |||||
graphic.SmoothingMode = SmoothingMode.AntiAlias; | |||||
using (Pen pen = new Pen(Color.Red, 2)) | |||||
{ | |||||
graphic.DrawRectangle(pen, rect); | |||||
Point p = new Point(rect.Right + 5, rect.Top + 5); | |||||
string text = string.Format("{0}:{1}%", name, (int)(score * 100)); | |||||
graphic.DrawString(text, new Font("Verdana", 8), Brushes.Red, p); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -10,10 +10,10 @@ | |||||
<PackageReference Include="Colorful.Console" Version="1.2.9" /> | <PackageReference Include="Colorful.Console" Version="1.2.9" /> | ||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> | <PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> | ||||
<PackageReference Include="SharpZipLib" Version="1.1.0" /> | <PackageReference Include="SharpZipLib" Version="1.1.0" /> | ||||
<PackageReference Include="System.Drawing.Common" Version="4.5.1" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" /> | |||||
<ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -0,0 +1,74 @@ | |||||
using Newtonsoft.Json; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
namespace TensorFlowNET.Examples.Utility | |||||
{ | |||||
public class PbtxtItem | |||||
{ | |||||
public string name { get; set; } | |||||
public int id { get; set; } | |||||
public string display_name { get; set; } | |||||
} | |||||
public class PbtxtItems | |||||
{ | |||||
public List<PbtxtItem> items { get; set; } | |||||
} | |||||
public class PbtxtParser | |||||
{ | |||||
public static PbtxtItems ParsePbtxtFile(string filePath) | |||||
{ | |||||
string line; | |||||
string newText = "{\"items\":["; | |||||
try | |||||
{ | |||||
using (System.IO.StreamReader reader = new System.IO.StreamReader(filePath)) | |||||
{ | |||||
while ((line = reader.ReadLine()) != null) | |||||
{ | |||||
string newline = string.Empty; | |||||
if (line.Contains("{")) | |||||
{ | |||||
newline = line.Replace("item", "").Trim(); | |||||
//newText += line.Insert(line.IndexOf("=") + 1, "\"") + "\","; | |||||
newText += newline; | |||||
} | |||||
else if (line.Contains("}")) | |||||
{ | |||||
newText = newText.Remove(newText.Length - 1); | |||||
newText += line; | |||||
newText += ","; | |||||
} | |||||
else | |||||
{ | |||||
newline = line.Replace(":", "\":").Trim(); | |||||
newline = "\"" + newline;// newline.Insert(0, "\""); | |||||
newline += ","; | |||||
newText += newline; | |||||
} | |||||
} | |||||
newText = newText.Remove(newText.Length - 1); | |||||
newText += "]}"; | |||||
reader.Close(); | |||||
} | |||||
PbtxtItems items = JsonConvert.DeserializeObject<PbtxtItems>(newText); | |||||
return items; | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
return null; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -22,7 +22,6 @@ | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" /> | |||||
<ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | <ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | ||||
<ProjectReference Include="..\TensorFlowNET.Examples\TensorFlowNET.Examples.csproj" /> | <ProjectReference Include="..\TensorFlowNET.Examples\TensorFlowNET.Examples.csproj" /> | ||||
</ItemGroup> | </ItemGroup> | ||||