Skip to content
This repository was archived by the owner on Aug 11, 2025. It is now read-only.

Commit c747383

Browse files
Dorokhovmigueldeicaza
authored andcommitted
Object Detection Example ReadMe (#148)
* Added shell scripts to run the object detection example on Windows and Mac OS simply. Scripts download trained model, .pbtxt file and run example against the image under the test_images folder. * Added README file with a description of the example
1 parent 3db1df1 commit c747383

File tree

9 files changed

+132
-50
lines changed

9 files changed

+132
-50
lines changed

Examples/ExampleCommon/CatalogUtil.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
24
using System.IO;
35
using System.Text.RegularExpressions;
46

57
namespace ExampleCommon
68
{
79
public static class CatalogUtil
810
{
9-
private static string CATALOG_ITEM_PATTERN = @"item {\r\n name: ""(?<name>.*)""\r\n id: (?<id>\d+)\r\n display_name: ""(?<displayName>.*)""\r\n}";
11+
// regexes with different new line symbols
12+
private static string CATALOG_ITEM_PATTERN = @"item {{{0} name: ""(?<name>.*)""{0} id: (?<id>\d+){0} display_name: ""(?<displayName>.*)""{0}}}";
13+
private static string CATALOG_ITEM_PATTERN_ENV = string.Format(CultureInfo.InvariantCulture, CATALOG_ITEM_PATTERN, Environment.NewLine);
14+
private static string CATALOG_ITEM_PATTERN_UNIX = string.Format (CultureInfo.InvariantCulture, CATALOG_ITEM_PATTERN, "\n");
1015

1116
/// <summary>
1217
/// Reads catalog of well-known objects from text file.
@@ -22,8 +27,13 @@ public static IEnumerable<CatalogItem> ReadCatalogItems (string file)
2227
yield break;
2328
}
2429

25-
Regex regex = new Regex (CATALOG_ITEM_PATTERN);
30+
Regex regex = new Regex (CATALOG_ITEM_PATTERN_ENV);
2631
var matches = regex.Matches (text);
32+
if(matches.Count == 0) {
33+
regex = new Regex (CATALOG_ITEM_PATTERN_UNIX);
34+
matches = regex.Matches (text);
35+
}
36+
2737
foreach (Match match in matches) {
2838
var name = match.Groups [1].Value;
2939
var id = int.Parse (match.Groups [2].Value);

Examples/ExampleObjectDetection/ExampleObjectDetection.csproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,17 @@
3333
<WarningLevel>4</WarningLevel>
3434
</PropertyGroup>
3535
<ItemGroup>
36+
<Reference Include="ICSharpCode.SharpZipLib, Version=0.86.0.518, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
37+
<HintPath>..\..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll</HintPath>
38+
</Reference>
3639
<Reference Include="Mono.Options, Version=5.0.0.0, Culture=neutral, processorArchitecture=MSIL">
3740
<HintPath>..\..\packages\Mono.Options.5.3.0.1\lib\net4-client\Mono.Options.dll</HintPath>
3841
</Reference>
3942
<Reference Include="System" />
4043
<Reference Include="System.Core" />
4144
<Reference Include="System.Drawing" />
45+
<Reference Include="System.IO.Compression" />
46+
<Reference Include="System.IO.Compression.FileSystem" />
4247
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
4348
<HintPath>..\..\packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll</HintPath>
4449
</Reference>
@@ -68,5 +73,10 @@
6873
<Name>ExampleCommon</Name>
6974
</ProjectReference>
7075
</ItemGroup>
76+
<ItemGroup>
77+
<Content Include="test_images\input.jpg">
78+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
79+
</Content>
80+
</ItemGroup>
7181
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
7282
</Project>

Examples/ExampleObjectDetection/ImageEditor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ public void AddBox (float xmin, float xmax, float ymin, float ymax, string text
5757
Pen pen = new Pen (brush);
5858

5959
_graphics.DrawRectangle (pen, left, top, right - left, bottom - top);
60-
_graphics.DrawString (text, new Font (_fontFamily, _fontSize), brush, new PointF (left, top));
60+
var font = new Font (_fontFamily, _fontSize);
61+
SizeF size = _graphics.MeasureString (text, font);
62+
_graphics.DrawString (text, font, brush, new PointF (left, top - size.Height));
6163
}
6264

6365
public void Dispose ()

Examples/ExampleObjectDetection/Program.cs

Lines changed: 70 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,21 @@
55
using TensorFlow;
66
using ExampleCommon;
77
using Mono.Options;
8+
using System.IO.Compression;
9+
using System.Reflection;
10+
using System.Net;
11+
using ICSharpCode.SharpZipLib.Zip;
12+
using ICSharpCode.SharpZipLib.Tar;
13+
using ICSharpCode.SharpZipLib.GZip;
814

915
namespace ExampleObjectDetection
1016
{
1117
class Program
1218
{
1319
private static IEnumerable<CatalogItem> _catalog;
14-
private static string _input;
15-
private static string _output;
20+
private static string _currentDir = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
21+
private static string _input = Path.Combine (_currentDir, "test_images/input.jpg");
22+
private static string _output = Path.Combine (_currentDir, "test_images/output.jpg");
1623
private static string _catalogPath;
1724
private static string _modelPath;
1825

@@ -28,20 +35,12 @@ class Program
2835
};
2936

3037
/// <summary>
31-
/// The utility processes the image and produces output image highlighting detected objects on it.
32-
/// You need to proceed following steps to get the example working:
33-
/// 1. Download and unzip one of trained models from
34-
/// https://github.com/tensorflow/models/blob/master/object_detection/g3doc/detection_model_zoo.md
35-
///
36-
/// for instance 'faster_rcnn_inception_resnet_v2_atrous_coco'
37-
/// 2. Download mscoco_label_map.pbtxt from
38-
/// https://github.com/tensorflow/models/blob/master/object_detection/data/mscoco_label_map.pbtxt
39-
///
40-
/// 3. Run the ExampleObjectDetection util from command line specifying input_image, output_image, catalog and model options
41-
/// where input_image - the path to the image for processing
42-
/// output_image - the path where the image with detected objects will be saved
43-
/// catalog - the path to the 'mscoco_label_map.pbtxt' file (see 2)
44-
/// model - the path to the 'frozen_inference_graph.pb' file (see 1)
38+
/// Run the ExampleObjectDetection util from command line. Following options are available:
39+
/// input_image - optional, the path to the image for processing (the default is 'test_images/input.jpg')
40+
/// output_image - optional, the path where the image with detected objects will be saved (the default is 'test_images/output.jpg')
41+
/// catalog - optional, the path to the '*.pbtxt' file (by default, 'mscoco_label_map.pbtxt' been loaded)
42+
/// model - optional, the path to the '*.pb' file (by default, 'frozen_inference_graph.pb' model been used, but you can download any other from here
43+
/// https://github.com/tensorflow/models/blob/master/object_detection/g3doc/detection_model_zoo.md or train your own)
4544
///
4645
/// for instance,
4746
/// ExampleObjectDetection --input_image="/demo/input.jpg" --output_image="/demo/output.jpg" --catalog="/demo/mscoco_label_map.pbtxt" --model="/demo/frozen_inference_graph.pb"
@@ -51,20 +50,12 @@ static void Main (string [] args)
5150
{
5251
options.Parse (args);
5352

54-
if(_input == null) {
55-
throw new ArgumentException ("Missing required option --input_image=");
56-
}
57-
58-
if (_output == null) {
59-
throw new ArgumentException ("Missing required option --output_image=");
60-
}
61-
6253
if (_catalogPath == null) {
63-
throw new ArgumentException ("Missing required option --catalog=");
54+
_catalogPath = DownloadDefaultTexts (_currentDir);
6455
}
6556

6657
if (_modelPath == null) {
67-
throw new ArgumentException ("Missing required option --model=");
58+
_modelPath = DownloadDefaultModel (_currentDir);
6859
}
6960

7061
_catalog = CatalogUtil.ReadCatalogItems (_catalogPath);
@@ -100,7 +91,47 @@ static void Main (string [] args)
10091
}
10192
}
10293
}
103-
94+
95+
private static string DownloadDefaultModel (string dir)
96+
{
97+
const string defaultModelUrl = "http://download.tensorflow.org/models/object_detection/faster_rcnn_inception_resnet_v2_atrous_coco_11_06_2017.tar.gz";
98+
99+
var modelFile = Path.Combine (dir, "faster_rcnn_inception_resnet_v2_atrous_coco_11_06_2017/frozen_inference_graph.pb");
100+
var zipfile = Path.Combine (dir, "faster_rcnn_inception_resnet_v2_atrous_coco_11_06_2017.tar.gz");
101+
102+
if (File.Exists (modelFile))
103+
return modelFile;
104+
105+
if (!File.Exists (zipfile)) {
106+
var wc = new WebClient ();
107+
wc.DownloadFile (defaultModelUrl, zipfile);
108+
}
109+
110+
ExtractToDirectory (zipfile, dir);
111+
File.Delete (zipfile);
112+
113+
return modelFile;
114+
}
115+
116+
private static void ExtractToDirectory (string file, string targetDir)
117+
{
118+
using (Stream inStream = File.OpenRead (file))
119+
using (Stream gzipStream = new GZipInputStream (inStream)) {
120+
TarArchive tarArchive = TarArchive.CreateInputTarArchive (gzipStream);
121+
tarArchive.ExtractContents (targetDir);
122+
}
123+
}
124+
125+
private static string DownloadDefaultTexts (string dir)
126+
{
127+
const string defaultTextsUrl = "https://raw.githubusercontent.com/tensorflow/models/master/object_detection/data/mscoco_label_map.pbtxt";
128+
var textsFile = Path.Combine (dir, "mscoco_label_map.pbtxt");
129+
var wc = new WebClient ();
130+
wc.DownloadFile (defaultTextsUrl, textsFile);
131+
132+
return textsFile;
133+
}
134+
104135
private static void DrawBoxes (float [,,] boxes, float [,] scores, float [,] classes, string inputFile, string outputFile, double minScore)
105136
{
106137
var x = boxes.GetLength (0);
@@ -117,18 +148,18 @@ private static void DrawBoxes (float [,,] boxes, float [,] scores, float [,] cla
117148
for (int k = 0; k < z; k++) {
118149
var box = boxes [i, j, k];
119150
switch (k) {
120-
case 0:
121-
ymin = box;
122-
break;
123-
case 1:
124-
xmin = box;
125-
break;
126-
case 2:
127-
ymax = box;
128-
break;
129-
case 3:
130-
xmax = box;
131-
break;
151+
case 0:
152+
ymin = box;
153+
break;
154+
case 1:
155+
xmin = box;
156+
break;
157+
case 2:
158+
ymax = box;
159+
break;
160+
case 3:
161+
xmax = box;
162+
break;
132163
}
133164

134165
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Object Detection Example #
2+
3+
This example uses tensorflow [object detection model API](https://github.com/tensorflow/models/tree/master/object_detection) and TensorFlowSharp library to identify multiple objects in a single image using .NET programming languages like C# and F#.
4+
5+
![alt tag](demo-picture.jpg)
6+
7+
## Run example ##
8+
1. ``` git clone https://github.com/migueldeicaza/TensorFlowSharp ```
9+
2. build _TensorFlowSharp.sln_
10+
3. copy _'libtensorflow.dylib'_ (Mac OS) or _'libtensorflow.dll'_ (Windows) to the project output path (see where you can get the library under [Working on TensorFlowSharp](https://github.com/migueldeicaza/TensorFlowSharp#working-on-tensorflowsharp) section)
11+
4. Run the ExampleObjectDetection util from command line:
12+
```
13+
ExampleObjectDetection
14+
```
15+
16+
By default, the example downloads a pretrained model, but you can specify your own using the following options:
17+
18+
_input_image_ - optional, the path to the image for processing (the default is 'test_images/input.jpg')
19+
_output_image_ - optional, the path where the image with detected objects will be saved (the default is 'test_images/output.jpg')
20+
_catalog_ - optional, the path to the '*.pbtxt' file (by default, 'mscoco_label_map.pbtxt' been loaded)
21+
_model_ - optional, the path to the '*.pb' file (by default, 'frozen_inference_graph.pb' model been used, but you can download any other from here https://github.com/tensorflow/models/blob/master/object_detection/g3doc/detection_model_zoo.md or train your own):
22+
```
23+
ExampleObjectDetection --input_image="/demo/input.jpg" --output_image="/demo/output.jpg" --catalog="/demo/mscoco_label_map.pbtxt" --model="/demo/frozen_inference_graph.pb"
24+
```
25+
26+
## I found an issue in the example ##
27+
If you want to address a bug or a question related to the object detection example - just create a new issue on github starting with [Object Detection Example] tag.
142 KB
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
33
<package id="Mono.Options" version="5.3.0.1" targetFramework="net461" />
4+
<package id="SharpZipLib" version="0.86.0" targetFramework="net461" />
45
<package id="System.ValueTuple" version="4.4.0" targetFramework="net461" />
56
</packages>
1.35 MB
Loading
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
33
<package id="Microsoft.DotNet.InternalAbstractions" version="1.0.500-preview2-1-003177" targetFramework="net461" />
4+
<package id="Microsoft.TestPlatform.TestHost" version="15.3.0" targetFramework="net461" />
45
<package id="System.ValueTuple" version="4.3.1" targetFramework="net461" />
5-
<package id="xunit" version="2.2.0" targetFramework="net452" />
6-
<package id="xunit.abstractions" version="2.0.1" targetFramework="net452" />
7-
<package id="xunit.assert" version="2.2.0" targetFramework="net452" />
8-
<package id="xunit.core" version="2.2.0" targetFramework="net452" />
9-
<package id="xunit.extensibility.core" version="2.2.0" targetFramework="net452" />
10-
<package id="xunit.extensibility.execution" version="2.2.0" targetFramework="net452" />
11-
<package id="xunit.runner.console" version="2.2.0" targetFramework="net452" developmentDependency="true" />
6+
<package id="xunit" version="2.2.0" targetFramework="net461" />
7+
<package id="xunit.abstractions" version="2.0.1" targetFramework="net461" />
8+
<package id="xunit.assert" version="2.2.0" targetFramework="net461" />
9+
<package id="xunit.core" version="2.2.0" targetFramework="net461" />
10+
<package id="xunit.extensibility.core" version="2.2.0" targetFramework="net461" />
11+
<package id="xunit.extensibility.execution" version="2.2.0" targetFramework="net461" />
12+
<package id="xunit.runner.console" version="2.2.0" targetFramework="net461" developmentDependency="true" />
1213
<package id="xunit.runner.visualstudio" version="2.3.0-beta3-build3705" targetFramework="net461" developmentDependency="true" />
1314
</packages>

0 commit comments

Comments
 (0)