├── .github
└── workflows
│ └── docs.yml
├── .gitignore
├── .vscode
└── settings.json
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── SECURITY.md
├── SUPPORT.md
├── goals
├── back-end.md
├── index.md
├── media
│ ├── apple-store.png
│ ├── custom-vision-detect-dog.png
│ ├── custom-vision-logo.png
│ ├── custom-vision-project-settings.png
│ ├── dog-pictures.png
│ ├── google-play-badge.png
│ ├── mutt-match-app-phone.png
│ ├── power-apps-logo.png
│ ├── power-automate-flow.png
│ ├── power-automate-logo.png
│ ├── prediction-key-url-root.png
│ ├── prediction-key-url.png
│ └── published-iteration.png
├── mobile-app.md
└── train-model.md
├── mkdocs.yml
├── model-images
├── testing-images
│ ├── american-staffordshire-terrier-10.jpg
│ ├── american-staffordshire-terrier-9.jpg
│ ├── australian-shepherd-10.jpg
│ ├── australian-shepherd-9.jpg
│ ├── buggle-10.jpg
│ ├── buggle-9.jpg
│ ├── german-wirehaired-pointer-10.jpg
│ ├── german-wirehaired-pointer-9.jpg
│ ├── shorkie-14.jpg
│ └── shorkie-15.jpg
└── training-images
│ ├── american-staffordshire-terrier-1.jpg
│ ├── american-staffordshire-terrier-2.jpg
│ ├── american-staffordshire-terrier-3.jpg
│ ├── american-staffordshire-terrier-4.jpg
│ ├── american-staffordshire-terrier-5.jpg
│ ├── american-staffordshire-terrier-6.jpg
│ ├── american-staffordshire-terrier-7.jpg
│ ├── american-staffordshire-terrier-8.jpg
│ ├── australian-shepherd-1.jpg
│ ├── australian-shepherd-2.jpg
│ ├── australian-shepherd-3.jpg
│ ├── australian-shepherd-4.jpg
│ ├── australian-shepherd-5.jpg
│ ├── australian-shepherd-6.jpg
│ ├── australian-shepherd-7.jpg
│ ├── australian-shepherd-8.jpg
│ ├── buggle-1.jpg
│ ├── buggle-2.jpg
│ ├── buggle-3.jpg
│ ├── buggle-4.jpg
│ ├── buggle-5.jpg
│ ├── buggle-6.jpg
│ ├── buggle-7.jpg
│ ├── buggle-8.jpg
│ ├── german-wirehaired-pointer-1.jpg
│ ├── german-wirehaired-pointer-2.jpg
│ ├── german-wirehaired-pointer-3.jpg
│ ├── german-wirehaired-pointer-4.jpg
│ ├── german-wirehaired-pointer-5.jpg
│ ├── german-wirehaired-pointer-6.jpg
│ ├── german-wirehaired-pointer-7.jpg
│ ├── german-wirehaired-pointer-8.jpg
│ ├── golden-doodle-5.jfif
│ ├── shorkie-1.jpg
│ ├── shorkie-10.jpg
│ ├── shorkie-11.jpg
│ ├── shorkie-12.jpg
│ ├── shorkie-13.jpg
│ ├── shorkie-2.jpg
│ ├── shorkie-3.jpg
│ ├── shorkie-4.jpg
│ ├── shorkie-5.jpg
│ ├── shorkie-6.jpg
│ ├── shorkie-7.jpg
│ ├── shorkie-8.jpg
│ └── shorkie-9.jpg
├── requirements.txt
├── theme
├── assets
│ ├── images
│ │ ├── 8_BIT.png
│ │ ├── favicon.ico
│ │ ├── favicon.png
│ │ └── icon_garage_white.png
│ └── stylesheets
│ │ └── extra.css
└── partials
│ ├── footer.html
│ └── tos.html
└── validation
├── requirements.txt
└── validate-model.py
/.github/workflows/docs.yml:
--------------------------------------------------------------------------------
1 | name: Publish docs via GitHub Pages
2 | on:
3 | push:
4 | branches:
5 | - main
6 | workflow_dispatch:
7 |
8 | jobs:
9 | build:
10 | name: Deploy docs
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout main
14 | uses: actions/checkout@v2
15 |
16 | - name: Deploy docs
17 | uses: mhausenblas/mkdocs-deploy-gh-pages@master
18 | env:
19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
20 | REQUIREMENTS: requirements.txt
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .venv
2 | __pycache__
3 | .DS_Store
4 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "markdownlint.config": {
3 | "MD028": false,
4 | "MD025": {
5 | "front_matter_title": ""
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Scenario: The Mutt Matcher (Power Apps version)
2 |
3 | According to the World Health Organization there are more than 200 million stray dogs worldwide. The American Society for the Prevention of Cruelty to Animals estimates over 3 million dogs enter their shelters annually - about 6 dogs per minute! Anything that can reduce the time and effort to take in strays can potentially help millions of dogs every year.
4 |
5 | Different breeds have different needs, or react differently to people, so when a stray or lost dog is found, identifying the breed can be a great help.
6 |
7 | 
8 |
9 | Your team has been asked by a fictional animal shelter to build **Mutt Matcher** - a mobile app to help determine the breed of a dog when it has been found. To help deliver this quickly, this will be a no-code app built using an on-line low/no-code app generation tool. This app will take a photo of the dog, and then use an image classifier Machine learning (ML) model to determine the breed, then show the breed in the app.
10 |
11 | This app will help workers and volunteers to be able to quickly detect the breed and make decisions on the best way to approach and care for the dog.
12 |
13 | 
14 |
15 | The animal shelter has provided [a set of images](https://github.com/microsoft/hack-workshop-power-apps/tree/main/model-images) for a range of dog breeds to get you started. These can be used to train the ML model using a service called Custom Vision.
16 |
17 | ## Prerequisites
18 |
19 | Each team member will need an Azure account. With [Azure for Students](https://azure.microsoft.com/free/students/?WT.mc_id=academic-39324-jabenn), you can access $100 in free credit, and a large suite of free services!
20 |
21 | Each team member will also need a Power Apps account, and you can sign up for a free developer plan. To sign up:
22 |
23 | 1. You will need a Microsoft 365 account. If you don't already have one, for example from your school, you can sign up for [the free M365 developer program](https://developer.microsoft.com/microsoft-365/dev-program?WT.mc_id=academic-39324-jabenn). You will need to activate your subscription and set up your new tenant and a new email address for that tenant. Once created, you can set up all the members of the team as users.
24 |
25 | > 💁 You can read more about signing up for the M365 developer program in the [Microsoft 365 Developer Program FAQ](https://docs.microsoft.com/office/developer-program/microsoft-365-developer-program-faq?WT.mc_id=academic-39324-jabenn).
26 |
27 | 1. Once your Microsoft 365 account is set up, you can then sign up for [the Power Apps developer plan](https://powerapps.microsoft.com/developerplan/?WT.mc_id=academic-39324-jabenn). You will need to log in using your M365 account, so if you set up an M365 developer program account then you will need to use the email address you created when you activated your subscription.
28 |
29 | > 💁 All the members of your team should be using the same M365 tenant (same school, or all as different users of the same M365 developer program) so that you can work together on this app.
30 |
31 | ### Power Platform Browser Support
32 |
33 | Users can access the model-driven apps with the most recent versions of these popular browsers:
34 |
35 | - Microsoft Edge (based on Chromium)
36 | - Chrome
37 | - Firefox
38 | - Safari
39 |
40 | For more details on [supported browsers and troubleshooting](https://docs.microsoft.com/power-platform/admin/supported-web-browsers-and-mobile-devices?WT.mc_id=academic-39324-jabenn)
41 |
42 | ## Git and GitHub
43 |
44 | Your team should also be familiar with the following:
45 |
46 | - [Forking](https://docs.github.com/github/getting-started-with-github/quickstart/fork-a-repo)
47 |
48 | - [Cloning](https://docs.github.com/github/creating-cloning-and-archiving-repositories/cloning-a-repository-from-github/cloning-a-repository)
49 |
50 | - If you have not used git before we suggest [GitHub Desktop](https://desktop.github.com/)
51 |
52 | If you do not have any experience with GitHub we recommend the following Microsoft Learn Module [Introduction to GitHub](https://docs.microsoft.com/en-us/learn/modules/introduction-to-github?WT.mc_id=academic-39324-jabenn)
53 |
54 | ## Resources
55 |
56 | A series of resources will be provided to help your team determine the appropriate steps for completion. The resources provided should provide your team with enough information to achieve each goal. These resources include appropriate links to documentation to learn more about the services you are using and how to do common tasks
57 |
58 | If you get stuck, you can always ask a mentor for additional help.
59 |
60 | ## Exploring the application
61 |
62 |   
63 |
64 | The application your team will build will consist of 2 components:
65 |
66 | - An image classifier running in the cloud using Microsoft Custom Vision
67 |
68 | - A no-code based mobile app built using Microsoft Power Apps
69 |
70 | - No-code back end logic built using Microsoft Power Automate
71 |
72 | When a dog breed needs to be detected:
73 |
74 | 1. A button on the mobile app is tapped
75 |
76 | 1. The mobile app uses the devices camera to take a picture
77 |
78 | 1. The picture is sent to a no-code application flow, where it is then sent to the image classifier ML model in the cloud to detect the breed
79 |
80 | 1. The results of the classification are sent back to the mobile app and displayed
81 |
82 | ## Goals
83 |
84 | Your team will train the ML model, build the mobile app, build the back end logic, then deploy to a mobile device and test.
85 |
86 | > 💁 Each goal below defines what you need to achieve, and points you to relevant on-line resources that will show you how the cloud services or tools work. The aim here is not to provide you with detailed steps to complete the task, but allow you to explore the documentation and learn more about the services as you work out how to complete each goal.
87 |
88 | 1. [Train your ML model](./goals/train-model.md): Your team will need to train the ML model in the cloud using Microsoft Custom Vision. You can train and test this model using the images that have been provided by the animal shelter.
89 |
90 | 1. [Build your no/low-code back end](./goals/back-end.md): Your team will use Power Automate with the Custom Vision connector to build a Power Automate flow that can be called with an image. This flow will send the image to Custom Vision, and return the detected breed.
91 |
92 | 1. [Build your no/low-code mobile app](./goals/mobile-app.md): Your team will use Power Apps to build a mobile app. This app will interact with the camera, capture an image, send it to the Power Automate flow, then show the result.
93 |
94 | ## Validation
95 |
96 | This workshop is designed to be a goal-oriented self-exploration of Azure and related technologies. Your team can validate the first goal using the supplied validation script, and instructions are provided where relevant. Your team can then validate the final solution by using the mobile app to take a picture of one of the provided testing images and ensuring the correct result is returned.
97 |
98 | ## Where do we go from here?
99 |
100 | This project is designed as a potential seed for ideas and future development during your hackathon. Other hack ideas for similar mobile apps that use image classification include:
101 |
102 | - Trash sorting into incineration/landfill, recycling, and compost.
103 |
104 | - Identification of disease in plant leaves.
105 |
106 | - Detecting skin cancer by classification of moles.
107 |
108 | Improvements you could make to this application include:
109 |
110 | - Adding a data store to save the count of breeds detected
111 |
112 | - Adding access to your photos to check the breed in a saved image
113 |
114 | ### Learn more
115 |
116 | You can learn more about using Custom Vision to train image classifiers and object detectors using the following resources:
117 |
118 | - [Custom Vision documentation](https://docs.microsoft.com/azure/cognitive-services/custom-vision-service/?WT.mc_id=academic-39324-jabenn)
119 |
120 | - [Custom Vision modules on Microsoft Learn, a free, hands-on, self-guided learning platform](https://docs.microsoft.com/users/jimbobbennett/collections/qe2ehjny7z7zgd?WT.mc_id=academic-39324-jabenn)
121 |
122 | You can learn more about Power Apps using the following resources:
123 |
124 | - [Power Apps documentation](https://docs.microsoft.com/power-automate/?WT.mc_id=academic-39324-jabenn)
125 |
126 | - [Power Apps modules and learning paths on Microsoft Learn, a free, hands-on, self-guided learning platform](https://docs.microsoft.com/learn/powerplatform/power-apps?WT.mc_id=academic-39324-jabenn)
127 |
128 | You can learn more about Power Automate using the following resources:
129 |
130 | - [Power Automate documentation](https://docs.microsoft.com/powerapps/?WT.mc_id=academic-39324-jabenn)
131 |
132 | - [Power Automate modules and learning paths on Microsoft Learn, a free, hands-on, self-guided learning platform](https://docs.microsoft.com/learn/powerplatform/power-automate?WT.mc_id=academic-39324-jabenn)
133 |
134 | ## Contributing
135 |
136 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
137 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
138 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
139 |
140 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide
141 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
142 | provided by the bot. You will only need to do this once across all repos using our CLA.
143 |
144 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
145 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
146 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
147 |
148 | ## Trademarks
149 |
150 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
151 | trademarks or logos is subject to and must follow
152 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
153 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
154 | Any use of third-party trademarks or logos are subject to those third-party's policies.
155 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
40 |
41 |
--------------------------------------------------------------------------------
/SUPPORT.md:
--------------------------------------------------------------------------------
1 | # TODO: The maintainer of this repo has not yet edited this file
2 |
3 | **REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?
4 |
5 | - **No CSS support:** Fill out this template with information about how to file issues and get help.
6 | - **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport).
7 | - **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide.
8 |
9 | *Then remove this first heading from this SUPPORT.MD file before publishing your repo.*
10 |
11 | # Support
12 |
13 | ## How to file issues and get help
14 |
15 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing
16 | issues before filing new issues to avoid duplicates. For new issues, file your bug or
17 | feature request as a new Issue.
18 |
19 | For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
20 | FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
21 | CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
22 |
23 | ## Microsoft Support Policy
24 |
25 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
26 |
--------------------------------------------------------------------------------
/goals/back-end.md:
--------------------------------------------------------------------------------
1 | # Goal 1: Build your no/low-code back end
2 |
3 | The **Mutt Matcher** needs to connect to your image classifier and classify an image, returning the result. To do this your team will need to build a no/low-code back end flow that is passed an image, sends it to the image classifier, and returns the top prediction.
4 |
5 | The goal of this section is create a Power Automate flow to classify an image.
6 |
7 | ## The no/low-code Service
8 |
9 | [](https://flow.microsoft.com/?WT.mc_id=academic-39324-jabenn)
10 |
11 | [Microsoft Power Automate](https://flow.microsoft.com/?WT.mc_id=academic-39324-jabenn) is a tool for building automated processes using flow-chart style no/low-code development. You start by defining triggers that are run when events happen, such as when a Power Apps mobile app button is tapped, an email is received, a form is submitted, or at a certain time each day. You then define a flow of events that happen using logic blocks, or connectors to services such as Custom Vision, databases, IoT platforms, or productivity applications.
12 |
13 | 
14 |
15 | For this workshop, you will need a Power Automate flow that is called by a Power Apps mobile app button. This will be passed an image from the mobile devices camera. This image will then be passed to the Custom Vision connector to classify an image. After the image is classified, the tag with the highest probability will be returned.
16 |
17 | ## Success criteria
18 |
19 | Your team will work together to create the Power Automate flow. Your team will have achieved this goal when the following success criteria is met:
20 |
21 | - Your flow takes an image passed from Power Apps.
22 |
23 | - Your flow is connected to Custom Vision using your image classifier, and passes the image from Power Apps converted to binary data.
24 |
25 | - You have parsed the output from Custom Vision and returned the first prediction (the predictions are always returned in order of most probable to least probable).
26 |
27 | ## Resources
28 |
29 | Your team might find these resources helpful:
30 |
31 | - [Power Automate documentation](https://docs.microsoft.com/power-automate/?WT.mc_id=academic-39324-jabenn)
32 |
33 | - [Create a cloud flow from a template in Power Automate documentation](https://docs.microsoft.com/power-automate/get-started-logic-template?WT.mc_id=academic-39324-jabenn#add-a-device)
34 |
35 | - [Custom Vision (Preview) connector documentation](https://docs.microsoft.com/connectors/cognitiveservicescustomvision/?WT.mc_id=academic-39324-jabenn)
36 |
37 | ## Tips
38 |
39 | - Use the Power Apps button template to get started
40 |
41 | - When you use the Custom Vision connector, you will need to provide the following pieces of information:
42 |
43 | - Prediction key
44 |
45 | - Prediction root URL
46 |
47 | - Project ID
48 |
49 | - Published iteration name
50 |
51 | - Image content
52 |
53 | The *Prediction Key* and *Prediction URL* come from the **Prediction URL** dialog. For the URL, you just need the root part, ending in `microsoft.com` or `azure.com` depending on the resource used when it was created.
54 |
55 | 
56 |
57 | In the dialog above, the root URL is `https://westus2.api.cognitive.microsoft.com`.
58 |
59 | The *Project ID* comes from the *Project Settings* for your Custom Vision project, available from the cog button.
60 |
61 | 
62 |
63 | The *Published iteration name* is the name you used when you published the iteration.
64 |
65 | - To pass the *Image content*, you will need to create *Dynamic content* that can be passed from the Power Apps mobile app. Images from the Power Apps mobile app camera are *base64 encoded*. Base64 encoding is a way to convert binary data into text that can be passed around applications. Before these images can be passed to Custom Vision, they need to be converted back to binary data. To do this:
66 |
67 | 1. Select the *Image Content* field, then select **Add dynamic content**
68 |
69 | 1. In the **Dynamic content** tab, select *Ask in PowerApps*. This will create a variable for the data passed in from the Power Apps, and it will default to something like `Classifyanimage(v2)_ImageContent`. The *Image content* will be set to this value.
70 |
71 | 1. This value cannot be used directly, it needs to be converted from a base64 encoded string to binary data using the [`dataUriToBinary` function](https://docs.microsoft.com/azure/logic-apps/workflow-definition-language-functions-reference?WT.mc_id=academic-39324-jabenn#dataUriToBinary). Close the *Dynamic content* popup by selecting outside it, then select the `Classifyanimage(v2)_ImageContent` value inside the *Image content* box to allow you to edit this value.
72 |
73 | 1. Select the **Expression** tab, then type `dataUriToBinary`, then select the function of that name that appears as you type, adding an open parentheses after the function name.
74 |
75 | 1. Select the **Dynamic content** tab, then select the `Classifyanimage(v2)_ImageContent` variable to pass this to the `dataUriToBinary` function. The final expression should read:
76 |
77 | ```javascript
78 | dataUriToBinary(triggerBody()['Classifyanimage(V2)_ImageContent'])
79 | ```
80 |
81 | 1. Select the **OK** button to update the value.
82 |
83 | - The easiest way to handle the output of the Custom Vision connector is to use a Parse JSON action. The schema to use is:
84 |
85 | ```json
86 | {
87 | "type": "array",
88 | "items": {
89 | "type": "object",
90 | "properties": {
91 | "probability": {
92 | "type": "number"
93 | },
94 | "tagId": {
95 | "type": "string"
96 | },
97 | "tagName": {
98 | "type": "string"
99 | }
100 | },
101 | "required": [
102 | "probability",
103 | "tagId",
104 | "tagName"
105 | ]
106 | }
107 | }
108 | ```
109 |
110 | This will convert the output of the Custom Vision connector to an array of objects. Pass the *Predictions* from the Custom Vision connector as the *Content*.
111 |
112 | - The predictions returned by Custom Vision are always returned in order of most probable to least probable, so you only need to return the first one. You can get this using the [`first` function](https://docs.microsoft.com/azure/logic-apps/workflow-definition-language-functions-reference?WT.mc_id=academic-39324-jabenn#first), passing in the array output from the Parse JSON action. The tag will be the `tagName` property on the first item in the array.
113 |
114 | - To return a value, you need to use the *Respond to a PowerApp or flow* action. Respond with text, passing the first prediction's `tagName` in a text field called `breed`.
115 |
116 | - So body("Parse_JSON") takes the result JSON as a dynamic object, which contains an array of predictions. The first() part gets the first item from this array, and the .tagName extracts the tag name field from that array item `tagname` = customvision.ai tag name of the image and tag = `breed` of dog
117 |
118 | - Ensure you add this as Expression and not Dynamic Content
119 |
120 | ## Final result
121 |
122 | 
123 |
124 | ## Next challenge
125 |
126 | The next goal is to [build your no-code mobile app](mobile-app.md).
127 |
--------------------------------------------------------------------------------
/goals/index.md:
--------------------------------------------------------------------------------
1 | {%
2 | include-markdown "../README.md"
3 | %}
4 |
--------------------------------------------------------------------------------
/goals/media/apple-store.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/apple-store.png
--------------------------------------------------------------------------------
/goals/media/custom-vision-detect-dog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/custom-vision-detect-dog.png
--------------------------------------------------------------------------------
/goals/media/custom-vision-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/custom-vision-logo.png
--------------------------------------------------------------------------------
/goals/media/custom-vision-project-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/custom-vision-project-settings.png
--------------------------------------------------------------------------------
/goals/media/dog-pictures.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/dog-pictures.png
--------------------------------------------------------------------------------
/goals/media/google-play-badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/google-play-badge.png
--------------------------------------------------------------------------------
/goals/media/mutt-match-app-phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/mutt-match-app-phone.png
--------------------------------------------------------------------------------
/goals/media/power-apps-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/power-apps-logo.png
--------------------------------------------------------------------------------
/goals/media/power-automate-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/power-automate-flow.png
--------------------------------------------------------------------------------
/goals/media/power-automate-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/power-automate-logo.png
--------------------------------------------------------------------------------
/goals/media/prediction-key-url-root.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/prediction-key-url-root.png
--------------------------------------------------------------------------------
/goals/media/prediction-key-url.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/prediction-key-url.png
--------------------------------------------------------------------------------
/goals/media/published-iteration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/goals/media/published-iteration.png
--------------------------------------------------------------------------------
/goals/mobile-app.md:
--------------------------------------------------------------------------------
1 | # Goal 2: Build your no/low-code mobile app
2 |
3 | Your team has a trained ML model, and built a Power Automate flow to use it. The final task for your team is to create a Power Apps mobile app to capture an image from the camera and send it to the flow, showing the results.
4 |
5 | ## The no/low-code Service
6 |
7 | [](https://powerapps.microsoft.com/?WT.mc_id=academic-39324-jabenn)
8 |
9 | The tool for building mobile apps with no/low-code is called [Microsoft Power Apps](https://powerapps.microsoft.com/?WT.mc_id=academic-39324-jabenn). You create an application by dragging/dropping controls onto a canvas, then adding code where necessary, such as code to call the Power Automate flow.
10 |
11 | When you create a mobile app, it runs inside the Power Apps host app - you install Power Apps on your phone, then from inside that app you can access all the different apps you develop.
12 |
13 | [](https://aka.ms/powerappsios) [](https://aka.ms/powerappsandroid)
14 |
15 | 
16 |
17 | For this project, you will need to design an app that connects to the phones camera, captures an image on a button tap, sends the image to your Power Automate flow, then displays the result. You can design the app any way you like, taking advantage of all the design features to layout and style your app.
18 |
19 | ## Success criteria
20 |
21 | Your team will work together to build the mobile app and connect it to your Power Automate flow. Your team will have achieved this goal when the following success criteria is met:
22 |
23 | - You have a mobile app with a camera and a button to tap to capture an image
24 |
25 | - The button is connected to your Power Automate flow, sending the image from the camera
26 |
27 | - The results from the Power Automate flow are visible in the app
28 |
29 | - Your app has been saved and shared, and is available in the Power Apps mobile app
30 |
31 | ## Resources
32 |
33 | Your team might find these resources helpful:
34 |
35 | - [Power Apps documentation](https://docs.microsoft.com/power-automate/?WT.mc_id=academic-39324-jabenn)
36 |
37 | - [Camera control in Power Apps documentation](https://docs.microsoft.com/powerapps/maker/canvas-apps/controls/control-camera?WT.mc_id=academic-39324-jabenn)
38 |
39 | - [Button control in Power Apps documentation](https://docs.microsoft.com/powerapps/maker/canvas-apps/controls/control-button?WT.mc_id=academic-39324-jabenn)
40 |
41 | - [Run model-driven apps and canvas apps on Power Apps mobile documentation](https://docs.microsoft.com/powerapps/mobile/run-powerapps-on-mobile?WT.mc_id=academic-39324-jabenn)
42 |
43 | ## Validation
44 |
45 | Have a mentor check your mobile app. They should be able to point your model device at an one of the training images loaded on a screen, select the Detect Breed button, then see the correct breed prediction in the app.
46 |
47 | ## Tips
48 |
49 | - To create a blank app, [create a Canvas app](https://docs.microsoft.com/powerapps/maker/?WT.mc_id=academic-39324-jabenn).
50 |
51 | - You can test your app inside Power Apps, using your computers camera. Either select the **Preview the app** button, or hold the `Alt` key in the designer to test your app.
52 |
53 | - Phones have multiple cameras, so you may want to add a drop down to select between the front and back cameras, or if you only want to use one camera make sure the correct one is selected.
54 |
55 | - The camera control captures photos in one of two ways:
56 |
57 | - When you tap the camera, the `Photo` property is updated
58 |
59 | - You can set the `StreamRate` property to automatically capture images on a regular basis into the `Stream` property.
60 |
61 | To use an image when a button is tapped, it is easiest to use the `Stream` property. This property will only have an image if the `StreamRate` is set to a valid value in milliseconds, such as 100 (100ms means it will capture images 10 times a second).
62 |
63 | - When you add your Power Automate flow to your app, the app will gather information about it, including the return type. You can use this to see the properties on the result, which should be a single property called `breed` with the breed (if you used a different name in the *Respond to a PowerApp or flow* action then this property will match that name).
64 |
65 | - To update a label, set a variable with the result of the call to the Power Automate flow in the buttons `OnSelect` event, and set the label to this variable. Every time the variable is updated, the label will be updated.
66 |
67 | ## Final result
68 |
69 | 
70 |
--------------------------------------------------------------------------------
/goals/train-model.md:
--------------------------------------------------------------------------------
1 | # Goal 0: Train your ML model
2 |
3 | The **Mutt Matcher** app will need to use a machine learning (ML) model to be able to detect different dog breeds in images. The ML model used is an *image classifier* - a model that can classify an image into different *tags* depending on what is in the image. These models are trained by giving them tagged images - multiple images for each tag. For example, you can train a model with images tagged as `cat`, and images tagged as `dog`. The model can then be given a new image and it will predict if the image should be a `cat` or a `dog`.
4 |
5 | A typical image classifier needs many thousands if not millions of images to train, but you can take a shortcut using a technique called *transfer learning*. Transfer learning allows to take an image classifier trained on a wide range of tags, then re-train it using a small number of images for your tags.
6 |
7 | Your team will use a cloud service that uses transfer learning to train an ML model to identify different dog breeds using images provided by the fictional animal shelter. These training images consist of a number of images of a range of breeds. You would use these to train the model, using the breed as the tag.
8 |
9 | > ⏱ Training a model can take a while, so you can work on this concurrently with the other goals in the workshop.
10 |
11 | ## The Azure Service
12 |
13 | [](https://customvision.ai?WT.mc_id=academic-39324-jabenn)
14 |
15 | The transfer learning service to use is [Custom Vision](https://customvision.ai?WT.mc_id=academic-39324-jabenn). This is a service from Microsoft that can train image classifiers using only a small number of images for each tag. Once your model has been trained, it can be published to be run in the cloud, using one of the Custom Vision SDKs for programming languages such as Python, Java or C#, via a REST API, or access from Power Automate using a Custom Vision connection. You can also download your model and run it locally on an IoT device, a web page, or in an application.
16 |
17 | 
18 |
19 | Image classifiers don't give a single fixed answer of the detected tag, instead they provide a list of all the tags that the model has been trained on with the probability that the image matches that tag. In the image above, the results show values against each tag:
20 |
21 | | Tag | Probability |
22 | | ------------------------------ | ----------: |
23 | | american-staffordshire-terrier | 69.8% |
24 | | german-wirehaired-pointer | 28.2% |
25 | | buggle | 1.6% |
26 | | shorkie | 0.2% |
27 | | australian-shepherd | 0.0% |
28 |
29 | To use Custom Vision, you will need an [Azure for Students subscription](https://azure.microsoft.com/free/students/?WT.mc_id=academic-39324-jabenn). Custom Vision has a generous free tier, so this workshop will not use any of your Azure credit.
30 |
31 | ## Image files
32 |
33 | The images you can use to train your model are in the [model-images](https://github.com/microsoft/hack-workshop-power-apps/tree/main/model-images) folder. You will need to clone the [Hack Workshops Power Apps GitHub repo](https://github.com/microsoft/hack-workshop-power-apps) (or download it as a zip file) to access these images. The images are in 2 different folders:
34 |
35 | - [training-images](https://github.com/microsoft/hack-workshop-power-apps/tree/main/model-images/training-images) - these are the images to use to train the model. The filename contains the tag for the image, along with a number to make the files uniquely named. For example, `american-staffordshire-terrier-1.jpg`, `american-staffordshire-terrier-1.jpg`, and `american-staffordshire-terrier-3.jpg` are all images for the tag `american-staffordshire-terrier`.
36 |
37 | - [testing-images](https://github.com/microsoft/hack-workshop-power-apps/tree/main/model-images/testing-images) - these are images you can use to test the image classifier once it is trained. These are different from the training images.
38 |
39 | > ⚠️ It is important that when you tag these images, you use the tag from the file name. This will allow teh validation script to work.
40 |
41 | ## Success criteria
42 |
43 | Your team will work together to train the ML model using the training images, then test it with the testing images. Your team will have achieved this goal when the following success criteria is met:
44 |
45 | - Your model has been trained on all the images in the `training-images` folder.
46 |
47 | - You have verified that the `testing-images` have the correct tags detected as the highest probability tag using the *Quick test* button.
48 |
49 | - Your model has a published iteration.
50 |
51 | ## Validation
52 |
53 | You can validate your model using a Python script inside this repo.
54 |
55 | 1. From wherever you cloned this repo, navigate to the `validation` folder.
56 |
57 | 1. Create and activate a Python 3 virtual environment. If you've not done this before, you can refer to the [Python creation of virtual environments documentation](https://docs.python.org/3/library/venv.html).
58 |
59 | 1. Install the Pip packages in the `requirements.txt` file using the following command from inside the activated virtual environment:
60 |
61 | ```sh
62 | pip install -r requirements.txt
63 | ```
64 |
65 | 1. Run the validation script using the following command:
66 |
67 | ```sh
68 | python validate-model.py
69 | ```
70 |
71 | 1. When prompted, enter the prediction key and the image file URL for your published model iteration. You can get these from the prediction API dialog from the **Prediction URL** button of the published iteration. You then need the *Image file* url and prediction key.
72 |
73 | 
74 |
75 | This validation script will take the testing images, and test them against the model to ensure the correct tag is found as the most probable. You will see output like the following:
76 |
77 | ```output
78 | (.venv) ➜ validation git:(main) ✗ python validate-model.py
79 | ML model validation
80 |
81 | What is your prediction key?
82 | xxxxxxxxxxxxxxxxxxxxxxxxxxxx
83 | What is your prediction URL?
84 | https://xxxxxxx.cognitiveservices.azure.com/customvision/v3.0/Prediction/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/classify/iterations/Iteration1/image
85 | ..........
86 | Validation passed!
87 | ```
88 |
89 | ## Resources
90 |
91 | Your team might find these resources helpful:
92 |
93 | - [Quickstart: Build a classifier with the Custom Vision website](https://docs.microsoft.com/azure/cognitive-services/custom-vision-service/getting-started-build-a-classifier?WT.mc_id=academic-39324-jabenn)
94 |
95 | - [Use your model with the prediction API](https://docs.microsoft.com/azure/cognitive-services/custom-vision-service/use-prediction-api?WT.mc_id=academic-39324-jabenn)
96 |
97 | - [Classify images learning module on Microsoft Learn](https://docs.microsoft.com/learn/modules/classify-images/?WT.mc_id=academic-39324-jabenn)
98 |
99 | ## Tips
100 |
101 | - When you create the training and prediction resource, use the **Free F0** tier, as this is free to use!
102 |
103 | - You **MUST** set the tags to be the breed name from the image file name. The validation script assumes this is the case.
104 |
105 | - When you train, use *Quick training*.
106 |
107 | - The training can take a while - even with quick training, so whilst your model is training, work on the other goals.
108 |
109 | ## Final result
110 |
111 | 
112 |
113 | ## Next challenge
114 |
115 | The next goal is to [build your no-code back end](back-end.md).
116 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | # Project information
2 | site_name: Microsoft Power Apps Workshop
3 | site_url: https://microsoft.github.io/hack-workshop-power-apps/
4 | site_author: Microsoft
5 | site_description: >-
6 | Learn to build an low code mobile app to detect dog breeds using Azure!
7 |
8 | # Repository
9 | repo_name: microsoft/hack-workshop-power-apps
10 | repo_url: https://github.com/microsoft/hack-workshop-power-apps
11 |
12 | copyright: Copyright © Microsoft
13 |
14 | # Project structure
15 | docs_dir: goals
16 |
17 | # Customizations & theme
18 | extra_css:
19 | - assets/stylesheets/extra.css
20 |
21 | extra:
22 | social:
23 | - icon: fontawesome/brands/github
24 | link: https://github.com/microsoft
25 | name: Microsoft on GitHub
26 | - icon: fontawesome/brands/linkedin
27 | link: https://linkedin.com/in/Microsoft/
28 | name: Microsoft on LinkedIn
29 | - icon: fontawesome/brands/twitter
30 | link: https://twitter.com/Microsoft
31 | name: Microsoft on Twitter
32 | tos:
33 | - link: https://privacy.microsoft.com/
34 | name: Privacy
35 | - link: https://www.microsoft.com/en-us/legal/terms-of-use
36 | name: Terms of Use
37 | - link: https://github.com/microsoft/hack-workshop-power-apps/blob/main/LICENSE
38 | name: License
39 |
40 | theme:
41 | name: material
42 | custom_dir: theme
43 | features:
44 | - navigation.indexes
45 | - navigation.instant
46 | - navigation.expand
47 | - navigation.top
48 | - toc.integrate
49 | font: false
50 | logo: assets/images/8_BIT.png
51 | palette:
52 | - media: "(prefers-color-scheme: light)"
53 | scheme: default
54 | primary: teal
55 | accent: teal
56 | toggle:
57 | icon: material/weather-night
58 | name: Switch to dark mode
59 | - media: "(prefers-color-scheme: dark)"
60 | scheme: slate
61 | primary: teal
62 | accent: teal
63 | toggle:
64 | icon: material/weather-sunny
65 | name: Switch to light mode
66 |
67 | # Extensions
68 | markdown_extensions:
69 | - admonition
70 | - attr_list
71 | - pymdownx.highlight
72 | - pymdownx.superfences
73 | - pymdownx.snippets
74 | - smarty
75 | - toc:
76 | permalink: True
77 |
78 | # Plugins
79 | plugins:
80 | - include-markdown
81 |
82 | # Navigation
83 | nav:
84 | - Overview: 'index.md'
85 | - 'Goals':
86 | - 'train-model.md'
87 | - 'back-end.md'
88 | - 'mobile-app.md'
89 |
--------------------------------------------------------------------------------
/model-images/testing-images/american-staffordshire-terrier-10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/american-staffordshire-terrier-10.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/american-staffordshire-terrier-9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/american-staffordshire-terrier-9.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/australian-shepherd-10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/australian-shepherd-10.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/australian-shepherd-9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/australian-shepherd-9.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/buggle-10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/buggle-10.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/buggle-9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/buggle-9.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/german-wirehaired-pointer-10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/german-wirehaired-pointer-10.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/german-wirehaired-pointer-9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/german-wirehaired-pointer-9.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/shorkie-14.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/shorkie-14.jpg
--------------------------------------------------------------------------------
/model-images/testing-images/shorkie-15.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/testing-images/shorkie-15.jpg
--------------------------------------------------------------------------------
/model-images/training-images/american-staffordshire-terrier-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/american-staffordshire-terrier-1.jpg
--------------------------------------------------------------------------------
/model-images/training-images/american-staffordshire-terrier-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/american-staffordshire-terrier-2.jpg
--------------------------------------------------------------------------------
/model-images/training-images/american-staffordshire-terrier-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/american-staffordshire-terrier-3.jpg
--------------------------------------------------------------------------------
/model-images/training-images/american-staffordshire-terrier-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/american-staffordshire-terrier-4.jpg
--------------------------------------------------------------------------------
/model-images/training-images/american-staffordshire-terrier-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/american-staffordshire-terrier-5.jpg
--------------------------------------------------------------------------------
/model-images/training-images/american-staffordshire-terrier-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/american-staffordshire-terrier-6.jpg
--------------------------------------------------------------------------------
/model-images/training-images/american-staffordshire-terrier-7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/american-staffordshire-terrier-7.jpg
--------------------------------------------------------------------------------
/model-images/training-images/american-staffordshire-terrier-8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/american-staffordshire-terrier-8.jpg
--------------------------------------------------------------------------------
/model-images/training-images/australian-shepherd-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/australian-shepherd-1.jpg
--------------------------------------------------------------------------------
/model-images/training-images/australian-shepherd-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/australian-shepherd-2.jpg
--------------------------------------------------------------------------------
/model-images/training-images/australian-shepherd-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/australian-shepherd-3.jpg
--------------------------------------------------------------------------------
/model-images/training-images/australian-shepherd-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/australian-shepherd-4.jpg
--------------------------------------------------------------------------------
/model-images/training-images/australian-shepherd-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/australian-shepherd-5.jpg
--------------------------------------------------------------------------------
/model-images/training-images/australian-shepherd-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/australian-shepherd-6.jpg
--------------------------------------------------------------------------------
/model-images/training-images/australian-shepherd-7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/australian-shepherd-7.jpg
--------------------------------------------------------------------------------
/model-images/training-images/australian-shepherd-8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/australian-shepherd-8.jpg
--------------------------------------------------------------------------------
/model-images/training-images/buggle-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/buggle-1.jpg
--------------------------------------------------------------------------------
/model-images/training-images/buggle-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/buggle-2.jpg
--------------------------------------------------------------------------------
/model-images/training-images/buggle-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/buggle-3.jpg
--------------------------------------------------------------------------------
/model-images/training-images/buggle-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/buggle-4.jpg
--------------------------------------------------------------------------------
/model-images/training-images/buggle-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/buggle-5.jpg
--------------------------------------------------------------------------------
/model-images/training-images/buggle-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/buggle-6.jpg
--------------------------------------------------------------------------------
/model-images/training-images/buggle-7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/buggle-7.jpg
--------------------------------------------------------------------------------
/model-images/training-images/buggle-8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/buggle-8.jpg
--------------------------------------------------------------------------------
/model-images/training-images/german-wirehaired-pointer-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/german-wirehaired-pointer-1.jpg
--------------------------------------------------------------------------------
/model-images/training-images/german-wirehaired-pointer-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/german-wirehaired-pointer-2.jpg
--------------------------------------------------------------------------------
/model-images/training-images/german-wirehaired-pointer-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/german-wirehaired-pointer-3.jpg
--------------------------------------------------------------------------------
/model-images/training-images/german-wirehaired-pointer-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/german-wirehaired-pointer-4.jpg
--------------------------------------------------------------------------------
/model-images/training-images/german-wirehaired-pointer-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/german-wirehaired-pointer-5.jpg
--------------------------------------------------------------------------------
/model-images/training-images/german-wirehaired-pointer-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/german-wirehaired-pointer-6.jpg
--------------------------------------------------------------------------------
/model-images/training-images/german-wirehaired-pointer-7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/german-wirehaired-pointer-7.jpg
--------------------------------------------------------------------------------
/model-images/training-images/german-wirehaired-pointer-8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/german-wirehaired-pointer-8.jpg
--------------------------------------------------------------------------------
/model-images/training-images/golden-doodle-5.jfif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/golden-doodle-5.jfif
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-1.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-10.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-11.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-12.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-13.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-2.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-3.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-4.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-5.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-6.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-7.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-8.jpg
--------------------------------------------------------------------------------
/model-images/training-images/shorkie-9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/model-images/training-images/shorkie-9.jpg
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | mkdocs
2 | mkdocs-material
3 | mkdocs-include-markdown-plugin
4 |
--------------------------------------------------------------------------------
/theme/assets/images/8_BIT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/theme/assets/images/8_BIT.png
--------------------------------------------------------------------------------
/theme/assets/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/theme/assets/images/favicon.ico
--------------------------------------------------------------------------------
/theme/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/theme/assets/images/favicon.png
--------------------------------------------------------------------------------
/theme/assets/images/icon_garage_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/hack-workshop-power-apps/0a0441079efa8b710e4e1977cd843c90394684ea/theme/assets/images/icon_garage_white.png
--------------------------------------------------------------------------------
/theme/assets/stylesheets/extra.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "SegoeUI";
3 | src: local("Segoe UI"),
4 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.woff2")
5 | format("woff2"),
6 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.woff")
7 | format("woff"),
8 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.ttf")
9 | format("ttf");
10 | font-weight: 400;
11 | }
12 |
13 | @font-face {
14 | font-family: "SegoeUI";
15 | src: local("Segoe UI"),
16 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/italic/latest.woff2")
17 | format("woff2"),
18 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/italic/latest.woff")
19 | format("woff"),
20 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/italic/latest.ttf")
21 | format("ttf");
22 | font-weight: 400;
23 | font-style: italic;
24 | }
25 |
26 | @font-face {
27 | font-family: "SegoeUI";
28 | src: local("Segoe UI"),
29 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/Semilight/latest.woff2")
30 | format("woff2"),
31 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/Semilight/latest.woff")
32 | format("woff"),
33 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/Semilight/latest.ttf")
34 | format("ttf");
35 | font-weight: 300;
36 | }
37 |
38 | @font-face {
39 | font-family: "SegoeUI";
40 | src: local("Segoe UI"),
41 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/Bold/latest.woff2")
42 | format("woff2"),
43 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/Bold/latest.woff")
44 | format("woff"),
45 | url("//c.s-microsoft.com/static/fonts/segoe-ui/west-european/Bold/latest.ttf")
46 | format("ttf");
47 | font-weight: 700;
48 | }
49 |
50 | :root {
51 | --md-text-font-family: "Segoe UI", "SegoeUI","Helvetica Neue",Helvetica,Arial,sans-serif;
52 | }
53 |
54 | [data-md-color-primary=teal] {
55 | --md-primary-fg-color: #004D40;
56 | --md-primary-fg-color--light: #80CBC4;
57 | --md-primary-fg-color--dark: #007a6c;
58 | --md-primary-bg-color: #fff;
59 | --md-primary-bg-color--light: hsla(0,0%,100%,0.7);
60 | }
61 |
62 | [data-md-color-scheme=slate] {
63 | --md-typeset-a-color: var(--md-primary-fg-color--light);
64 | }
65 |
66 | figcaption {
67 | max-width: 80% !important;
68 | }
69 |
70 | [class$="__repository"]{
71 | overflow: unset;
72 | }
73 |
74 | [class $="tos__link"]{
75 | padding-right: 0.25rem;
76 | }
--------------------------------------------------------------------------------
/theme/partials/footer.html:
--------------------------------------------------------------------------------
1 | {% import "partials/language.html" as lang with context %}
2 |
3 |
4 |
93 |
--------------------------------------------------------------------------------
/theme/partials/tos.html:
--------------------------------------------------------------------------------
1 |
2 | {% if config.extra.tos %}
3 | {% for tos in config.extra.tos %}
4 | {% set title = tos.name %}
5 | {% if not title and "//" in tos.link %}
6 | {% set _,url = tos.link.split("//") %}
7 | {% set title = url.split("/")[0] %}
8 | {% endif %}
9 |
17 |
18 | {% endfor %}
19 | {% endif %}
--------------------------------------------------------------------------------
/validation/requirements.txt:
--------------------------------------------------------------------------------
1 | azure-cognitiveservices-vision-customvision
2 | azure-iot-device
3 | requests
--------------------------------------------------------------------------------
/validation/validate-model.py:
--------------------------------------------------------------------------------
1 | import os
2 | from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
3 | from msrest.authentication import ApiKeyCredentials
4 |
5 | print('ML model validation')
6 | print()
7 |
8 | # Get the users prediction key and URL
9 | print('What is your prediction key?')
10 | prediction_key = input().strip()
11 | print('What is your prediction URL?')
12 | prediction_url = input().strip()
13 |
14 | # Decompose the prediction URL
15 | parts = prediction_url.split('/')
16 | endpoint = 'https://' + parts[2]
17 | project_id = parts[6]
18 | iteration_name = parts[9]
19 |
20 | # Create the image classifier predictor
21 | prediction_credentials = ApiKeyCredentials(in_headers={'Prediction-key': prediction_key})
22 | predictor = CustomVisionPredictionClient(endpoint, prediction_credentials)
23 |
24 | directory = '../model-images/testing-images'
25 |
26 | pass_count = 0
27 | fail_count = 0
28 |
29 | for entry in os.scandir(directory):
30 | tag = entry.name[:entry.name.rfind('-')]
31 |
32 | with open(entry.path, 'rb') as image:
33 | results = predictor.classify_image(project_id, iteration_name, image)
34 |
35 | best_prediction = results.predictions[0]
36 |
37 | if best_prediction.tag_name == tag:
38 | pass_count += 1
39 | else:
40 | fail_count += 1
41 |
42 | print()
43 |
44 | if fail_count > 0:
45 | print('Validation failed - please check your model')
46 | else:
47 | print('Validation passed!')
48 |
--------------------------------------------------------------------------------