[WIP] Port image tests from WAI (#3365)

* Copy image tests from ADO

* wip

* Port tests to googletest

* Add FNS-Candy license

* Add missing collaterals

* Remove brand images

* Fix typos

* Use PrepareModelSessionBinding in MnistImageTest

* Fix typos
This commit is contained in:
Tiago Koji Castro Shibata 2020-04-01 15:38:44 -07:00 committed by GitHub
parent 1c334ed0f1
commit 1671072b6b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 1511 additions and 0 deletions

View file

@ -83,6 +83,17 @@ function(get_winml_test_concurrency_src
set(${output_winml_test_concurrency_src} ${winml_test_concurrency_src} PARENT_SCOPE)
endfunction()
function(get_winml_test_image_src
winml_test_src_path
output_winml_test_image_src
)
if (onnxruntime_USE_DML)
set(${output_winml_test_scenario_libs} "onnxruntime_providers_dml" PARENT_SCOPE)
endif()
file(GLOB winml_test_image_src CONFIGURE_DEPENDS "${winml_test_src_path}/image/*.cpp")
set(${output_winml_test_image_src} ${winml_test_image_src} PARENT_SCOPE)
endfunction()
file(GLOB winml_test_common_src CONFIGURE_DEPENDS "${WINML_TEST_SRC_DIR}/common/*.cpp")
add_library(winml_test_common STATIC ${winml_test_common_src})
add_dependencies(winml_test_common
@ -127,6 +138,18 @@ endif()
# on dev machines but not on the aiinfra agent pool
target_link_options(winml_test_scenario PRIVATE /ignore:4199)
get_winml_test_image_src(${WINML_TEST_SRC_DIR} winml_test_image_src winml_test_image_libs)
add_winml_test(
TARGET winml_test_image
SOURCES ${winml_test_image_src}
LIBS winml_test_common delayimp.lib ${winml_test_image_libs}
)
target_precompiled_header(winml_test_image testPch.h)
target_link_options(winml_test_image PRIVATE /DELAYLOAD:d3d12.dll /DELAYLOAD:api-ms-win-core-file-l1-2-2.dll /DELAYLOAD:api-ms-win-core-synch-l1-2-1.dll)
if (EXISTS ${dxcore_header})
target_link_options(winml_test_image PRIVATE /DELAYLOAD:ext-ms-win-dxcore-l1-*.dll)
endif()
get_winml_test_concurrency_src(${WINML_TEST_SRC_DIR} winml_test_concurrency_src)
add_winml_test(
@ -155,9 +178,15 @@ function(add_winml_collateral source)
endfunction()
add_winml_collateral("${WINML_TEST_SRC_DIR}/api/models/*.onnx")
add_winml_collateral("${WINML_TEST_SRC_DIR}/collateral/images/*.jpg")
add_winml_collateral("${WINML_TEST_SRC_DIR}/collateral/images/*.png")
add_winml_collateral("${WINML_TEST_SRC_DIR}/collateral/models/*.onnx")
add_winml_collateral("${WINML_TEST_SRC_DIR}/common/testdata/squeezenet/*")
add_winml_collateral("${WINML_TEST_SRC_DIR}/image/images/*.jpg")
add_winml_collateral("${WINML_TEST_SRC_DIR}/image/images/*.png")
add_winml_collateral("${WINML_TEST_SRC_DIR}/image/groundTruth/*.jpg")
add_winml_collateral("${WINML_TEST_SRC_DIR}/image/groundTruth/*.png")
add_winml_collateral("${WINML_TEST_SRC_DIR}/image/models/*.onnx")
add_winml_collateral("${WINML_TEST_SRC_DIR}/scenario/cppwinrt/*.onnx")
add_winml_collateral("${WINML_TEST_SRC_DIR}/scenario/models/*.onnx")
add_winml_collateral("${REPO_ROOT}/onnxruntime/test/testdata/sequence_length.onnx")

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

View file

@ -0,0 +1,4 @@
The FNS_Candy machine learning models here are used with permission from Justin Johnson.
For additional information on these models, refer to:
* [Fast-neural-style GitHub repo](https://github.com/jcjohnson/fast-neural-style)
* [Perceptual Losses for Real-Time Style Transfer and Super-Resolution](https://cs.stanford.edu/people/jcjohns/papers/eccv16/JohnsonECCV16.pdf)

Binary file not shown.

127
winml/test/image/README.md Normal file
View file

@ -0,0 +1,127 @@
# Overview
ImageTests are to test all kinds of scenarios that are related to images.
# Purpose
To make image related tests data driven and increase test code coverage.
# Image Test Data Table
|Table Name | Device |EvaluationStrategies|Models |Input Files |Output Binding Strategies|Input Image Sources |InputPixelFormats|
|--------------|--------------|--------------------|---------------------------|-----------------|-------------------------|---------------------|-----------------|
|Table Rows |GPU |Async |fns-candy_Bgr8_freeDimInput|fish_720.png |Bound |FromImageFeatureValue|Bgra8
| |CPU |Sync |fns-candy_Bgr8 |fish_720_Gray.png|Unbound |FromVideoFrame |Rgba8
| | | |fns-candy_Rgb8 | | |FromCPUResource |Gray8
| | | |fns-candy_tensor | | |FromGPUResource |
# Test Coverage
### 1. Devices
> Devices the Test uses.
* GPU
* CPU
### 2. Evaluation Strategy
> The strategy to use during evalution.
* EvalutateAsync
* EvaluateSync
* MultipleEvaluations (**TODO**)
* SwapChain (**TODO**)
* Chain (**TODO**)
### 3. Output Binding Strategy
* Bound
```
VideoFrame outputimage(BitmapPixelFormat::Rgba8, outputtensorshape.GetAt(3), outputtensorshape.GetAt(2));
ImageFeatureValue outputTensor = ImageFeatureValue::CreateFromVideoFrame(outputimage);
```
* Unbound
### 4. Models
> Des: Currently, we are using four models, FNS-candy_Bgr8_freeDimInput, FNS-candy_Bgr8, FNS-candy_Rgb8, and FNS-candy_Tensor. We would try to get more models to cover the following listed cases.
a. [Input Image Metadata](https://github.com/onnx/onnx/blob/master/docs/MetadataProps.md)
1. No metadata provided (**TODO**)
2. BitmapPixelFormat
* Bgr8
* Rgb8
* Gray8
* Bgra8 (**TODO**, not supported in RS5)
* Rgba8 (**TODO**, not supported in RS5)
* yuv (**TODO**, not in ONNX1.2.2 spec)
* ColorSpaceGamma
* sRGB
* Linear (**TODO**, not supported in RS5)
* NominalPixelRange
* NominalRange_0_255
* Normalized_0_1 (No such model)
* Normalized_1_1 (No such model)
* NominalRange_16_235 (No such model)
b. Model Input Output Type
* free dimension
* image : corresponding to ImageFeatureDescriptor
* tensor : corresponding to TensorFeatureDescriptor
c. Models we are using.
* Model takes Gray8 image as input and also output image (**TODO**, MNIST outputs tensor)
* FNS-candy_Bgr8_freeDimInput
* FNS-candy_Bgr8
* FNS-candy_Rgb8
* FNS-candy_Tensor
### 5. Input Image Files
* fish_720.png
* fish_720_gray.png
### 6. Input
a. input image source
* FromImageFeatureValue
```
VideoFrame frame = VideoFrame::CreateWithSoftwareBitmap(softwareBitmap);
VERIFY_NO_THROW(m_modelBinding.Bind(inputFeature.Current().Name(), frame));
```
* FromVideoFrame
```
VideoFrame frame = VideoFrame::CreateWithSoftwareBitmap(softwareBitmap);
VERIFY_NO_THROW(m_modelBinding.Bind(inputFeature.Current().Name(), frame));
```
* FromGPUResource
> Bind input from GPU Resources as described in this [PR](https://mscodehub.visualstudio.com/_git/WindowsAI/pullrequest/4542?_a=overview)
* FromCPUResource
> Bind input from GPU Resources as described in this [PR](https://mscodehub.visualstudio.com/_git/WindowsAI/pullrequest/4507?_a=overview)
b. Multiple inputs (**TODO**)
1. test the case where 2 inputs requiring GPU processing are bound back to back forcing bind calls that potentially overlap GPU work from previous bind
2. Test models require multiple inputs
c. Bind with Property (**TODO**)
* _If bind with Property, what properties should be tested? And how to make properties as parameters?_
### 7. InputPixelFormats
> We could convert the input image to the following PixelFormats, and then used as input of model. The pixel format expected from model input can be different from the pixel format of real input. But WinML can handle the conversion between them.
* Bgra8
* Rgba8
* Gray8
# Implementation
Googletest's [value parameterized tests](https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#value-parameterized-tests) are used.

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

View file

@ -0,0 +1,284 @@
#include "testPch.h"
#include "imageTestHelper.h"
#include "robuffer.h"
#include "winrt/Windows.Storage.h"
#include "winrt/Windows.Storage.Streams.h"
#include <d3dx12.h>
#include <MemoryBuffer.h>
#include <wil\Resource.h>
#define FENCE_SIGNAL_VALUE 1
using namespace winrt;
using namespace winrt::Windows::AI::MachineLearning;
using namespace winrt::Windows::Foundation::Collections;
using namespace winrt::Windows::Media;
using namespace winrt::Windows::Graphics::Imaging;
namespace ImageTestHelper {
BitmapPixelFormat GetPixelFormat(const std::wstring& inputPixelFormat) {
// Return corresponding BitmapPixelFormat according to input string
if (L"Bgra8" == inputPixelFormat || L"Bgr8" == inputPixelFormat) {
return BitmapPixelFormat::Bgra8;
} else if (L"Rgba8" == inputPixelFormat || L"Rgb8" == inputPixelFormat) {
return BitmapPixelFormat::Rgba8;
} else if (L"Gray8" == inputPixelFormat) {
return BitmapPixelFormat::Gray8;
} else {
throw std::invalid_argument("Unsupported pixelFormat");
}
}
TensorFloat LoadInputImageFromCPU(
SoftwareBitmap softwareBitmap,
const std::wstring& modelPixelFormat) {
softwareBitmap = SoftwareBitmap::Convert(softwareBitmap, BitmapPixelFormat::Bgra8);
BYTE* pData = nullptr;
UINT32 size = 0;
winrt::Windows::Graphics::Imaging::BitmapBuffer spBitmapBuffer(softwareBitmap.LockBuffer(winrt::Windows::Graphics::Imaging::BitmapBufferAccessMode::Read));
winrt::Windows::Foundation::IMemoryBufferReference reference = spBitmapBuffer.CreateReference();
auto spByteAccess = reference.as<::Windows::Foundation::IMemoryBufferByteAccess>();
spByteAccess->GetBuffer(&pData, &size);
uint32_t height = softwareBitmap.PixelHeight();
uint32_t width = softwareBitmap.PixelWidth();
// TODO: Need modification for Gray8
std::vector<int64_t> shape = { 1, 3, height , width };
float* pCPUTensor;
uint32_t uCapacity;
TensorFloat tf = TensorFloat::Create(shape);
com_ptr<ITensorNative> itn = tf.as<ITensorNative>();
itn->GetBuffer(reinterpret_cast<BYTE**>(&pCPUTensor), &uCapacity);
if (BitmapPixelFormat::Bgra8 == GetPixelFormat(modelPixelFormat)) {
for (UINT32 i = 0; i < size; i += 4) {
UINT32 pixelInd = i / 4;
pCPUTensor[pixelInd] = (float)pData[i];
pCPUTensor[(height * width) + pixelInd] = (float)pData[i + 1];
pCPUTensor[(height * width * 2) + pixelInd] = (float)pData[i + 2];
}
} else if (BitmapPixelFormat::Rgba8 == GetPixelFormat(modelPixelFormat)) {
for (UINT32 i = 0; i < size; i += 4) {
UINT32 pixelInd = i / 4;
pCPUTensor[pixelInd] = (float)pData[i + 2];
pCPUTensor[(height * width) + pixelInd] = (float)pData[i + 1];
pCPUTensor[(height * width * 2) + pixelInd] = (float)pData[i];
}
}
// else if()
// TODO: for Gray8
else {
std::cerr << "Unsupportted pixelFormat";
}
return tf;
}
TensorFloat LoadInputImageFromGPU(
SoftwareBitmap softwareBitmap,
const std::wstring& modelPixelFormat) {
softwareBitmap = SoftwareBitmap::Convert(softwareBitmap, BitmapPixelFormat::Bgra8);
BYTE* pData = nullptr;
UINT32 size = 0;
BitmapBuffer spBitmapBuffer(softwareBitmap.LockBuffer(winrt::Windows::Graphics::Imaging::BitmapBufferAccessMode::Read));
winrt::Windows::Foundation::IMemoryBufferReference reference = spBitmapBuffer.CreateReference();
com_ptr<::Windows::Foundation::IMemoryBufferByteAccess> spByteAccess = reference.as<::Windows::Foundation::IMemoryBufferByteAccess>();
spByteAccess->GetBuffer(&pData, &size);
std::vector<int64_t> shape = { 1, 3, softwareBitmap.PixelHeight() , softwareBitmap.PixelWidth() };
float* pCPUTensor;
uint32_t uCapacity;
// CPU tensorization
TensorFloat tf = TensorFloat::Create(shape);
com_ptr<ITensorNative> itn = tf.as<ITensorNative>();
itn->GetBuffer(reinterpret_cast<BYTE**>(&pCPUTensor), &uCapacity);
uint32_t height = softwareBitmap.PixelHeight();
uint32_t width = softwareBitmap.PixelWidth();
if (BitmapPixelFormat::Bgra8 == GetPixelFormat(modelPixelFormat)) {
for (UINT32 i = 0; i < size; i += 4) {
UINT32 pixelInd = i / 4;
pCPUTensor[pixelInd] = (float)pData[i];
pCPUTensor[(height * width) + pixelInd] = (float)pData[i + 1];
pCPUTensor[(height * width * 2) + pixelInd] = (float)pData[i + 2];
}
} else if (BitmapPixelFormat::Rgba8 == GetPixelFormat(modelPixelFormat)) {
for (UINT32 i = 0; i < size; i += 4) {
UINT32 pixelInd = i / 4;
pCPUTensor[pixelInd] = (float)pData[i + 2];
pCPUTensor[(height * width) + pixelInd] = (float)pData[i + 1];
pCPUTensor[(height * width * 2) + pixelInd] = (float)pData[i];
}
}
// else if()
// TODO: for Gray8
else {
std::cerr << "unsupported pixelFormat";
}
// create the d3d device.
com_ptr<ID3D12Device> pD3D12Device = nullptr;
WINML_EXPECT_NO_THROW(D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), reinterpret_cast<void**>(&pD3D12Device)));
// create the command queue.
com_ptr<ID3D12CommandQueue> dxQueue = nullptr;
D3D12_COMMAND_QUEUE_DESC commandQueueDesc = {};
commandQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
pD3D12Device->CreateCommandQueue(&commandQueueDesc, __uuidof(ID3D12CommandQueue), reinterpret_cast<void**>(&dxQueue));
com_ptr<ILearningModelDeviceFactoryNative> devicefactory = get_activation_factory<LearningModelDevice, ILearningModelDeviceFactoryNative>();
com_ptr<ITensorStaticsNative> tensorfactory = get_activation_factory<TensorFloat, ITensorStaticsNative>();
com_ptr<::IUnknown> spUnk;
devicefactory->CreateFromD3D12CommandQueue(dxQueue.get(), spUnk.put());
// Create ID3D12GraphicsCommandList and Allocator
D3D12_COMMAND_LIST_TYPE queuetype = dxQueue->GetDesc().Type;
com_ptr<ID3D12CommandAllocator> alloctor;
com_ptr<ID3D12GraphicsCommandList> cmdList;
pD3D12Device->CreateCommandAllocator(
queuetype,
winrt::guid_of<ID3D12CommandAllocator>(),
alloctor.put_void());
pD3D12Device->CreateCommandList(
0,
queuetype,
alloctor.get(),
nullptr,
winrt::guid_of<ID3D12CommandList>(),
cmdList.put_void());
// Create Committed Resource
// 3 is number of channels we use. R G B without alpha.
UINT64 bufferbytesize = 3 * sizeof(float) * softwareBitmap.PixelWidth()*softwareBitmap.PixelHeight();
D3D12_HEAP_PROPERTIES heapProperties = {
D3D12_HEAP_TYPE_DEFAULT,
D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
D3D12_MEMORY_POOL_UNKNOWN,
0,
0
};
D3D12_RESOURCE_DESC resourceDesc = {
D3D12_RESOURCE_DIMENSION_BUFFER,
0,
bufferbytesize,
1,
1,
1,
DXGI_FORMAT_UNKNOWN,
{ 1, 0 },
D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS
};
com_ptr<ID3D12Resource> pGPUResource = nullptr;
com_ptr<ID3D12Resource> imageUploadHeap;
pD3D12Device->CreateCommittedResource(
&heapProperties,
D3D12_HEAP_FLAG_NONE,
&resourceDesc,
D3D12_RESOURCE_STATE_COMMON,
nullptr,
__uuidof(ID3D12Resource),
pGPUResource.put_void()
);
// Create the GPU upload buffer.
auto heap_properties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
WINML_EXPECT_NO_THROW(pD3D12Device->CreateCommittedResource(
&heap_properties,
D3D12_HEAP_FLAG_NONE,
&CD3DX12_RESOURCE_DESC::Buffer(bufferbytesize),
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
__uuidof(ID3D12Resource),
imageUploadHeap.put_void()));
// Copy from Cpu to GPU
D3D12_SUBRESOURCE_DATA CPUData = {};
CPUData.pData = reinterpret_cast<BYTE*>(pCPUTensor);
CPUData.RowPitch = bufferbytesize;
CPUData.SlicePitch = bufferbytesize;
UpdateSubresources(cmdList.get(), pGPUResource.get(), imageUploadHeap.get(), 0, 0, 1, &CPUData);
// Close the command list and execute it to begin the initial GPU setup.
WINML_EXPECT_NO_THROW(cmdList->Close());
ID3D12CommandList* ppCommandLists[] = { cmdList.get() };
dxQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
//Create Event
HANDLE directEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
wil::unique_event hDirectEvent(directEvent);
//Create Fence
Microsoft::WRL::ComPtr<ID3D12Fence> spDirectFence = nullptr;
WINML_EXPECT_HRESULT_SUCCEEDED(pD3D12Device->CreateFence(
0,
D3D12_FENCE_FLAG_NONE,
IID_PPV_ARGS(spDirectFence.ReleaseAndGetAddressOf())));
//Adds fence to queue
WINML_EXPECT_HRESULT_SUCCEEDED(dxQueue->Signal(spDirectFence.Get(), FENCE_SIGNAL_VALUE));
WINML_EXPECT_HRESULT_SUCCEEDED(spDirectFence->SetEventOnCompletion(FENCE_SIGNAL_VALUE, hDirectEvent.get()));
//Wait for signal
DWORD retVal = WaitForSingleObject(hDirectEvent.get(), INFINITE);
if (retVal != WAIT_OBJECT_0) {
WINML_EXPECT_HRESULT_SUCCEEDED(E_UNEXPECTED);
}
// GPU tensorize
com_ptr<::IUnknown> spUnkTensor;
TensorFloat input1imagetensor(nullptr);
int64_t shapes[4] = { 1,3, softwareBitmap.PixelWidth(), softwareBitmap.PixelHeight() };
tensorfactory->CreateFromD3D12Resource(pGPUResource.get(), shapes, 4, spUnkTensor.put());
spUnkTensor.try_as(input1imagetensor);
return input1imagetensor;
}
bool VerifyHelper(
VideoFrame actual,
VideoFrame expected) {
// Verify two input ImageFeatureValues are identified.
auto softwareBitmapActual = actual.SoftwareBitmap();
auto softwareBitmapExpected = expected.SoftwareBitmap();
WINML_EXPECT_TRUE(softwareBitmapActual.PixelHeight() == softwareBitmapExpected.PixelHeight());
WINML_EXPECT_TRUE(softwareBitmapActual.PixelWidth() == softwareBitmapExpected.PixelWidth());
WINML_EXPECT_TRUE(softwareBitmapActual.BitmapPixelFormat() == softwareBitmapExpected.BitmapPixelFormat());
uint32_t size = 4 * softwareBitmapActual.PixelHeight() * softwareBitmapActual.PixelWidth();
winrt::Windows::Storage::Streams::Buffer actualOutputBuffer(size);
winrt::Windows::Storage::Streams::Buffer expectedOutputBuffer(size);
softwareBitmapActual.CopyToBuffer(actualOutputBuffer);
softwareBitmapExpected.CopyToBuffer(expectedOutputBuffer);
byte* actualBytes;
actualOutputBuffer.try_as<::Windows::Storage::Streams::IBufferByteAccess>()->Buffer(&actualBytes);
byte* expectedBytes;
expectedOutputBuffer.try_as<::Windows::Storage::Streams::IBufferByteAccess>()->Buffer(&expectedBytes);
byte* pActualByte = actualBytes;
byte* pExpectedByte = expectedBytes;
// hard code, might need to be modified later.
const float cMaxErrorRate = 0.06f;
int8_t epsilon = 20;
// Even given two same ImageFeatureValues, the comparison cannot exactly match.
// So we use error rate.
UINT errors = 0;
for (uint32_t i = 0; i < size; i++, pActualByte++, pExpectedByte++) {
auto diff = (*pActualByte - *pExpectedByte);
if (diff > epsilon) {
errors++;
}
}
std::cerr << "total errors is " << errors << "/" << size << ", errors rate is " << (float)errors / size;
return (float)errors / size < cMaxErrorRate;
}
}

View file

@ -0,0 +1,34 @@
//-----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
#pragma once
#include <winrt/Windows.Media.h>
#include <winrt/Windows.Graphics.Imaging.h>
enum OutputBindingStrategy { Bound, Unbound, Empty };
enum EvaluationStrategy { Async, Sync };
enum ModelInputOutputType { Image, Tensor };
enum InputImageSource { FromVideoFrame, FromImageFeatureValue, FromCPUResource, FromGPUResource };
enum VideoFrameSource { FromSoftwareBitmap, FromDirect3DSurface, FromUnsupportedD3DSurface };
namespace ImageTestHelper
{
winrt::Windows::Graphics::Imaging::BitmapPixelFormat GetPixelFormat(const std::wstring& inputPixelFormat);
winrt::Windows::AI::MachineLearning::TensorFloat LoadInputImageFromCPU(
winrt::Windows::Graphics::Imaging::SoftwareBitmap softwareBitmap,
const std::wstring& modelPixelFormat);
winrt::Windows::AI::MachineLearning::TensorFloat LoadInputImageFromGPU(
winrt::Windows::Graphics::Imaging::SoftwareBitmap softwareBitmap,
const std::wstring& modelPixelFormat);
bool VerifyHelper(
winrt::Windows::Media::VideoFrame actual,
winrt::Windows::Media::VideoFrame expected);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,4 @@
The FNS_Candy machine learning models here are used with permission from Justin Johnson.
For additional information on these models, refer to:
* [Fast-neural-style GitHub repo](https://github.com/jcjohnson/fast-neural-style)
* [Perceptual Losses for Real-Time Style Transfer and Super-Resolution](https://cs.stanford.edu/people/jcjohns/papers/eccv16/JohnsonECCV16.pdf)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.