Skip to content

Commit 7ab1daf

Browse files
committed
[AI tutorials] - create tutorials for YOLOv7
1 parent 549a89b commit 7ab1daf

File tree

5 files changed

+405
-0
lines changed

5 files changed

+405
-0
lines changed
Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
---
2+
title: AI Deploy - Tutorial - Create a web service to recognize sign language with YOLOv7
3+
slug: deploy/tuto-streamlit-yolov7-sign-language
4+
excerpt: How to build a sign language recognition app with Streamlit
5+
section: AI Deploy - Tutorials
6+
order: 13
7+
updated: 2023-03-31
8+
---
9+
10+
**Last updated 31th March, 2023.**
11+
12+
## Objective
13+
14+
The purpose of this tutorial is to show how to deploy a web service to recognize **Amercian Sign Language letters** using YOLOv7 model.
15+
16+
In order to do this, you will use [Streamlit](https://streamlit.io/), a Python framework that turns scripts into a shareable web application. You will also learn how to build and use a custom Docker image for a Streamlit application.
17+
18+
For more information on how to train YOLOv7 on a custom dataset, refer to the following [documentation](https://docs.ovh.com/gb/en/publiccloud/ai/notebooks/yolov7-sign-language/).
19+
20+
Overview of the Sign Language recognition app:
21+
22+
![Overview](images/overview-streamlit-yolov7-asl.png){.thumbnail}
23+
24+
## Requirements
25+
26+
- access to the [OVHcloud Control Panel](https://www.ovh.com/auth/?action=gotomanager&from=https://www.ovh.co.uk/&ovhSubsidiary=GB)
27+
- an AI Deploy project created inside a Public Cloud project
28+
- a [user for AI Deploy](https://docs.ovh.com/gb/en/publiccloud/ai/users)
29+
- [Docker](https://www.docker.com/get-started) installed on your local computer
30+
- some knowledge about building image and [Dockerfile](https://docs.docker.com/engine/reference/builder/)
31+
- your weights obtained from training YOLOv7 model on the [ASL letters dataset](https://public.roboflow.com/object-detection/american-sign-language-letters/1) (refer to the *"Export trained weights for future inference"* part of the [notebook for YOLOv7](https://github.com/ovh/ai-training-examples/blob/main/notebooks/computer-vision/object-detection/miniconda/yolov7/notebook_object_detection_yolov7_asl.ipynb)
32+
33+
## Instructions
34+
35+
You are going to follow different steps to build your Streamlit application.
36+
37+
- More information about Streamlit capabilities can be found [here](https://docs.streamlit.io/en/stable/).
38+
- Direct link to the full Python script can be found [here](https://github.com/ovh/ai-training-examples/blob/main/apps/streamlit/sign-language-recognition-yolov7-app/main.py).
39+
40+
> **Warning**
41+
> You must have previously created an `asl-volov7-model` Object Storage container when training your model via [AI Notebooks](https://docs.ovh.com/gb/en/publiccloud/ai/notebooks/yolov7-sign-language/).
42+
>
43+
> Check that this container contains your **YOLOv7 custom weights**. They will be necessary for the deployment of the app!
44+
45+
Here we will mainly discuss how to write the `main.py` code, the `requirements.txt` file and the `Dockerfile`. If you want to see the whole code, please refer to the [GitHub](https://github.com/ovh/ai-training-examples/tree/main/apps/streamlit/sign-language-recognition-yolov7-app) repository.
46+
47+
### Write the Streamlit application
48+
49+
Create a Python file named `main.py`.
50+
51+
Inside that file, import your required modules:
52+
53+
```python
54+
import streamlit as st
55+
from PIL import Image
56+
import numpy as np
57+
import torch
58+
import cv2
59+
import io
60+
import os
61+
```
62+
63+
Load the **YOLOv7** model and your own weights. Put this function it in **cache**:
64+
65+
```python
66+
@st.cache
67+
def load_model():
68+
69+
custom_yolov7_model = torch.hub.load("WongKinYiu/yolov7", 'custom', '/workspace/asl-volov7-model/yolov7.pt')
70+
71+
return custom_yolov7_model
72+
```
73+
74+
Create the inference function to get prediction:
75+
76+
```python
77+
def get_prediction(img_bytes, model):
78+
79+
img = Image.open(io.BytesIO(img_bytes))
80+
results = model(img, size=640)
81+
82+
return results
83+
```
84+
85+
Write the image analysis function:
86+
87+
```python
88+
def analyse_image(image, model):
89+
90+
if image is not None:
91+
92+
img = Image.open(image)
93+
bytes_data = image.getvalue()
94+
img_bytes = np.asarray(bytearray(bytes_data), dtype=np.uint8)
95+
result = get_prediction(img_bytes, model)
96+
result.render()
97+
98+
for img in result.imgs:
99+
RGB_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
100+
im_arr = cv2.imencode('.jpg', RGB_img)[1]
101+
st.image(im_arr.tobytes())
102+
103+
result_list = list((result.pandas().xyxy[0])["name"])
104+
105+
else:
106+
st.write("no asl letters were detected!")
107+
result_list = []
108+
109+
return result_list
110+
```
111+
112+
Define the Python function that displays the letters and forms a word:
113+
114+
```python
115+
def display_letters(letters_list):
116+
117+
word = ''.join(letters_list)
118+
path_file = "/workspace/word_file.txt"
119+
with open(path_file, "a") as f:
120+
f.write(word)
121+
122+
return path_file
123+
```
124+
125+
Define the main and start your app:
126+
127+
```python
128+
if __name__ == '__main__':
129+
130+
st.image("/workspace/head-asl-yolov7-app.png")
131+
st.write("## Welcome on your ASL letters recognition app!")
132+
133+
model = load_model()
134+
135+
img_file_buffer = st.camera_input("Take your picture in real time:")
136+
137+
result_list = analyse_image(img_file_buffer, model)
138+
path_file = display_letters(result_list)
139+
140+
if st.button("Clear result"):
141+
if os.path.isfile(path_file):
142+
os.remove(path_file)
143+
print("File has been deleted")
144+
else:
145+
print("File does not exist")
146+
147+
if (os.path.exists(path_file)==True):
148+
with open(path_file, "r") as f:
149+
content = f.read()
150+
st.write(content)
151+
f.close()
152+
else:
153+
pass
154+
```
155+
156+
### Write the requirements.txt file for the application
157+
158+
The `requirements.txt` file will allow us to write all the modules needed to make our application work. This file will be useful when writing the `Dockerfile`.
159+
160+
```console
161+
torchvision==0.14.0
162+
numpy==1.23.4
163+
pandas==1.5.1
164+
matplotlib==3.6.2
165+
pillow==9.3.0
166+
opencv-python-headless==4.6.0.66
167+
streamlit==1.14.0
168+
tqdm==4.64.1
169+
seaborn==0.12.1
170+
scipy==1.9.3
171+
ipython==8.6.0
172+
psutil==5.9.4
173+
pyyaml==6.0
174+
```
175+
176+
### Write the Dockerfile for the application
177+
178+
Your Dockerfile should start with the the `FROM` instruction indicating the parent image to use. In our case we choose to start from a `python:3.8` image:
179+
180+
```console
181+
FROM python:3.8
182+
```
183+
184+
Create the home directory and add your files to it:
185+
186+
```console
187+
WORKDIR /workspace
188+
ADD . /workspace
189+
```
190+
191+
Install the `requirements.txt` file which contains your needed Python modules using a `pip install ...` command:
192+
193+
```console
194+
RUN pip install -r requirements.txt
195+
```
196+
197+
Define your default launching command to start the application:
198+
199+
```console
200+
CMD [ "streamlit" , "run" , "/workspace/main.py", "--server.address=0.0.0.0" ]
201+
```
202+
203+
Give correct access rights to **ovhcloud user** (`42420:42420`):
204+
205+
```console
206+
RUN chown -R 42420:42420 /workspace
207+
ENV HOME=/workspace
208+
```
209+
210+
### Build the Docker image from the Dockerfile
211+
212+
Launch the following command from the **Dockerfile** directory to build your application image:
213+
214+
```console
215+
docker build . -t yolov7-streamlit-asl-recognition:latest
216+
```
217+
218+
> **Note**
219+
> The dot `.` argument indicates that your build context (place of the **Dockerfile** and other needed files) is the current directory.
220+
221+
> **Note**
222+
> The `-t` argument allows you to choose the identifier to give to your image. Usually image identifiers are composed of a **name** and a **version tag** `<name>:<version>`. For this example we chose **yolov7-streamlit-asl-recognition:latest**.
223+
224+
### Test it locally (optional)
225+
226+
Launch the following **Docker command** to launch your application locally on your computer:
227+
228+
```console
229+
docker run --rm -it -p 8501:8051 --user=42420:42420 yolov7-streamlit-asl-recognition:latest
230+
```
231+
232+
> **Note**
233+
> The `-p 8501:8501` argument indicates that you want to execute a port redirection from the port **8501** of your local machine into the port **8501** of the Docker container. The port **8501** is the default port used by **Streamlit** applications.
234+
235+
> **Note**
236+
> Don't forget the `--user=42420:42420` argument if you want to simulate the exact same behaviour that will occur on **AI Deploy apps**. It executes the Docker container as the specific OVHcloud user (user **42420:42420**).
237+
238+
Once started, your application should be available on `http://localhost:8501`.
239+
240+
### Push the image into the shared registry
241+
242+
> **Warning**
243+
> The shared registry of AI Deploy should only be used for testing purpose. Please consider attaching your own Docker registry. More information about this can be found [here](https://docs.ovh.com/gb/en/publiccloud/ai/training/add-private-registry).
244+
245+
Find the adress of your shared registry by launching this command:
246+
247+
```console
248+
ovhai registry list
249+
```
250+
251+
Login on the shared registry with your usual openstack credentials:
252+
253+
```console
254+
docker login -u <user> -p <password> <shared-registry-address>
255+
```
256+
257+
Push the compiled image into the shared registry:
258+
259+
```console
260+
docker tag yolov7-streamlit-asl-recognition:latest <shared-registry-address>/yolov7-streamlit-asl-recognition:latest
261+
docker push <shared-registry-address>/yolov7-streamlit-asl-recognition:latest
262+
```
263+
264+
### Launch the AI Deploy app
265+
266+
The following command starts a new app running your Streamlit application:
267+
268+
```console
269+
ovhai app run <shared-registry-address>/yolov7-streamlit-asl-recognition:latest \
270+
--gpu 1 \
271+
--default-http-port 8501 \
272+
--volume asl-volov7-model@GRA/:/workspace/asl-volov7-model:RO
273+
```
274+
275+
> **Note**
276+
> `--default-http-port 8501` indicates that the port to reach on the app URL is the `8501`.
277+
278+
> **Note**
279+
> `--gpu 1` indicates that we request 4 CPUs for that app.
280+
281+
> **Note**
282+
> Consider adding the `--unsecure-http` attribute if you want your application to be reachable without any authentication.
283+
284+
## Go further
285+
286+
- You can imagine deploying an app using YOLO models with an other Python framework: **Flask**. Refer to this [tutorial](https://docs.ovh.com/gb/en/publiccloud/ai/deploy/web-service-yolov5/).
287+
- Feel free to use **Streamlit** for other AI tasks! Deploy a Speech-to-Text app [here](https://docs.ovh.com/gb/en/publiccloud/ai/deploy/tuto-streamlit-speech-to-text-app/).
770 KB
Loading

0 commit comments

Comments
 (0)