Introduction
After completing my postgraduate exams last year, I decided to learn how to use Python to invoke machine learning libraries, having previously only known some basic Flask operations.
This is a web-based image object recognition project built on the xyolo library, (just for fun). The frontend was developed using pure native techniques (I hadn’t learned Vue back then), and the backend API part is implemented using Flask. The code is extremely simple.
Preview
Here are a few images to give you an idea of what the final output looks like. The different colored boxes in the images are drawn by frontend divs, and the recognition result tags are also rendered using HTML. Finally, a table is drawn to display the recognition results and accuracy.
Implementation
Backend Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| import numpy
from xyolo import YOLO, DefaultYolo3Config
from xyolo import init_yolo_v3
from flask import Flask, jsonify, request
from flask_cors import CORS
from PIL import Image
app = Flask(__name__)
CORS(app, resources=r'/*')
config = DefaultYolo3Config()
init_yolo_v3(config)
yolo = YOLO(config)
@app.route('/postimg', methods=['POST'])
def hello_world():
img = Image.open(request.files['file'].stream)
result = yolo.detect_image(img)
print(result)
return jsonify({'result':numpy.array(result).tolist()})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8808, debug=True)
|
Frontend Code
Took a shortcut here, it’s all in HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
| <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Let's See What's Here</title>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
<style>
input {
margin: 15px;
}
.myimg {
max-height: 100vh;
max-width: 100%;
margin: auto;
}
.target-info {
color: #f00;
padding: 10px;
border: solid 3px #f00;
}
table,
th,
td {
border: 1px solid black;
}
</style>
</head>
<body>
<h2>Let's See What's In Here!</h2>
<p>Supports dragging and dropping images below this line of text</p>
<div id="dropBox" style="min-height: 100px; min-height: 100px;">
<div id="target" style="position:absolute"></div>
<img src="" id="myimg" class="myimg">
</div>
<input id="fileInput" type="file" onchange="processFiles(this.files)">
<img id="thumbnail">
<p id="stat">Ready</p>
<table id="restab">
<tr><th>Object</th><th>Confidence</th></tr>
</table>
<p>by xianfei 2021.12</p>
<script>
var dropBox;
window.onload = function () {
dropBox = document.getElementById("dropBox");
dropBox.ondragenter = ignoreDrag;
dropBox.ondragover = ignoreDrag;
dropBox.ondrop = drop;
}
function ignoreDrag(e) {
// We're handling the drag-and-drop, so make sure no other elements take this event
e.stopPropagation();
e.preventDefault();
}
function drop(e) {
// Stop propagation and prevent default behavior
e.stopPropagation();
e.preventDefault();
// Get the files that were dragged in
var data = e.dataTransfer;
var files = data.files;
// Pass them to the real file processing function
processFiles(files);
}
function ran() {
return Math.floor(Math.random() * 256);
}
function processFiles(files) {
$('#stat').html('Uploading and processing...')
var file = files[0];
const formData = new FormData();
formData.append('file', file)
fetch("/postimg", {
body: formData,
method: "post"
}).then(res => {
res.json().then(json => {
$('#stat').html('Detected ' + json.result.length + ' objects.')
var e = $('#myimg')
var heightRate = e.height() / e[0].naturalHeight
var widthRate = e.width() / e[0].naturalWidth
if (json.result.length == 0) $('#target').append('<div style="position:absolute;width:100px;">Detection Failed</div>')
for (var i of json.result) {
var color = 'rgb(' + ran() + ',' + ran() + ',' + ran() + ')';
$('#restab').append('<tr style="color:' + color + ';"><td>'+i[0]+'</td><td>'+i[2]+'</td></tr>')
$('#target').append('<div style="position:absolute;margin-left:' + i[3] * widthRate + 'px;margin-top:' + i[4] * heightRate + 'px;width: ' + (i[5] - i[3]) * widthRate + 'px;height: ' + (i[6] - i[4]) * heightRate + 'px;border-color: ' + color + ';color:' + color + ';" class="target-info">' + i[0] + '</div>')
}
console.log(json)
})
}).catch(ex => {
consoleLog("Submission failed:" + ex.toString());
});
var output = document.getElementById("fileOutput");
// Create a FileReader
var reader = new FileReader();
// Set up what to do when the data is ready
reader.onload = function (e) {
// Use the image URL to draw the background of the dropBox
$('#myimg')[0].src = e.target.result;
$('#target').html('')
$('#restab').html('<tr><th>Object</th><th>Confidence</th></tr>')
};
// Read the image
reader.readAsDataURL(file);
}
function showFileInput() {
var fileInput = document.getElementById("fileInput");
fileInput.click();
}
</script>
</body>
</html>
|