Use image metadata model for cppcx
This commit is contained in:
Родитель
9b3c5a5692
Коммит
4fb87c2c05
Двоичный файл не отображается.
Двоичные данные
Samples/MNIST/UWP/cppcx/Assets/model.onnx
Двоичные данные
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"
|
||||
|
|
Загрузка…
Ссылка в новой задаче