-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
295 lines (262 loc) · 13.2 KB
/
index.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
<!--
Algorithmes numériques
Mini Projet
Auteurs : Lucas Fridez
Date : 2020.06.20
Version : 2020.06.20
-->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css">
<title>AN2020_MiniProjet_FridezLucas</title>
</head>
<body>
<h1>Traitement d'images pour nombre de globules blancs</h1>
<fieldset>
<legend>Interactions utilisateurs</legend>
<p>A noter que la liste déroulante ne fonctionne pas en local pour des raisons d'accès Cross Origine au disque.
Elle fonctionne sur le site internet mis à disposition : <a href="https://an.fridez.dev">an.fridez.dev</a>.
</p>
<p>Si ce mini-projet est utilisé en local; veuillez utiliser le petit formulaire (le champ input file
ci-dessous) avec les images dans le répertoire <em>img</em> de l'archive envoyée.</p>
<input type="file" id="fileInput" />
<select name="" id="selectImage">
<option value="0" selected disabled>Selectionner une image</option>
<option value="1">Image 1</option>
<option value="2">Image 2</option>
<option value="3">Image 3</option>
<option value="4">Image 4</option>
</select>
<div>
<label for="limit">Seuil du gris/blanc [0; 255]</label>
<div>
<em>Minimum :</em>
<input type="range" name="limitMin" id="limitMin" min="0" max="255" value="180">
<span>180</span>
</div>
<div>
<em>Maximum :</em>
<input type="range" name="limitMax" id="limitMax" min="0" max="255" value="220">
<span>220</span>
</div>
<div>
<em>Maximum pour graph :</em>
<input type="range" name="maxBlack" id="maxBlack" min="0" max="255" value="240">
<span>240</span>
</div>
<div>
<p>Image Processing options</p>
<ul>
<li>
<input type="checkbox" name="cbApplyErosion" id="cbApplyErosion" checked>
<label for="cbApplyErosion">Apply erosion</label>
</li>
<li>
<input type="checkbox" name="cbApplyDilation" id="cbApplyDilation" checked>
<label for="cbApplyDilation">Apply dilation</label>
</li>
<li>
<label for="txtCellSize">Taille de cellule</label>
<input type="number" value="25" name="txtCellSize" id="txtCellSize">
</li>
</ul>
</div>
</div>
</fieldset>
<div id="images">
<img src="img/white-blood-cells-1.jpeg" alt="Image 1">
<img src="img/white-blood-cells-2.jpg" alt="Image 2">
<img src="img/white-blood-cells-3.jpg" alt="Image 3">
<img src="img/white-blood-cells-4.jpg" alt="Image 4">
</div>
<div id="container">
<div id="analysis">
<div class="step">
<p>1. Image originale</p>
<canvas id="canvas" width="400" height="400"></canvas>
</div>
<div class="step">
<p>2. Image niveaux de gris</p>
<canvas id="canvas-gray" width="400" height="400"></canvas>
</div>
<div class="step">
<p>3. Spectre d'intensité noir</p>
<canvas id="myChart" width="400" height="300"></canvas>
</div>
<div class="step">
<p>4. Image noir & blanc</p>
<canvas id="canvas2" width="400" height="400"></canvas>
</div>
<div class="step">
<p>5. Erosion/Dilatation</p>
<canvas id="canvas4" width="400" height="400"></canvas>
</div>
<div class="step">
<p>6. Globules blancs (nombre = <span id="numberWhiteBloodCells"></span>)</p>
<canvas id="canvas5" width="400" height="400"></canvas>
</div>
</div>
</div>
<h2>1. Introduction</h2>
<p>Ce présent projet traite d'une détection de cellules au sein d'une image. Le nombre de globules blancs dans le
sang est un indice important de santé pour toutes personnes.</p>
<p>En effet, un surplus de globules blancs peut indiquer :</p>
<ul>
<li>infection</li>
<li>inflammation</li>
<li>blessures</li>
<li>etc...</li>
</ul>
<p>Et un manque de globules blancs peut indiquer :</p>
<ul>
<li>cancer</li>
<li>etc...</li>
</ul>
<p>Il est donc important de pouvoir compter précisément le nombre de globules blancs d'une personne au sein d'un
échantillon. Cela permet d'estimer correctement le nombre de cellules et de définir si la personne est en bonne
santé ou non.</p>
<p>Pour un être humain, il est facile mais lent de dénombrer des cellules sur une image. Pour un ordinateur, c'est
l'inverse. Il ne reconnaît en rien l'apparence d'une cellule. Un bon algorithme permet à un ordinateur de
reconnâitre des cellules (formes).
Une fois ce dernier implémenté, le dénombrement sera bien plus rapide qu'un humain grâce à la rapidité d'un
ordinateur.
</p>
<h2>2. Solution proposée</h2>
<p>La démarche pour dénombrer les globules blancs sur une image est la suivante :</p>
<ol>
<li>Récupérer l'image originale</li>
<li>Transformer l'image en niveau de gris</li>
<li>Dessiner un graphique du spectre d'intensité de l'image en niveaux de gris (de 0 à 255)</li>
<li>Créer une image en noir et blanc (binaire, 0 ou 1)</li>
<li>Effectuer un <em>Image Processing</em></li>
<li>Entourer les globules trouvés</li>
</ol>
<h3>2.1 Idée en lien avec le/les chapitres d'Algo num.</h3>
<p>L'Image Processing est un lien direct avec le chapitre 3, <strong>Systèmes linéaires</strong>. En effet, beaucoup
d'algorithmes utilisent des matrices pour travailler sur des images.</p>
<p>De plus, le calcul pour trouver le seuil limite [min; max] se réfère plus au chapitre 2, <strong>Résolution
d'Equation</strong>.</p>
<h3>2.2 Modèle développé</h3>
<h4>2.2.1 Calcul du seuil</h4>
<img src="img/report/seuil.jpg" alt="Calcul seuil">
<p>Si i' est plus grand que la valeur de a, on garde a comme valeur maximale. L'intervalle s obtenu permet de
transformer les pixels compris en valeur noir. Les autres seront définis en tant que pixels blanc pour l'image
binaire.</p>
<h4>2.2.2 Détecter des cercles</h4>
<img src="img/report/detect-cell.jpg" alt="Détection de cellules">
<p>Ici, l'image est parcourue avec une fenêtre de taille fixe a. Cette dernière comprend un cercle permettant de
tester si l'image dans la fenêtre contient une cellule. A chaque itération, l'algorithme contrôle si la fenêtre
contient une cellule (tester les pixels du cercle de la fenêtre avec la matrice cercle créée). Si elle ne
contient pas de cercle; la fenêtre est déplacée sur la droite d'un pixel. Si la fenêtre contient une cellule, la
fenêtre est décallée sur la droite de la taille de cellule.</p>
<p>En cas de double détections ou plus, un test est effectuée pour ne pas compter à double des cellules. Leur centre
doit être espacée de la taille d'une cellule pour que ces dernières soient comptées comme <strong>cellules
différentes</strong>.</p>
<h2>3. Résultats</h2>
<p>Les résultats sont concluants. Ci-dessous se trouve la table des résultats avec les 4 images proposées :</p>
<table>
<caption>Résultats pour les 4 images proposées</caption>
<thead>
<tr>
<th id="number">Image numéro</th>
<th id="size">Taille cellule</th>
<th id="found">Cellules trouvées</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>23</td>
<td>15/15 (cellules entières)</td>
</tr>
<tr>
<td>2</td>
<td>40</td>
<td>15/15 (cellules entières)</td>
</tr>
<tr>
<td>3</td>
<td>17</td>
<td>22/23 (cellules entières)</td>
</tr>
<tr>
<td>4</td>
<td>25</td>
<td>28/29 (cellules entières)</td>
</tr>
</tbody>
</table>
<em>Note : les cellules non trouvées sont plus petites que les autres. L'algorithme implémenté cherche des cellules
de même taille.</em>
<p>Pour des images trop grandes (ici l'image 2), il se peut qu'une erreur "RangeError: Maximum call stack size
exceeded" soit retournée. Il s'agit de la pile d'appels de méthodes JavaScript qui est limitée. Cela provient
des appels récursifs pour l'érosion et la dilatation. Une alerte s'affiche mais le résultat apparaît correct
suite à l'Image Processing.</p>
<h3>3.1 Code source</h3>
<p>Le mini projet est scanné à l'aide d'un outil de qualité de code source. Les résultats sont les suivants :</p>
<img src="img/report/sonarscan.png" alt="Sonarscan">
<h3>3.2 Documentation</h3>
<p>Une documentation type <strong>TypeDoc</strong> est également générée. <a href="docs/index.html">Voir la
documentation</a></p>
<h2>4. Conclusion</h2>
<p>L'algorithme de détection des cellules fonctionne bien. En somme, la presque totalité des cellules est
détectée.</p>
<p>Les faiblesses de la solution proposée sont les suivantes :</p>
<ul>
<li>L'utilisateur doit définir une taille de cellule</li>
<li>L'utilisateur doit choisir le seuil maximaml du noir (Slider maximum pour graph)</li>
</ul>
<p>Les forces de la solution sont les suivantes :</p>
<ul>
<li>L'utilisateur peut choisir une image et l'analyser avec le file input</li>
<li>Le dénombrement fonctionne correctement pour les cellules entière (car même taille)</li>
<li>Transformer l'image en niveua de gris selon la formule suivante : <em>gray = 0.3*R + 0.59*G + 0.11*B</em>.
Cela permet d'obtenir un gris "équitable" selon la perception des couleurs de l'oeil humain.</li>
</ul>
<p>Les perspectives d'améliorations sont les suivantes :</p>
<ul>
<li>Implémenter un algorithme <strong>Hough Circle Transform</strong> permettant de détecter des cellules de
n'importe quelle taille</li>
<li>Trouver la valeur maximale du noir automatiquement</li>
</ul>
<h2>5. Références</h2>
<ul>
<li>Mayo Clinic Staff, Low white blood cell count, <a target="_blank" rel="noopener noreferrer"
href="https://www.mayoclinic.org/symptoms/low-white-blood-cell-count/basics/causes/sym-20050615">www.mayoclinic.org</a>,
30 novembre 2018</li>
<li>MedicalNewsToday, What to know about high white blood cell count, <a target="_blank"
rel="noopener noreferrer"
href="https://www.medicalnewstoday.com/articles/315133#high-levels">www.medicalnewstoday.com</a>, 21
novembre 2018</li>
<li>VapidSpace, Converting Images To Grayscale Using The Canvas,
<a target="_blank" rel="noopener noreferrer"
href="http://www.vapidspace.com/coding/2012/02/26/converting-images-to-grayscale-using-the-canvas/">www.vapidspace.com</a>,
26 février
2012
</li>
<li>Frédéric Legrand, Traitement d'image : niveaux de gris, <a target="_blank" rel="noopener noreferrer"
href="https://www.f-legrand.fr/scidoc/docmml/image/niveaux/images/images.html">www.f-legrand.fr</a>, lu
le 5 mai 2020</li>
<li>Rahul, async await in image loading, <a target="_blank" rel="noopener noreferrer"
href="https://stackoverflow.com/questions/46399223/async-await-in-image-loading">www.stackoverflow.com</a>,
25 septembre 2017</li>
<li>tech_geek, Draw horizontal line on chart in chart.js on v2, <a target="_blank" rel="noopener noreferrer"
href="https://stackoverflow.com/questions/42691873/draw-horizontal-line-on-chart-in-chart-js-on-v2">www.stackoverflow.com</a>,
9 mars 2017</li>
<li>PorkShoulderHolder, mathematical morphology for javascript, <a target="_blank" rel="noopener noreferrer"
href="https://github.com/PorkShoulderHolder/morph">www.github.com</a>, 17 août 2018</li>
<li>Wikipédia, Circle Hough Transform, <a target="_blank" rel="noopener noreferrer"
href="https://en.wikipedia.org/wiki/Circle_Hough_Transform">www.wikipedia.org</a>, 1 décembre 2019
</li>
</ul>
<footer>
<p>Algorithmes numériques - Mini Projet. Lucas Fridez (20 juin 2020)</p>
<p>A destination de Monsieur Stéphane Gobron</p>
</footer>
<script src="src/lib/morph.js"></script>
<script src="app.js"></script>
</body>
</html>