Skip to content

Commit 1020a0f

Browse files
authored
Merge pull request #429 from microsoft/user/sheilk/opencv-test
Add OpenCV Interop sample to the gallery
2 parents 8515b46 + c9a39a8 commit 1020a0f

28 files changed

+1324
-86
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
*.userprefs
1414

1515
# Build results
16+
[Bb]uild/
1617
[Dd]ebug/
1718
[Dd]ebugPublic/
1819
[Rr]elease/
1920
[Rr]eleases/
2021
x64/
2122
x86/
23+
[Ii]nt/
2224
bld/
2325
[Bb]in/
2426
[Oo]bj/

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@
44
[submodule "Samples/RustSqueezenet/winrt-rs"]
55
path = Samples/RustSqueezenet/winrt-rs
66
url = https://github.com/microsoft/winrt-rs.git
7+
[submodule "external/opencv"]
8+
path = external/opencv
9+
url = https://github.com/opencv/opencv.git

README.md

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,24 @@ A subdomain of computer vision in which an algorithm looks at an image and assig
5454

5555
| Windows App Type <br/>Distribution | UWP<br/>In-Box | UWP<br/>NuGet | Desktop<br/>In-Box | Desktop<br/>NuGet |
5656
|------------|------------------------------------|--------------------------------------|------------------------------------|--------------------------------------|
57-
| [AlexNet](https://github.com/onnx/models/tree/master/vision/classification/alexnet) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
58-
| [CaffeNet](https://github.com/onnx/models/tree/master/vision/classification/caffenet) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
59-
| [DenseNet](https://github.com/onnx/models/tree/master/vision/classification/densenet-121) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
60-
| [EfficientNet](https://github.com/onnx/models/tree/master/vision/classification/efficientnet-lite4) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
57+
| [AlexNet](https://github.com/onnx/models/tree/master/vision/classification/alexnet) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
58+
| [CaffeNet](https://github.com/onnx/models/tree/master/vision/classification/caffenet) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
59+
| [DenseNet](https://github.com/onnx/models/tree/master/vision/classification/densenet-121) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
60+
| [EfficientNet](https://github.com/onnx/models/tree/master/vision/classification/efficientnet-lite4) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
6161
| [Emoji8](https://blogs.windows.com/windowsdeveloper/2018/11/16/introducing-emoji8/) | [✔️C#](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/Emoji8/UWP/cs) | |
62-
| [GoogleNet](https://github.com/onnx/models/tree/master/vision/classification/inception_and_googlenet/googlenet) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
63-
| [InceptionV1](https://github.com/onnx/models/tree/master/vision/classification/inception_and_googlenet/inception_v1) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
64-
| [InceptionV2](https://github.com/onnx/models/tree/master/vision/classification/inception_and_googlenet/inception_v2) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
62+
| [GoogleNet](https://github.com/onnx/models/tree/master/vision/classification/inception_and_googlenet/googlenet) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
63+
| [InceptionV1](https://github.com/onnx/models/tree/master/vision/classification/inception_and_googlenet/inception_v1) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
64+
| [InceptionV2](https://github.com/onnx/models/tree/master/vision/classification/inception_and_googlenet/inception_v2) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
6565
| [MNIST](https://github.com/onnx/models/tree/master/vision/classification/mnist) | [✔️C++/CX](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/MNIST/UWP)<br/>[✔️C#](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/MNIST/Tutorial/cs)<br/> | |
66-
| [MobileNetV2](https://github.com/onnx/models/tree/master/vision/classification/mobilenet) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
67-
| [RCNN](https://github.com/onnx/models/tree/master/vision/classification/rcnn_ilsvrc13) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
68-
| [ResNet50](https://github.com/onnx/models/tree/master/vision/classification/resnet) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
69-
| [ShuffleNetV1](https://github.com/onnx/models/tree/master/vision/classification/shufflenet) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
70-
| [ShuffleNetV2](https://github.com/onnx/models/tree/master/vision/classification/shufflenet) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
71-
| [SqueezeNet](https://github.com/onnx/models/tree/master/vision/classification/squeezenet) | [✔️C#](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/UWP/cs)<br/>[✔️JavaScript](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/UWP/cs)<br/> | |[✔️C++/WinRT](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/Desktop/cpp)<br/> [✔️C# .NET5](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/NET5)<br/>[✔️C# .NET Core 2](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/NETCore/cs)<br/>|[✔️C++/WinRT](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/Desktop/cpp)<br/>[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>[✔️Rust](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/RustSqueezenet)<br/>|
72-
| [VGG19](https://github.com/onnx/models/tree/master/vision/classification/vgg) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
73-
| [VGG19bn](https://github.com/onnx/models/tree/master/vision/classification/vgg) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
74-
| [ZFNet512](https://github.com/onnx/models/tree/master/vision/classification/zfnet-512) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
66+
| [MobileNetV2](https://github.com/onnx/models/tree/master/vision/classification/mobilenet) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
67+
| [RCNN](https://github.com/onnx/models/tree/master/vision/classification/rcnn_ilsvrc13) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
68+
| [ResNet50](https://github.com/onnx/models/tree/master/vision/classification/resnet) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
69+
| [ShuffleNetV1](https://github.com/onnx/models/tree/master/vision/classification/shufflenet) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
70+
| [ShuffleNetV2](https://github.com/onnx/models/tree/master/vision/classification/shufflenet) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
71+
| [SqueezeNet](https://github.com/onnx/models/tree/master/vision/classification/squeezenet) | [✔️C#](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/UWP/cs)<br/>[✔️JavaScript](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/UWP/cs)<br/> | |[✔️C++/WinRT](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/Desktop/cpp)<br/> [✔️C# .NET5](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/NET5)<br/>[✔️C# .NET Core 2](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/NETCore/cs)<br/>|[✔️C++/WinRT](https://github.com/Microsoft/Windows-Machine-Learning/tree/master/Samples/SqueezeNetObjectDetection/Desktop/cpp)<br/>[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>[✔️Rust](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/RustSqueezenet)<br/>|
72+
| [VGG19](https://github.com/onnx/models/tree/master/vision/classification/vgg) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
73+
| [VGG19bn](https://github.com/onnx/models/tree/master/vision/classification/vgg) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
74+
| [ZFNet512](https://github.com/onnx/models/tree/master/vision/classification/zfnet-512) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
7575

7676
**Style Transfer**
7777

@@ -87,7 +87,7 @@ A computer vision technique that allows us to recompose the content of an image
8787
8888
| | Store App<br/>Inbox API | Store App<br/>NuGet API | Desktop App<br/>Inbox API | Desktop App<br/>NuGet API |
8989
|------------|------------------------------------|--------------------------------------|------------------------------------|--------------------------------------|
90-
| [YoloV4](https://github.com/onnx/models/raw/master/vision/object_detection_segmentation/yolov4/model/yolov4.onnx) | | ||[✔️C# .NET5 - Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery)<br/>|
90+
| [YoloV4](https://github.com/onnx/models/raw/master/vision/object_detection_segmentation/yolov4/model/yolov4.onnx) | | ||[✔️C# .NET5 - Samples Gallery](Samples/WinMLSamplesGallery)<br/>|
9191
9292
-->
9393

@@ -104,6 +104,7 @@ These advanced samples show how to use various binding and evaluation features i
104104
- **[PyTorch Data Analysis](https://github.com/Microsoft/Windows-AppConsult-Samples-UWP/tree/master/PlaneIdentifier)**: The tutorial shows how to solve a classification task with a neural network using the PyTorch library, export the model to ONNX format and deploy the model with the Windows Machine Learning application that can run on any Windows device.
105105
- **[PyTorch Image Classification](https://github.com/Microsoft/Windows-AppConsult-Samples-UWP/tree/master/PlaneIdentifier)**: The tutorial shows how to train an image classification neural network model using PyTorch, export the model to the ONNX format, and deploy it in a Windows Machine Learning application running locally on your Windows device.
106106
- **[YoloV4 Object Detection](https://github.com/Microsoft/Windows-AppConsult-Samples-UWP/tree/master/PlaneIdentifier)**: This tutorial shows how to build a UWP C# app that uses the YOLOv4 model to detect objects in video streams.
107+
- **[OpenCV Interop](Samples/WinMLSamplesGallery/WinMLSamplesGallery/Samples/OpenCVInterop)**: This sample demonstrates how to interop between [Windows ML](https://docs.microsoft.com/en-us/windows/ai/windows-ml/) and [OpenCV](https://github.com/opencv/opencv).
107108

108109
## Developer Tools
109110

@@ -135,7 +136,7 @@ These advanced samples show how to use various binding and evaluation features i
135136

136137
Download for [VS 2017](https://marketplace.visualstudio.com/items?itemName=WinML.mlgen), [VS 2019](https://marketplace.visualstudio.com/items?itemName=WinML.MLGenV2)
137138

138-
- **[WinML Samples Gallery](https://github.com/microsoft/Windows-Machine-Learning/tree/master/Samples/WinMLSamplesGallery):** explore a variety of ML integration scenarios and models.
139+
- **[WinML Samples Gallery](Samples/WinMLSamplesGallery):** explore a variety of ML integration scenarios and models.
139140

140141
- Check out the [Model Samples](#model-samples) and [Advanced Scenario Samples](#advanced-scenarios) to learn how to use Windows ML in your application.
141142

Samples/WinMLSamplesGallery/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ To learn how to implement these features in your application, or unlock addition
3636

3737
- [Batched Inputs](./WinMLSamplesGallery/Samples/Batching): WinML enables batched inputs that allow callers to perform inference over multiple inputs at once in order to increase performance. Use this sample to compare inference runtime performace with and without batching.
3838

39+
- [OpenCV Interop](./WinMLSamplesGallery/Samples/OpenCVInterop): This sample demonstrates how to interop between [Windows ML](https://docs.microsoft.com/en-us/windows/ai/windows-ml/) and [OpenCV](https://github.com/opencv/opencv). The demo will run [SqueezeNet](https://github.com/onnx/models/tree/master/vision/classification/squeezenet) image classification in WindowsML and consume images loaded and preprocessed using OpenCV.
40+
3941
## Feedback
4042
Please file an issue [here](https://github.com/microsoft/Windows-Machine-Learning/issues/new) if you encounter any issues with the WinML Samples Gallery or wish to request a new sample.
4143

Samples/WinMLSamplesGallery/WinMLSamplesGallery (Package)/WinMLSamplesGallery (Package).wapproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
</ItemGroup>
129129
<ItemGroup>
130130
<None Include="$(SolutionDir)$(Platform)\$(Configuration)\WinMLSamplesGalleryNative\*.dll" Link="%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
131+
<None Include="$(SolutionDir)..\..\build\external\opencv\cmake_config\$(Platform)\bin\$(Configuration)\*.dll" Link="%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" />
131132
</ItemGroup>
132133
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
133134
<ItemGroup>

Samples/WinMLSamplesGallery/WinMLSamplesGallery/Pages/SampleBasePage.xaml.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ protected override async void OnNavigatedTo(NavigationEventArgs e)
2828
case "ImageEffects":
2929
SampleFrame.Navigate(typeof(Samples.ImageEffects));
3030
break;
31+
case "OpenCVInterop":
32+
SampleFrame.Navigate(typeof(Samples.OpenCVInterop));
33+
break;
3134
}
3235
if (sampleMetadata.Docs.Count > 0)
3336
DocsHeader.Visibility = Visibility.Visible;

Samples/WinMLSamplesGallery/WinMLSamplesGallery/SampleMetadata/SampleMetadata.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ public static async Task<List<SampleMetadata>> GetAllSampleMetadata()
3939
for (int i = 0; i < metadataJsonArray.Count; i++)
4040
{
4141
JsonObject currentSampleMetadata = metadataJsonArray[i].GetObject();
42+
43+
bool shouldHideSample = false;
44+
#if !USE_OPENCV
45+
shouldHideSample |= currentSampleMetadata["Tag"].GetString() == "OpenCVInterop";
46+
#endif
47+
48+
if (shouldHideSample)
49+
{
50+
continue;
51+
}
52+
4253
allSampleMetadata.Add(new SampleMetadata
4354
{
4455
Title = currentSampleMetadata["Title"].GetString(),

Samples/WinMLSamplesGallery/WinMLSamplesGallery/SampleMetadata/SampleMetadata.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@
3434
"link": "https://docs.microsoft.com/en-us/uwp/api/windows.ai.machinelearning.learningmodelsessionoptions.batchsizeoverride?view=winrt-20348"
3535
}
3636
]
37+
},
38+
{
39+
"Title": "OpenCV Interop",
40+
"DescriptionShort": "The sample uses Windows ML to classify images that have been denoised using OpenCV.",
41+
"Description": "This sample demonstrates interop between Windows ML and OpenCV. The sample classifes images that have been denoised using OpenCV's medianBlur using the SqueezeNet model on Windows ML. Choose an image to get started.",
42+
"Icon": "\uE155",
43+
"Tag": "OpenCVInterop",
44+
"XAMLGithubLink": "https://github.com/microsoft/Windows-Machine-Learning/blob/master/Samples/WinMLSamplesGallery/WinMLSamplesGallery/Samples/OpenCVInterop/OpenCVInterop.xaml",
45+
"CSharpGithubLink": "https://github.com/microsoft/Windows-Machine-Learning/blob/master/Samples/WinMLSamplesGallery/WinMLSamplesGallery/Samples/OpenCVInterop/OpenCVInterop.xaml.cs",
46+
"Docs": []
3747
}
3848
]
3949
}

Samples/WinMLSamplesGallery/WinMLSamplesGallery/Samples/ImageClassifier/ImageClassifier.xaml.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,11 @@ private void EnsureInitialized()
233233

234234
private void InitializeWindowsMachineLearning()
235235
{
236-
_tensorizationSession =
237-
CreateLearningModelSession(
238-
TensorizationModels.BasicTensorization(
239-
Height, Width,
240-
BatchSize, Channels, CurrentImageDecoder.PixelHeight, CurrentImageDecoder.PixelWidth,
241-
"nearest"),
242-
LearningModelDeviceKind.Cpu);
236+
_tensorizationSession = CreateLearningModelSession(TensorizationModels.BasicTensorization(
237+
Height, Width,
238+
BatchSize, Channels, CurrentImageDecoder.PixelHeight, CurrentImageDecoder.PixelWidth,
239+
"nearest"),
240+
LearningModelDeviceKind.Cpu);
243241

244242
var model = SelectedModel;
245243
if (model != CurrentModel)
@@ -287,7 +285,7 @@ private void InitializeWindowsMachineLearning()
287285
{
288286
var pixelDataProvider = decoder.GetPixelDataAsync().GetAwaiter().GetResult();
289287
var bytes = pixelDataProvider.DetachPixelData();
290-
var buffer = bytes.AsBuffer(); // Need to make this 0 copy...
288+
var buffer = bytes.AsBuffer();
291289
input = TensorUInt8Bit.CreateFromBuffer(new long[] { 1, buffer.Length }, buffer);
292290

293291
tensorizationSession = _tensorizationSession;
@@ -303,6 +301,7 @@ private void InitializeWindowsMachineLearning()
303301
var tensorizationResults = Evaluate(tensorizationSession, input);
304302
tensorizedOutput = tensorizationResults.Outputs.First().Value;
305303
}
304+
306305
stop = HighResolutionClock.UtcNow();
307306
var tensorizeDuration = HighResolutionClock.DurationInMs(start, stop);
308307

0 commit comments

Comments
 (0)