AsusHP commited on
Commit
629e738
·
1 Parent(s): 0745bc9

first commit

Browse files
app ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+ RUN apt-get update && apt-get install -y libgl1-mesa-glx
4
+
5
+ WORKDIR /app
6
+
7
+ COPY ./deploy /app
8
+
9
+ RUN pip install --no-cache-dir -r requirements.txt
10
+
11
+ CMD ["python", "app.py", "--host", "0.0.0.0", "--port", "7860"]
deploy/app.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #Import Library
2
+ from flask import Flask, request, jsonify, render_template, send_from_directory
3
+ import os
4
+ from tensorflow import keras
5
+ from keras.models import load_model
6
+
7
+ #Import functions and model
8
+ from functions import predict
9
+
10
+ model = load_model('model_mnist.h5')
11
+
12
+ app = Flask('meu app', template_folder='templates')
13
+
14
+ @app.route('/')
15
+ def index():
16
+ return render_template('webpage.html')
17
+
18
+ @app.route('/static/<path:filename>')
19
+ def serve_static(filename):
20
+ return send_from_directory(os.path.join(app.root_path, 'static'), filename)
21
+
22
+ @app.route('/process_drawing', methods=['POST'])
23
+ def process_drawing():
24
+
25
+ data = request.json
26
+ image_data = data.get("imageData")
27
+
28
+ if image_data:
29
+
30
+ value_1, value_2 = predict(image_data, model)
31
+
32
+ response = {
33
+ "value_1": value_1,
34
+ "value_2": value_2
35
+ }
36
+
37
+ return jsonify(response)
38
+
39
+ return jsonify({"response": "Erro: Dados de imagem não recebidos."})
40
+
41
+ if __name__ == '__main__':
42
+ app.run()
deploy/functions.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import cv2
3
+ import base64
4
+ from PIL import Image
5
+ import io
6
+
7
+ def predict(image_input, model):
8
+
9
+ image_data_bytes = base64.b64decode(image_input)
10
+
11
+ image_stream = io.BytesIO(image_data_bytes)
12
+
13
+ image_pil = Image.open(image_stream)
14
+
15
+ image_np = np.array(image_pil)
16
+
17
+ image = cv2.resize(image_np, (28,28))[:, :, 3]
18
+
19
+ resized_image = image / 255.0
20
+
21
+ input_image = np.expand_dims(resized_image, axis=0)
22
+
23
+ predicted_probabilities = model.predict(input_image)
24
+
25
+ predicted_labels = np.argmax(predicted_probabilities, axis=1)
26
+
27
+ return predicted_labels[0].astype(str), np.around(predicted_probabilities.max()*100,3).astype(str)
deploy/model_mnist.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9235d310f346384d3f068edd3c096612d4a846bb8a7d2173cc50e650279f5d9c
3
+ size 5493688
deploy/requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ #Let's install all the necessary libraries, specifying their versions
2
+ Flask==2.2.2
3
+ Werkzeug==2.2.2
4
+ tensorflow==2.12.0
5
+ opencv-python==4.8.1.78
6
+ numpy==1.23.1
7
+ Pillow==9.3.0
deploy/static/script.js ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var canvas = document.getElementById('drawingCanvas');
2
+ var context = canvas.getContext('2d');
3
+ var isDrawing = false;
4
+
5
+ // Define a grossura da linha
6
+ context.lineWidth = 14.5; // Altere para o valor desejado em pixels
7
+
8
+ canvas.addEventListener('mousedown', function(e) {
9
+ isDrawing = true;
10
+ context.beginPath();
11
+ context.moveTo(e.clientX - canvas.getBoundingClientRect().left, e.clientY - canvas.getBoundingClientRect().top);
12
+ });
13
+
14
+ canvas.addEventListener('mousemove', function(e) {
15
+ if (!isDrawing) return;
16
+ context.lineTo(e.clientX - canvas.getBoundingClientRect().left, e.clientY - canvas.getBoundingClientRect().top);
17
+ context.stroke();
18
+ });
19
+
20
+ canvas.addEventListener('mouseup', function() {
21
+ isDrawing = false;
22
+ });
23
+
24
+ document.getElementById("clearCanvas").addEventListener("click", function() {
25
+ var canvas = document.getElementById("drawingCanvas");
26
+ var context = canvas.getContext("2d");
27
+
28
+ // Limpa o canvas preenchendo-o com uma cor de fundo (pode ser branco)
29
+ context.fillStyle = "white"; // Altere a cor de fundo desejada
30
+ context.clearRect(0, 0, canvas.width, canvas.height);
31
+
32
+ // Você pode adicionar outras ações de limpeza, se necessário
33
+ });
34
+
35
+ document.getElementById("sendDrawing").addEventListener("click", function() {
36
+
37
+ // Obtenha a imagem em base64
38
+ var imageDataURL = canvas.toDataURL("image/png");
39
+
40
+ // Verifique se a imagem base64 contém dados
41
+ if (imageDataURL.indexOf("base64,") === -1) {
42
+ alert("Desenhe algo no canvas antes de enviar.");
43
+ return;
44
+ }
45
+
46
+ // Remova o prefixo "data:image/png;base64,"
47
+ var base64Data = imageDataURL.replace(/^data:image\/(png|jpeg);base64,/, "");
48
+
49
+ // Adicione padding de acordo com o comprimento da string
50
+ while (base64Data.length % 4 !== 0) {
51
+ base64Data += "=";
52
+ }
53
+
54
+ var xhr = new XMLHttpRequest();
55
+
56
+ xhr.open("POST", "/process_drawing", true);
57
+ xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
58
+ var data = JSON.stringify({ "imageData": base64Data });
59
+ xhr.send(data);
60
+
61
+ xhr.onload = function() {
62
+ if (xhr.status === 200) {
63
+
64
+ var response = JSON.parse(xhr.responseText);
65
+
66
+ var value_1 = response.value_1;
67
+ var value_2 = response.value_2;
68
+
69
+ document.getElementById("digitoValor").textContent = value_1;
70
+ document.getElementById("probabilidadeValor").textContent = value_2;
71
+
72
+ } else {
73
+
74
+ document.getElementById("responseText").textContent = "Erro na solicitação.";
75
+ }
76
+ };
77
+ });
deploy/static/styles.css ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ margin: 0;
3
+ padding: 0;
4
+ display: flex;
5
+ flex-direction: column;
6
+ font-family: Arial, sans-serif;
7
+ background: linear-gradient(to bottom, #FF66A3, #007BFF);
8
+ background-repeat: no-repeat;
9
+ background-attachment: fixed;
10
+ background-size: cover;
11
+ background-position: center;
12
+ color: #333;
13
+ height: 100vh;
14
+ }
15
+
16
+ header {
17
+ /* background-color: #1f1f1f; */
18
+ color: #fff;
19
+ text-align: center;
20
+ padding: 0px 0;
21
+ }
22
+
23
+ #button-container {
24
+ text-align: center;
25
+ }
26
+
27
+ #button-container, #drawingCanvas{
28
+ flex-direction: column;
29
+ margin: 5px;
30
+ }
31
+
32
+ #sendDrawing, #clearCanvas {
33
+ display: inline-block;
34
+ margin: 10px; /* Espaçamento entre os botões */
35
+ padding: 10px 20px; /* Espaçamento interno dos botões */
36
+ background-color: #1265e0; /* Cor de fundo do botão */
37
+ color: #fff; /* Cor do texto do botão */
38
+ border: none;
39
+ border-radius: 5px;
40
+ cursor: pointer;
41
+ transition: background-color 0.3s; /* Efeito de transição de cor ao passar o mouse */
42
+ }
43
+
44
+ #sendDrawing:hover, #clearCanvas:hover {
45
+ background-color: #023d7c; /* Cor do botão ao passar o mouse */
46
+ }
47
+
48
+ #textbox-container {
49
+ text-align: center;
50
+ margin-top: 20px; /* Espaçamento acima dos elementos de texto */
51
+ }
52
+
53
+ #bigChar {
54
+ font-size: 40px; /* Tamanho grande para o caracter */
55
+ margin-bottom: 10px; /* Espaçamento abaixo do caracter */
56
+ }
57
+
58
+ #number {
59
+ font-size: 24px; /* Tamanho do número */
60
+ }
61
+
62
+ .grid-container {
63
+ display: flex;
64
+ flex-direction: column;
65
+ align-items: center;
66
+ }
67
+
68
+ .container {
69
+ display: flex;
70
+ justify-content: center;
71
+ margin-top: 100px;
72
+ }
73
+
74
+ #grid-container, #textbox-container{
75
+ margin-left: 150px;
76
+ margin-right: 150px;
77
+ }
78
+
79
+ .numero-container {
80
+ width: 280px;
81
+ height: 280px;
82
+ background-color: #fff;
83
+ color: #000;
84
+ text-align: center;
85
+ line-height: 100px;
86
+ }
deploy/templates/webpage.html ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles.css') }}">
7
+ <title>Digit Recognizer</title>
8
+ </head>
9
+ <body>
10
+ <header>
11
+ <h1>Digit Recognizer</h1>
12
+ </header>
13
+
14
+ <div class="container">
15
+
16
+ <div class="grid-container">
17
+
18
+ <canvas id="drawingCanvas" width="280" height="280" style="border: 1px solid black; background-color: white;"></canvas>
19
+
20
+ <div id="button-container">
21
+
22
+ <button id="sendDrawing">Enviar Desenho</button>
23
+ <button id="clearCanvas">Limpar Desenho</button>
24
+ <script src="{{ url_for('static', filename='script.js') }}"></script>
25
+
26
+ </div>
27
+
28
+ </div>
29
+
30
+ <div id="textbox-container">
31
+
32
+ <div id="bigChar">Seu dígito é: <span id="digitoValor"></span></div>
33
+ <div id="number">Propabilidade da previsão: <span id="probabilidadeValor"></span>%</div>
34
+
35
+ </div>
36
+
37
+ </div>
38
+ </body>
39
+ </html>