├── .gitignore ├── README.md ├── coco.prototxt ├── csharp ├── App.config ├── Form1.Designer.cs ├── Form1.cs ├── Form1.resx ├── Onnx.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── object_detection.csproj ├── object_detection.sln └── packages.config ├── docs ├── csharp.jpg └── python.jpg ├── images ├── airport.jpg ├── persons.jpg └── school.jpg ├── object_detection_image_onnx.py └── ssd_mobilenet_v1_coco_2018_01_28 ├── frozen.onnx └── model.onnx /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # .NET Core 11 | project.lock.json 12 | project.fragment.lock.json 13 | artifacts/ 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | build/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | 27 | # Roslyn cache directories 28 | *.ide/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | #NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | *_i.c 44 | *_p.c 45 | *_i.h 46 | *.ilk 47 | *.meta 48 | *.obj 49 | *.pch 50 | *.pdb 51 | *.pgc 52 | *.pgd 53 | *.rsp 54 | *.sbr 55 | *.tlb 56 | *.tli 57 | *.tlh 58 | *.tmp 59 | *.tmp_proj 60 | *.log 61 | *.vspscc 62 | *.vssscc 63 | .builds 64 | *.pidb 65 | *.svclog 66 | *.scc 67 | 68 | # Chutzpah Test files 69 | _Chutzpah* 70 | 71 | # Visual C++ cache files 72 | ipch/ 73 | *.aps 74 | *.ncb 75 | *.opensdf 76 | *.sdf 77 | *.cachefile 78 | 79 | # Visual Studio profiler 80 | *.psess 81 | *.vsp 82 | *.vspx 83 | 84 | # TFS 2012 Local Workspace 85 | $tf/ 86 | 87 | # Guidance Automation Toolkit 88 | *.gpState 89 | 90 | # ReSharper is a .NET coding add-in 91 | _ReSharper*/ 92 | *.[Rr]e[Ss]harper 93 | *.DotSettings.user 94 | 95 | # JustCode is a .NET coding addin-in 96 | .JustCode 97 | 98 | # TeamCity is a build add-in 99 | _TeamCity* 100 | 101 | # DotCover is a Code Coverage Tool 102 | *.dotCover 103 | 104 | # NCrunch 105 | _NCrunch_* 106 | .*crunch*.local.xml 107 | 108 | # MightyMoose 109 | *.mm.* 110 | AutoTest.Net/ 111 | 112 | # Web workbench (sass) 113 | .sass-cache/ 114 | 115 | # Installshield output folder 116 | [Ee]xpress/ 117 | 118 | # DocProject is a documentation generator add-in 119 | DocProject/buildhelp/ 120 | DocProject/Help/*.HxT 121 | DocProject/Help/*.HxC 122 | DocProject/Help/*.hhc 123 | DocProject/Help/*.hhk 124 | DocProject/Help/*.hhp 125 | DocProject/Help/Html2 126 | DocProject/Help/html 127 | 128 | # Click-Once directory 129 | publish/ 130 | 131 | # Publish Web Output 132 | *.[Pp]ublish.xml 133 | *.azurePubxml 134 | # TODO: Comment the next line if you want to checkin your web deploy settings 135 | # but database connection strings (with potential passwords) will be unencrypted 136 | *.pubxml 137 | *.publishproj 138 | 139 | # NuGet Packages 140 | *.nupkg 141 | # The packages folder can be ignored because of Package Restore 142 | **/packages/* 143 | # except build/, which is used as an MSBuild target. 144 | !**/packages/build/ 145 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 146 | #!**/packages/repositories.config 147 | 148 | # Windows Azure Build Output 149 | csx/ 150 | *.build.csdef 151 | 152 | # Windows Store app package directory 153 | AppPackages/ 154 | 155 | # Others 156 | *.Cache 157 | ClientBin/ 158 | [Ss]tyle[Cc]op.* 159 | ~$* 160 | *~ 161 | *.dbmdl 162 | *.dbproj.schemaview 163 | #*.pfx 164 | #*.publishsettings 165 | node_modules/ 166 | bower_components/ 167 | 168 | # RIA/Silverlight projects 169 | Generated_Code/ 170 | 171 | # Backup & report files from converting an old project file 172 | # to a newer Visual Studio version. Backup files are not needed, 173 | # because we have git ;-) 174 | _UpgradeReport_Files/ 175 | Backup*/ 176 | UpgradeLog*.XML 177 | UpgradeLog*.htm 178 | 179 | # SQL Server files 180 | *.mdf 181 | *.ldf 182 | 183 | # Business Intelligence projects 184 | *.rdl.data 185 | *.bim.layout 186 | *.bim_*.settings 187 | 188 | # Microsoft Fakes 189 | FakesAssemblies/ 190 | 191 | # Installer files 192 | Installer/Files 193 | Installer/Installer/output/ 194 | 195 | # Visual Studio files 196 | *.VC.opendb 197 | .vs/ 198 | .idea/ 199 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Running TF object detection model using onnxruntime 2 | 3 | 4 | ## Installation 5 | Install **python 3+** dependencies. 6 | ``` 7 | tensorflow: 1.12.0 8 | onnx: 1.6.0 9 | tf2onnx: 1.5.5 10 | onnxruntime: 1.1.0 11 | ``` 12 | 13 | ## TF to ONNX 14 | Download TF object detection model trained on [**COCO dataset**](https://cocodataset.org/#home) from the [**Model Zoo**](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/tf1_detection_zoo.md) and convert it to onnx model. 15 | For example download [**ssd_mobilenet_v1_coco_2018_01_28**](http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v1_coco_2018_01_28.tar.gz) and convert it to onnx model from **saved_model.pb** 16 | ``` 17 | python -m tf2onnx.convert 18 | --opset 11 19 | --fold_const 20 | --saved-model ssd_mobilenet_v1_coco_2018_01_28/saved_model/ 21 | --output ssd_mobilenet_v1_coco_2018_01_28/model.onnx 22 | ``` 23 | or from **frozen_inference_graph.pb** 24 | ``` 25 | python -m tf2onnx.convert 26 | --opset 11 27 | --fold_const 28 | --graphdef ssd_mobilenet_v1_coco_2018_01_28/frozen_inference_graph.pb 29 | --output ssd_mobilenet_v1_coco_2018_01_28/frozen.onnx 30 | --inputs image_tensor:0 31 | --outputs detection_boxes:0,detection_classes:0,detection_scores:0,num_detections:0 32 | ``` 33 | For run **python** and **C#** examples below download [**path**](https://yadi.sk/d/ap5F1VPma6qMGQ?w=1) with already-made **ssd_mobilenet_v1_coco_2018_01_28** onnx models and move it to repository root folder. 34 | 35 | ## Python script 36 | Run python script [**object_detection_image_onnx.py**](object_detection_image_onnx.py) to test converted onnx model. 37 |

38 |

Figure 1. Python example

39 | 40 | ## C# application 41 | Build [**C#**](/csharp) source code and run application. 42 |

43 |

Figure 2. C# example

44 | 45 | ## References 46 | [1] TensorFlow detection [**model zoo**](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md). 47 | [2] Tutorial: how to convert them to ONNX and run them under [**onnxruntime**](https://github.com/onnx/tensorflow-onnx/blob/master/tutorials/ConvertingSSDMobilenetToONNX.ipynb). 48 | [3] Microsoft: ONNX Runtime [**C#**](https://github.com/microsoft/onnxruntime/blob/master/docs/CSharp_API.md) API. 49 | -------------------------------------------------------------------------------- /coco.prototxt: -------------------------------------------------------------------------------- 1 | person 2 | bicycle 3 | car 4 | motorcycle 5 | airplane 6 | bus 7 | train 8 | truck 9 | boat 10 | traffic light 11 | fire hydrant 12 | --unknown 13 | stop sign 14 | parking meter 15 | bench 16 | bird 17 | cat 18 | dog 19 | horse 20 | sheep 21 | cow 22 | elephant 23 | bear 24 | zebra 25 | giraffe 26 | --unknown 27 | backpack 28 | umbrella 29 | --unknown 30 | --unknown 31 | handbag 32 | tie 33 | suitcase 34 | frisbee 35 | skis 36 | snowboard 37 | sports ball 38 | kite 39 | baseball bat 40 | baseball glove 41 | skateboard 42 | surfboard 43 | tennis racket 44 | bottle 45 | --unknown 46 | wine glass 47 | cup 48 | fork 49 | knife 50 | spoon 51 | bowl 52 | banana 53 | apple 54 | sandwich 55 | orange 56 | broccoli 57 | carrot 58 | hot dog 59 | pizza 60 | donut 61 | cake 62 | chair 63 | couch 64 | potted plant 65 | bed 66 | --unknown 67 | dining table 68 | --unknown 69 | --unknown 70 | toilet 71 | --unknown 72 | tv 73 | laptop 74 | mouse 75 | remote 76 | keyboard 77 | cell phone 78 | microwave 79 | oven 80 | toaster 81 | sink 82 | refrigerator 83 | --unknown 84 | book 85 | clock 86 | vase 87 | scissors 88 | teddy bear 89 | hair drier 90 | toothbrush -------------------------------------------------------------------------------- /csharp/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /csharp/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace object_detection 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // Form1 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; 38 | this.ClientSize = new System.Drawing.Size(550, 415); 39 | this.Name = "Form1"; 40 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 41 | this.Text = "Form1"; 42 | this.Load += new System.EventHandler(this.Form1_Load); 43 | this.ResumeLayout(false); 44 | 45 | } 46 | 47 | #endregion 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /csharp/Form1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.ML.OnnxRuntime; 2 | using Microsoft.ML.OnnxRuntime.Tensors; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Windows.Forms; 9 | 10 | namespace object_detection 11 | { 12 | public partial class Form1 : Form 13 | { 14 | #region Private data 15 | 16 | private readonly string model = @"..\..\..\ssd_mobilenet_v1_coco_2018_01_28\model.onnx"; 17 | private readonly string prototxt = @"..\..\..\coco.prototxt"; 18 | private readonly InferenceSession session; 19 | 20 | #endregion 21 | 22 | #region Form voids 23 | 24 | public Form1() 25 | { 26 | InitializeComponent(); 27 | DragDrop += Form1_DragDrop; 28 | DragEnter += Form1_DragEnter; 29 | AllowDrop = true; 30 | session = new InferenceSession(model); 31 | string file = @"..\..\..\\images\airport.jpg"; 32 | BackgroundImage = new Bitmap(file); 33 | } 34 | 35 | private void Form1_DragEnter(object sender, DragEventArgs e) 36 | { 37 | e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.All : DragDropEffects.None; 38 | } 39 | 40 | private void Form1_DragDrop(object sender, DragEventArgs e) 41 | { 42 | Cursor = Cursors.WaitCursor; 43 | var file = ((string[])e.Data.GetData(DataFormats.FileDrop, true))[0]; 44 | BackgroundImage?.Dispose(); 45 | BackgroundImage = new Bitmap(file, false); 46 | Process(); 47 | Cursor = Cursors.Default; 48 | } 49 | 50 | private void Form1_Load(object sender, EventArgs e) 51 | { 52 | Process(); 53 | } 54 | 55 | private void Process() 56 | { 57 | // params 58 | var threshold = 0.0f; 59 | var c = Color.Yellow; 60 | using var font = new Font("Arial", 22); 61 | 62 | // inference session 63 | Console.WriteLine("Starting inference session..."); 64 | var tic = Environment.TickCount; 65 | var inputMeta = session.InputMetadata; 66 | var name = inputMeta.Keys.ToArray()[0]; 67 | var labels = File.ReadAllLines(prototxt); 68 | Console.WriteLine("Session started in " + (Environment.TickCount - tic) + " mls."); 69 | 70 | // image 71 | Console.WriteLine("Creating image tensor..."); 72 | tic = Environment.TickCount; 73 | var image = (Bitmap)BackgroundImage; 74 | var width = image.Width; 75 | var height = image.Height; 76 | var dimentions = new int[] { 1, height, width, 3 }; 77 | var inputData = Onnx.ToTensor(image); 78 | Console.WriteLine("Tensor was created in " + (Environment.TickCount - tic) + " mls."); 79 | 80 | // prediction 81 | Console.WriteLine("Detecting objects..."); 82 | tic = Environment.TickCount; 83 | var t1 = new DenseTensor(inputData, dimentions); 84 | var inputs = new List() { NamedOnnxValue.CreateFromTensor(name, t1) }; 85 | var results = session.Run(inputs).ToArray(); 86 | 87 | // dump the results 88 | foreach (var r in results) 89 | { 90 | Console.WriteLine(r.Name + "\n"); 91 | Console.WriteLine(r.AsTensor().GetArrayString()); 92 | } 93 | Console.WriteLine("Detecting was finished in " + (Environment.TickCount - tic) + " mls."); 94 | 95 | // drawing results 96 | Console.WriteLine("Drawing inference results..."); 97 | tic = Environment.TickCount; 98 | var detection_boxes = results[0].AsTensor(); 99 | var detection_classes = results[1].AsTensor(); 100 | var detection_scores = results[2].AsTensor(); 101 | var num_detections = results[3].AsTensor()[0]; 102 | 103 | using (var g = Graphics.FromImage(image)) 104 | { 105 | for (int i = 0; i < num_detections; i++) 106 | { 107 | var score = detection_scores[0, i]; 108 | 109 | if (score > threshold) 110 | { 111 | var label = labels[(int)detection_classes[0, i] - 1]; 112 | 113 | var x = (int)(detection_boxes[0, i, 0] * height); 114 | var y = (int)(detection_boxes[0, i, 1] * width); 115 | var w = (int)(detection_boxes[0, i, 2] * height); 116 | var h = (int)(detection_boxes[0, i, 3] * width); 117 | 118 | // python rectangle 119 | var rectangle = Rectangle.FromLTRB(y, x, h, w); 120 | using var brush = new SolidBrush(c); 121 | using var pen = new Pen(c) { Width = 3 }; 122 | g.DrawString(label, font, brush, y, x); 123 | g.DrawRectangle(pen, rectangle); 124 | } 125 | } 126 | } 127 | 128 | BackgroundImage = image; 129 | Console.WriteLine("Drawing was finished in " + (Environment.TickCount - tic) + " mls."); 130 | } 131 | 132 | #endregion 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /csharp/Form1.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /csharp/Onnx.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using System.Drawing.Imaging; 3 | 4 | namespace object_detection 5 | { 6 | public static class Onnx 7 | { 8 | #region Tensor 9 | /// 10 | /// Converts a Bitmap to an RGB tensor array. 11 | /// 12 | /// Bitmap 13 | /// RGB tensor array 14 | public static byte[] ToTensor(this Bitmap Data) 15 | { 16 | BitmapData bmData = Onnx.Lock24bpp(Data); 17 | byte[] rgb = Onnx.ToTensor(bmData); 18 | Onnx.Unlock(Data, bmData); 19 | return rgb; 20 | } 21 | /// 22 | /// Converts a Bitmap to an RGB tensor array. 23 | /// 24 | /// Bitmap data 25 | /// RGB tensor array 26 | public unsafe static byte[] ToTensor(this BitmapData bmData) 27 | { 28 | // params 29 | int width = bmData.Width, height = bmData.Height, stride = bmData.Stride; 30 | byte* p = (byte*)bmData.Scan0.ToPointer(); 31 | byte[] t = new byte[3 * height * width]; 32 | int pos = 0; 33 | 34 | // do job 35 | for (int j = 0; j < height; j++) 36 | { 37 | int k, jstride = j * stride; 38 | 39 | for (int i = 0; i < width; i++) 40 | { 41 | k = jstride + i * 3; 42 | 43 | t[pos++] = p[k + 2]; 44 | t[pos++] = p[k + 1]; 45 | t[pos++] = p[k + 0]; 46 | } 47 | } 48 | 49 | return t; 50 | } 51 | /// 52 | /// Converts an RGB tensor array to a color image. 53 | /// 54 | /// RGB tensor array 55 | /// Bitmap width 56 | /// Bitmap height 57 | /// Bitmap 58 | public unsafe static Bitmap FromTensor(this byte[] tensor, int width, int height) 59 | { 60 | Bitmap bitmap = new Bitmap(width, height); 61 | FromTensor(tensor, width, height, bitmap); 62 | return bitmap; 63 | } 64 | /// 65 | /// Converts an RGB tensor array to a color image. 66 | /// 67 | /// RGBA tensor array 68 | /// Bitmap width 69 | /// Bitmap height 70 | /// Bitmap data 71 | public unsafe static void FromTensor(this byte[] tensor, int width, int height, BitmapData bmData) 72 | { 73 | // params 74 | int stride = bmData.Stride; 75 | byte* p = (byte*)bmData.Scan0.ToPointer(); 76 | int pos = 0; 77 | 78 | // do job 79 | for (int j = 0; j < height; j++) 80 | { 81 | int k, jstride = j * stride; 82 | 83 | for (int i = 0; i < width; i++) 84 | { 85 | k = jstride + i * 3; 86 | 87 | // rgb 88 | p[k + 2] = tensor[pos++]; 89 | p[k + 1] = tensor[pos++]; 90 | p[k + 0] = tensor[pos++]; 91 | } 92 | } 93 | 94 | return; 95 | } 96 | /// 97 | /// Converts an RGB tensor array to a color image. 98 | /// 99 | /// RGBA tensor array 100 | /// Bitmap width 101 | /// Bitmap height 102 | /// Bitmap 103 | public static void FromTensor(this byte[] tensor, int width, int height, Bitmap Data) 104 | { 105 | BitmapData bmData = Onnx.Lock24bpp(Data); 106 | FromTensor(tensor, width, height, bmData); 107 | Onnx.Unlock(Data, bmData); 108 | return; 109 | } 110 | #endregion 111 | 112 | #region BitmapData voids 113 | /// 114 | /// Blocks Bitmap in system memory. 115 | /// 116 | /// Bitmap 117 | /// Bitmap data 118 | public static BitmapData Lock24bpp(this Bitmap b) 119 | { 120 | return b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 121 | } 122 | /// 123 | /// Unblocks Bitmap in system memory. 124 | /// 125 | /// Bitmap 126 | /// Bitmap data 127 | public static void Unlock(this Bitmap b, BitmapData bmData) 128 | { 129 | b.UnlockBits(bmData); 130 | return; 131 | } 132 | #endregion 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /csharp/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace object_detection 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Form1()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /csharp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("object_detection")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("object_detection")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1934e6a4-d235-4007-a918-96a0e72bdcaf")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /csharp/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace object_detection.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("object_detection.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /csharp/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /csharp/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace object_detection.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /csharp/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /csharp/object_detection.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Debug 7 | AnyCPU 8 | {1934E6A4-D235-4007-A918-96A0E72BDCAF} 9 | Exe 10 | object_detection 11 | object_detection 12 | v4.7.2 13 | 10.0 14 | 512 15 | true 16 | true 17 | 18 | 19 | 20 | 21 | x86 22 | true 23 | full 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | prompt 28 | 4 29 | true 30 | 31 | 32 | AnyCPU 33 | pdbonly 34 | true 35 | bin\Release\ 36 | TRACE 37 | prompt 38 | 4 39 | 40 | 41 | 42 | 43 | 44 | 45 | packages\Microsoft.ML.OnnxRuntime.Managed.1.5.2\lib\netstandard1.1\Microsoft.ML.OnnxRuntime.dll 46 | 47 | 48 | packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll 49 | True 50 | True 51 | 52 | 53 | 54 | packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll 55 | True 56 | True 57 | 58 | 59 | packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll 60 | 61 | 62 | 63 | packages\System.Console.4.3.0\lib\net46\System.Console.dll 64 | True 65 | True 66 | 67 | 68 | 69 | packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll 70 | 71 | 72 | packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll 73 | True 74 | True 75 | 76 | 77 | packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll 78 | True 79 | True 80 | 81 | 82 | packages\System.IO.4.3.0\lib\net462\System.IO.dll 83 | True 84 | True 85 | 86 | 87 | packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll 88 | True 89 | True 90 | 91 | 92 | 93 | packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll 94 | True 95 | True 96 | 97 | 98 | packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll 99 | True 100 | True 101 | 102 | 103 | packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll 104 | True 105 | True 106 | 107 | 108 | packages\System.Linq.4.3.0\lib\net463\System.Linq.dll 109 | True 110 | True 111 | 112 | 113 | packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll 114 | True 115 | True 116 | 117 | 118 | packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll 119 | 120 | 121 | packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll 122 | True 123 | True 124 | 125 | 126 | packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll 127 | True 128 | True 129 | 130 | 131 | 132 | packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll 133 | 134 | 135 | packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll 136 | True 137 | True 138 | 139 | 140 | packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll 141 | True 142 | True 143 | 144 | 145 | packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll 146 | 147 | 148 | packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll 149 | True 150 | True 151 | 152 | 153 | packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll 154 | True 155 | True 156 | 157 | 158 | packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll 159 | True 160 | True 161 | 162 | 163 | packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll 164 | True 165 | True 166 | 167 | 168 | packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll 169 | True 170 | True 171 | 172 | 173 | packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll 174 | True 175 | True 176 | 177 | 178 | packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll 179 | True 180 | True 181 | 182 | 183 | packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll 184 | True 185 | True 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll 197 | True 198 | True 199 | 200 | 201 | 202 | 203 | Form 204 | 205 | 206 | Form1.cs 207 | 208 | 209 | 210 | 211 | 212 | Form1.cs 213 | 214 | 215 | ResXFileCodeGenerator 216 | Resources.Designer.cs 217 | Designer 218 | 219 | 220 | True 221 | Resources.resx 222 | 223 | 224 | 225 | SettingsSingleFileGenerator 226 | Settings.Designer.cs 227 | 228 | 229 | True 230 | Settings.settings 231 | True 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 242 | 243 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /csharp/object_detection.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30413.136 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "object_detection", "object_detection.csproj", "{1934E6A4-D235-4007-A918-96A0E72BDCAF}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1934E6A4-D235-4007-A918-96A0E72BDCAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1934E6A4-D235-4007-A918-96A0E72BDCAF}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1934E6A4-D235-4007-A918-96A0E72BDCAF}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1934E6A4-D235-4007-A918-96A0E72BDCAF}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {F20FE739-D4D4-4D7F-968F-53E66DF508F8} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /csharp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/csharp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asiryan/object-detection-tf/84ca341fe6e9094246b8792e796b5241a566cd1c/docs/csharp.jpg -------------------------------------------------------------------------------- /docs/python.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asiryan/object-detection-tf/84ca341fe6e9094246b8792e796b5241a566cd1c/docs/python.jpg -------------------------------------------------------------------------------- /images/airport.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asiryan/object-detection-tf/84ca341fe6e9094246b8792e796b5241a566cd1c/images/airport.jpg -------------------------------------------------------------------------------- /images/persons.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asiryan/object-detection-tf/84ca341fe6e9094246b8792e796b5241a566cd1c/images/persons.jpg -------------------------------------------------------------------------------- /images/school.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asiryan/object-detection-tf/84ca341fe6e9094246b8792e796b5241a566cd1c/images/school.jpg -------------------------------------------------------------------------------- /object_detection_image_onnx.py: -------------------------------------------------------------------------------- 1 | import onnxruntime as rt 2 | import numpy as np 3 | from PIL import Image, ImageDraw, ImageColor, ImageFont 4 | import math 5 | import matplotlib.pyplot as plt 6 | import os 7 | 8 | # params 9 | MODEL = "ssd_mobilenet_v1_coco_2018_01_28/model.onnx" 10 | PROTOTXT = 'coco.prototxt' 11 | IMAGE = 'images/school.jpg' 12 | 13 | # force tf2onnx to cpu 14 | os.environ['CUDA_VISIBLE_DEVICES'] = "-1" 15 | 16 | # inference session 17 | img = Image.open(IMAGE) 18 | img_data = np.array(img.getdata()).reshape(img.size[1], img.size[0], 3) 19 | img_data = np.expand_dims(img_data.astype(np.uint8), axis=0) 20 | sess = rt.InferenceSession(MODEL) 21 | outputs = ["detection_boxes:0", "detection_classes:0", "detection_scores:0", "num_detections:0"] 22 | result = sess.run(outputs, {"image_tensor:0": img_data}) 23 | detection_boxes, detection_classes, detection_scores, num_detections = result 24 | 25 | # draw results 26 | def draw_detection(draw, d, c): 27 | width, height = draw.im.size 28 | # the box is relative to the image size so we multiply with height and width to get pixels. 29 | top = d[0] * height 30 | left = d[1] * width 31 | bottom = d[2] * height 32 | right = d[3] * width 33 | top = max(0, np.floor(top + 0.5).astype('int32')) 34 | left = max(0, np.floor(left + 0.5).astype('int32')) 35 | bottom = min(height, np.floor(bottom + 0.5).astype('int32')) 36 | right = min(width, np.floor(right + 0.5).astype('int32')) 37 | label = coco_classes[c.astype('int32') - 1] # shift to zero element 38 | label_size = draw.textsize(label) 39 | text_origin = tuple(np.array([left + 1, top + 1])) 40 | color = ImageColor.getrgb("yellow") 41 | thickness = 0 42 | draw.rectangle([left + thickness, top + thickness, right - thickness, bottom - thickness], outline=color) 43 | draw.text(text_origin, label, fill=color, font=font) 44 | 45 | coco_classes = [] 46 | 47 | with open(PROTOTXT) as lines: 48 | for line in lines: 49 | coco_classes.append(line.strip()) 50 | 51 | font = ImageFont.truetype("C:\\Windows\\Fonts\\Arial.ttf", 22) 52 | 53 | batch_size = num_detections.shape[0] 54 | draw = ImageDraw.Draw(img) 55 | for batch in range(0, batch_size): 56 | for detection in range(0, int(num_detections[batch])): 57 | c = detection_classes[batch][detection] 58 | d = detection_boxes[batch][detection] 59 | draw_detection(draw, d, c) 60 | 61 | #print(detection_scores) 62 | plt.figure(figsize=(8, 8)) 63 | plt.axis('off') 64 | plt.imshow(img) 65 | plt.show() 66 | -------------------------------------------------------------------------------- /ssd_mobilenet_v1_coco_2018_01_28/frozen.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asiryan/object-detection-tf/84ca341fe6e9094246b8792e796b5241a566cd1c/ssd_mobilenet_v1_coco_2018_01_28/frozen.onnx -------------------------------------------------------------------------------- /ssd_mobilenet_v1_coco_2018_01_28/model.onnx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/asiryan/object-detection-tf/84ca341fe6e9094246b8792e796b5241a566cd1c/ssd_mobilenet_v1_coco_2018_01_28/model.onnx --------------------------------------------------------------------------------