Use image metadata model for cppcx

This commit is contained in:
Young Kim 2018-08-02 18:09:23 -07:00
Родитель 9b3c5a5692
Коммит 4fb87c2c05
9 изменённых файлов: 76 добавлений и 88 удалений

Двоичные данные
Samples/MNIST/UWP/cppcx/Assets/mnist.onnx Normal file

Двоичный файл не отображается.

Двоичные данные
Samples/MNIST/UWP/cppcx/Assets/model.onnx

Двоичный файл не отображается.

Просмотреть файл

@ -73,18 +73,7 @@
Name="inkCanvas"
Height="336"
Width="336"/>
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
<Image
Name="secondImage"
Grid.Row="2"
Grid.Column="0"
Height="336"
Width="336"
Margin="0,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
</Page>

Просмотреть файл

@ -46,8 +46,8 @@ MainPage::MainPage()
fullModelName += ModelFileName;
create_task(StorageFile::GetFileFromApplicationUriAsync(ref new Uri(ref new Platform::String(fullModelName.c_str()))))
.then([](StorageFile^ file) {
return create_task(coreml_MNISTModel::CreateFromStreamAsync(file)); })
.then([this](coreml_MNISTModel ^model) {
return create_task(mnistModel::CreateFromStreamAsync(file)); })
.then([this](mnistModel ^model) {
this->m_model = model;
});
}
@ -55,21 +55,22 @@ MainPage::MainPage()
void mnist_cppcx::MainPage::recognizeButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
coreml_MNISTInput^ input = ref new coreml_MNISTInput();
mnistInput^ input = ref new mnistInput();
create_task(GetHandWrittenImage())
.then([this, input](VideoFrame^ vf) {
input->image = ImageFeatureValue::CreateFromVideoFrame(vf);
input->Input3 = ImageFeatureValue::CreateFromVideoFrame(vf);
return create_task(this->m_model->EvaluateAsync(input)); })
.then([this](coreml_MNISTOutput^ output) {
.then([this](mnistOutput^ output) {
float maxProb = 0;
int maxKey = 0;
IMapView<int64_t, float>^ map = output->prediction->GetAt(0)->GetView();
for (const auto& pair : map)
unsigned int maxKey = 0;
auto vector = output->Plus214_Output_0->GetAsVectorView();
for (unsigned int i = 0; i < vector->Size; ++i)
{
if (pair->Value > maxProb)
float value = vector->GetAt(i);
if (value > maxProb)
{
maxProb = pair->Value;
maxKey = (int64_t)pair->Key;
maxProb = value;
maxKey = i;
}
}
numberLabel->Text = maxKey.ToString();
@ -90,9 +91,8 @@ void mnist_cppcx::MainPage::clearButton_Click(Platform::Object^ sender, Windows:
.then([renderBitmap]() { return renderBitmap->GetPixelsAsync(); })
.then([this, renderBitmap](IBuffer ^ buffer) {
SoftwareBitmap ^ softwareBitMap = SoftwareBitmap::CreateCopyFromBuffer(
buffer, BitmapPixelFormat::Rgba8, renderBitmap->PixelWidth,
buffer, BitmapPixelFormat::Bgra8, renderBitmap->PixelWidth,
renderBitmap->PixelHeight, BitmapAlphaMode::Ignore);
this->secondImage->Source = renderBitmap;
VideoFrame ^ vf = VideoFrame::CreateWithSoftwareBitmap(softwareBitMap);
return create_task(CropAndDisplayInputImageAsync(vf)); })
.then([](VideoFrame^ cropped_vf) {
@ -125,7 +125,7 @@ void mnist_cppcx::MainPage::clearButton_Click(Platform::Object^ sender, Windows:
cropBounds.Width = w;
cropBounds.Height = h;
VideoFrame^ cropped_vf = ref new VideoFrame(BitmapPixelFormat::Rgba8, w, h, BitmapAlphaMode::Ignore);
VideoFrame^ cropped_vf = ref new VideoFrame(BitmapPixelFormat::Bgra8, 28, 28, BitmapAlphaMode::Ignore);
inputVideoFrame->CopyToAsync(cropped_vf, cropBounds, nullptr);
return cropped_vf;

Просмотреть файл

@ -22,8 +22,8 @@ namespace mnist_cppcx
void recognizeButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
void clearButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
static constexpr wchar_t* ModelFileName = L"model.onnx";
coreml_MNISTModel^ m_model;
static constexpr wchar_t* ModelFileName = L"mnist.onnx";
mnistModel^ m_model;
::Windows::Foundation::IAsyncOperation<::Windows::Media::VideoFrame^>^ GetHandWrittenImage();
::Windows::Foundation::IAsyncOperation<::Windows::Media::VideoFrame^>^ CropAndDisplayInputImageAsync(::Windows::Media::VideoFrame^ inputVideoFrame);
};

Просмотреть файл

@ -0,0 +1,57 @@
#include <ppltasks.h>
#include <collection.h>
namespace mnist_cppcx
{
ref class mnistInput sealed
{
public:
property ::Windows::AI::MachineLearning::ImageFeatureValue^ Input3; // BitmapPixelFormat: Gray8, BitmapAlphaMode: Premultiplied, width: 28, height: 28
};
ref class mnistOutput sealed
{
public:
property ::Windows::AI::MachineLearning::TensorFloat^ Plus214_Output_0; // shape(1,10)
};
ref class mnistModel sealed
{
private:
::Windows::AI::MachineLearning::LearningModel^ m_model;
::Windows::AI::MachineLearning::LearningModelSession^ m_session;
::Windows::AI::MachineLearning::LearningModelBinding^ m_binding;
public:
property ::Windows::AI::MachineLearning::LearningModel^ LearningModel { ::Windows::AI::MachineLearning::LearningModel^ get() { return m_model; } }
property ::Windows::AI::MachineLearning::LearningModelSession^ LearningModelSession { ::Windows::AI::MachineLearning::LearningModelSession^ get() { return m_session; } }
property ::Windows::AI::MachineLearning::LearningModelBinding^ LearningModelBinding { ::Windows::AI::MachineLearning::LearningModelBinding^ get() { return m_binding; } }
static ::Windows::Foundation::IAsyncOperation<mnistModel^>^ CreateFromStreamAsync(::Windows::Storage::Streams::IRandomAccessStreamReference^ stream, ::Windows::AI::MachineLearning::LearningModelDeviceKind deviceKind = ::Windows::AI::MachineLearning::LearningModelDeviceKind::Default)
{
return ::concurrency::create_async([stream, deviceKind] {
return ::concurrency::create_task(::Windows::AI::MachineLearning::LearningModel::LoadFromStreamAsync(stream))
.then([deviceKind](::Windows::AI::MachineLearning::LearningModel^ learningModel) {
mnistModel^ model = ref new mnistModel();
model->m_model = learningModel;
::Windows::AI::MachineLearning::LearningModelDevice^ device = ref new ::Windows::AI::MachineLearning::LearningModelDevice(deviceKind);
model->m_session = ref new ::Windows::AI::MachineLearning::LearningModelSession(model->m_model, device);
model->m_binding = ref new ::Windows::AI::MachineLearning::LearningModelBinding(model->m_session);
return model;
});
});
}
::Windows::Foundation::IAsyncOperation<mnistOutput^>^ EvaluateAsync(mnistInput^ input)
{
if (this->m_model == nullptr) throw ref new Platform::InvalidArgumentException();
return ::concurrency::create_async([this, input] {
return ::concurrency::create_task([this, input]() {
m_binding->Bind("Input3", input->Input3);
return ::concurrency::create_task(this->m_session->EvaluateAsync(m_binding, L""));
}).then([](::Windows::AI::MachineLearning::LearningModelEvaluationResult^ evalResult) {
mnistOutput^ output = ref new mnistOutput();
output->Plus214_Output_0 = static_cast<::Windows::AI::MachineLearning::TensorFloat^>(evalResult->Outputs->Lookup("Plus214_Output_0"));
return output;
});
});
}
};
}

Просмотреть файл

@ -136,7 +136,7 @@
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="model.h" />
<ClInclude Include="mnist.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="App.xaml.h">
<DependentUpon>App.xaml</DependentUpon>
@ -157,7 +157,7 @@
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<None Include="Assets\model.onnx">
<None Include="Assets\mnist.onnx">
<DeploymentContent>true</DeploymentContent>
</None>
<None Include="mnist_cppcx_TemporaryKey.pfx" />

Просмотреть файл

@ -1,58 +0,0 @@
#include <ppltasks.h>
#include <collection.h>
ref class coreml_MNISTInput sealed
{
public:
property ::Windows::AI::MachineLearning::ImageFeatureValue^ image; // shape(-1,1,28,28)
};
ref class coreml_MNISTOutput sealed
{
public:
property ::Windows::AI::MachineLearning::TensorInt64Bit^ classLabel; // shape(-1,1)
property ::Windows::Foundation::Collections::IVector<::Windows::Foundation::Collections::IMap<int64_t, float>^>^ prediction;
};
ref class coreml_MNISTModel sealed
{
private:
::Windows::AI::MachineLearning::LearningModel^ m_model;
::Windows::AI::MachineLearning::LearningModelSession^ m_session;
::Windows::AI::MachineLearning::LearningModelBinding^ m_binding;
public:
property ::Windows::AI::MachineLearning::LearningModel^ LearningModel { ::Windows::AI::MachineLearning::LearningModel^ get() { return m_model; } }
property ::Windows::AI::MachineLearning::LearningModelSession^ LearningModelSession { ::Windows::AI::MachineLearning::LearningModelSession^ get() { return m_session; } }
property ::Windows::AI::MachineLearning::LearningModelBinding^ LearningModelBinding { ::Windows::AI::MachineLearning::LearningModelBinding^ get() { return m_binding; } }
static ::Windows::Foundation::IAsyncOperation<coreml_MNISTModel^>^ CreateFromStreamAsync(::Windows::Storage::Streams::IRandomAccessStreamReference^ stream, ::Windows::AI::MachineLearning::LearningModelDeviceKind deviceKind = ::Windows::AI::MachineLearning::LearningModelDeviceKind::Cpu)
{
return ::concurrency::create_async([stream, deviceKind] {
return ::concurrency::create_task(::Windows::AI::MachineLearning::LearningModel::LoadFromStreamAsync(stream))
.then([deviceKind](::Windows::AI::MachineLearning::LearningModel^ learningModel) {
coreml_MNISTModel^ model = ref new coreml_MNISTModel();
model->m_model = learningModel;
::Windows::AI::MachineLearning::LearningModelDevice^ device = ref new ::Windows::AI::MachineLearning::LearningModelDevice(deviceKind);
model->m_session = ref new ::Windows::AI::MachineLearning::LearningModelSession(model->m_model, device);
model->m_binding = ref new ::Windows::AI::MachineLearning::LearningModelBinding(model->m_session);
return model;
});
});
}
::Windows::Foundation::IAsyncOperation<coreml_MNISTOutput^>^ EvaluateAsync(coreml_MNISTInput^ input)
{
if (this->m_model == nullptr) throw ref new Platform::InvalidArgumentException();
return ::concurrency::create_async([this, input] {
return ::concurrency::create_task([this, input]() {
m_binding->Bind("image", input->image);
return ::concurrency::create_task(this->m_session->EvaluateAsync(m_binding, L""));
}).then([](::Windows::AI::MachineLearning::LearningModelEvaluationResult^ evalResult) {
coreml_MNISTOutput^ output = ref new coreml_MNISTOutput();
output->classLabel = static_cast<::Windows::AI::MachineLearning::TensorInt64Bit^>(evalResult->Outputs->Lookup("classLabel"));
output->prediction = static_cast<::Windows::Foundation::Collections::IVector<::Windows::Foundation::Collections::IMap<int64_t, float>^>^>(evalResult->Outputs->Lookup("prediction"));
return output;
});
});
}
};

Просмотреть файл

@ -8,4 +8,4 @@
#include <ppltasks.h>
#include "App.xaml.h"
#include "model.h"
#include "mnist.h"