@@ -3,6 +3,7 @@ import 'dart:math';
3
3
4
4
import 'package:flutter/foundation.dart' ;
5
5
import 'package:flutter/material.dart' ;
6
+ import 'package:flutter/widgets.dart' ;
6
7
import 'package:http/http.dart' as http;
7
8
import 'package:image/image.dart' as img;
8
9
@@ -37,10 +38,12 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
37
38
late Image displayedCmappedMaskImage;
38
39
39
40
Map <int , int > pixelCount = < int , int > {};
41
+ Map <int , int > totalTissuePixelFound = < int , int > {};
40
42
41
43
User myuser = UserManager .instance.user;
42
44
43
- late int indexTissueToFind;
45
+ int tissueToFind = 0 ;
46
+
44
47
Map <int , String > tissueTypes = < int , String > {
45
48
1 : 'Carcinoma' ,
46
49
2 : 'Necrosis' ,
@@ -57,19 +60,19 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
57
60
void _getPixelsTypeCount () {
58
61
for (int x = 0 ; x < maskImage! .width; x++ ) {
59
62
for (int y = 0 ; y < maskImage! .height; y++ ) {
60
- final img.Pixel pixelValue = maskImage! .getPixel (x, y);
61
- pixelCount.update (pixelValue.r as int , (int value) => value + 1 ,
63
+ final pixelValue = maskImage! .getPixel (x, y);
64
+ totalTissuePixelFound.update (
65
+ pixelValue.r as int , (int value) => value + 1 ,
62
66
ifAbsent: () => 1 );
63
67
}
64
68
}
65
-
66
69
// Print each unique pixel value
67
- for (final int pixelValue in pixelCount .keys) {
68
- if (kDebugMode) {
69
- print ('Total Pixel Value: $pixelValue ' );
70
- print ('Total Pixel Count: ${pixelCount [pixelValue ]}' );
71
- }
72
- }
70
+ // for (final int pixelValue in totalTissuePixelFound .keys) {
71
+ // if (kDebugMode) {
72
+ // print('Total Pixel Value: $pixelValue');
73
+ // print('Total Pixel Count: ${totalTissuePixelFound [pixelValue]}');
74
+ // }
75
+ // }
73
76
}
74
77
75
78
void _getTissueToFind () {
@@ -79,13 +82,13 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
79
82
// 4: (0, 255, 255), # Others
80
83
81
84
// Select randomly one of the keys in pixelCount exept 0
82
- final List <int > pixelValues = pixelCount .keys.toList ();
85
+ final List <int > pixelValues = totalTissuePixelFound .keys.toList ();
83
86
pixelValues.remove (0 );
84
- indexTissueToFind = pixelValues[Random ().nextInt (pixelValues.length)];
87
+ tissueToFind = pixelValues[Random ().nextInt (pixelValues.length)];
85
88
86
89
if (kDebugMode) {
87
- final String tissueName = tissueTypes[indexTissueToFind ]! ;
88
- print ('Tissue Index to Find: $indexTissueToFind ' );
90
+ final String tissueName = tissueTypes[tissueToFind ]! ;
91
+ print ('Tissue Index to Find: $tissueToFind ; ' );
89
92
print ('Tissue to Find: $tissueName ' );
90
93
}
91
94
}
@@ -130,9 +133,10 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
130
133
_getPixelsTypeCount ();
131
134
132
135
// Check if 0 is the only pixel value
133
- if (pixelCount.length == 1 && pixelCount.containsKey (0 )) {
136
+ if (totalTissuePixelFound.length == 1 &&
137
+ totalTissuePixelFound.containsKey (0 )) {
134
138
if (kDebugMode) {
135
- print ('Only Background Pixels' );
139
+ print ('Only Unknown Class Pixels' );
136
140
}
137
141
continue ;
138
142
}
@@ -195,15 +199,15 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
195
199
2 ) *
196
200
scalingFactorX; // Assuming uniform scaling
197
201
198
- if (kDebugMode) {
199
- print ('Center: ($centerX , $centerY ), Radius: $radius ' );
200
- print ('Image Size: ${fullImage !.width } x ${fullImage !.height }' );
201
- print ('Mask Size: ${maskImage !.width } x ${maskImage !.height }' );
202
- print (
203
- 'Rendered cmapped Mask Size: ${displayedCmappedMaskImage .width } x ${displayedCmappedMaskImage .height }' );
204
- print (
205
- 'Rendered Image Size: ${displayedFullImage .width } x ${displayedFullImage .height }' );
206
- }
202
+ // if (kDebugMode) {
203
+ // print('Center: ($centerX, $centerY), Radius: $radius');
204
+ // print('Image Size: ${fullImage!.width} x ${fullImage!.height}');
205
+ // print('Mask Size: ${maskImage!.width} x ${maskImage!.height}');
206
+ // print(
207
+ // 'Rendered cmapped Mask Size: ${displayedCmappedMaskImage.width} x ${displayedCmappedMaskImage.height}');
208
+ // print(
209
+ // 'Rendered Image Size: ${displayedFullImage.width} x ${displayedFullImage.height}');
210
+ // }
207
211
208
212
final Set <int > uniquePixelValues = < int > {};
209
213
final Map <int , int > pixelCount = < int , int > {};
@@ -228,13 +232,54 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
228
232
}
229
233
}
230
234
231
- // Print each unique pixel value
232
- for (final int pixelValue in uniquePixelValues) {
235
+ // if tissueToFind is in pixelCount
236
+ if (pixelCount.containsKey (tissueToFind)) {
237
+ // sum the total number of pixels in image
238
+ double totalCoveredPixels = 0 ;
239
+ for (final int pixelValue in pixelCount.keys) {
240
+ totalCoveredPixels += pixelCount[pixelValue]! ;
241
+ }
242
+
243
+ // if selected pixels cover the whole image area
244
+ final double coveredArea =
245
+ totalCoveredPixels / (maskImage! .width * maskImage! .height);
246
+
247
+ if (coveredArea > 0.7 ) {
248
+ if (kDebugMode) {
249
+ print (
250
+ 'Devi selezionare solo la parte dell\' immagine in cui è presente il tessuto' );
251
+ return ;
252
+ }
253
+ }
254
+
255
+ // if number of pixel of correct tissue is less than 50% of the total correct tissue pixels
256
+ if (pixelCount[tissueToFind]! <
257
+ 0.5 * totalTissuePixelFound[tissueToFind]! ) {
258
+ print ('Non hai individuato tutto il tessuto corretto' );
259
+ return ;
260
+ }
261
+
233
262
if (kDebugMode) {
234
- print ('Pixel Value in selected Area: $pixelValue ' );
235
- print ('Pixel Count in selected Area: ${pixelCount [pixelValue ]}' );
263
+ print ('Tissue Name: ${tissueTypes [tissueToFind ]}' );
264
+ print ('Total Pixel Count: ${totalTissuePixelFound [tissueToFind ]}' );
265
+ print ('Pixel Count in selected Area: ${pixelCount [tissueToFind ]}' );
266
+ print ('Covered Area: $coveredArea ' );
267
+ print ('Total Area: ${maskImage !.width * maskImage !.height }' );
268
+ print ('Covered Pixels: $totalCoveredPixels ' );
236
269
}
270
+
271
+ print ('Hai individuato il tessuto corretto' );
272
+ } else {
273
+ print ('Non hai individuato il tessuto corretto' );
237
274
}
275
+
276
+ // Print each unique pixel value
277
+ // for (final int pixelValue in uniquePixelValues) {
278
+ // if (kDebugMode) {
279
+ // print('Pixel Value in selected Area: $pixelValue');
280
+ // print('Pixel Count in selected Area: ${pixelCount[pixelValue]}');
281
+ // }
282
+ // }
238
283
}
239
284
240
285
void checkAnswer () {
@@ -247,7 +292,7 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
247
292
appBar: AppBar (
248
293
title: const Text ('Circle Area Comparison' ),
249
294
),
250
- body: imageBytes.isEmpty
295
+ body: imageBytes.isEmpty || tissueToFind == 0
251
296
? const Center (child: CircularProgressIndicator ())
252
297
: Column (
253
298
children: < Widget > [
@@ -261,7 +306,7 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
261
306
),
262
307
children: < TextSpan > [
263
308
TextSpan (
264
- text: tissueTypes[indexTissueToFind ],
309
+ text: tissueTypes[tissueToFind ],
265
310
style:
266
311
const TextStyle (fontWeight: FontWeight .bold)),
267
312
const TextSpan (text: ' Tissue!' ),
@@ -272,7 +317,7 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
272
317
Row (
273
318
children: < Widget > [
274
319
Padding (
275
- padding: const EdgeInsets .only (left: 20 , right: 20 ),
320
+ padding: const EdgeInsets .only (left: 50 , right: 20 ),
276
321
child: Center (
277
322
child: ClipRect (
278
323
child: FittedBox (
@@ -303,56 +348,104 @@ class _CircleImageComparisonScreenState extends State<SelectTheAreaGame> {
303
348
),
304
349
),
305
350
),
351
+ Column (
352
+ mainAxisAlignment: MainAxisAlignment .spaceAround,
353
+ children: < Widget > [
354
+ const Row (
355
+ children: < Widget > [
356
+ Align (
357
+ alignment: Alignment .topLeft,
358
+ child: SizedBox (
359
+ height: 200 ,
360
+ width: 550 ,
361
+ child: Text (
362
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '
363
+ 'Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. '
364
+ 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '
365
+ 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. '
366
+ 'Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' ,
367
+ style: TextStyle (
368
+ color: Colors .black,
369
+ fontSize: 16 ,
370
+ overflow: TextOverflow .visible,
371
+ ),
372
+ maxLines: 20 ,
373
+ ),
374
+ ),
375
+ ),
376
+ ],
377
+ ),
378
+ const SizedBox (height: 30 ),
379
+ Row (
380
+ children: < Widget > [
381
+ if (_isVisible)
382
+ Column (
383
+ children: < Widget > [
384
+ Padding (
385
+ padding: const EdgeInsets .only (left: 20 ),
386
+ child: RichText (
387
+ text: TextSpan (
388
+ text: 'Image visibility: ' ,
389
+ style: DefaultTextStyle .of (context)
390
+ .style
391
+ .apply (
392
+ fontSizeFactor: 1.5 ,
393
+ ),
394
+ children: < TextSpan > [
395
+ TextSpan (
396
+ text: imageVisibility
397
+ .toStringAsFixed (2 ),
398
+ style: const TextStyle (
399
+ fontWeight: FontWeight .bold)),
400
+ ],
401
+ ),
402
+ ),
403
+ ),
404
+ const SizedBox (height: 10 ),
405
+ Slider (
406
+ value: imageVisibility,
407
+ onChanged: (double value) {
408
+ setState (() {
409
+ imageVisibility = value;
410
+ });
411
+ },
412
+ ),
413
+ const SizedBox (width: 30 ),
414
+ const Text ('legenda' )
415
+ ],
416
+ ),
417
+ ],
418
+ )
419
+ ],
420
+ )
306
421
],
307
422
),
308
423
const SizedBox (height: 30 ),
309
424
// Display bottom left button to confirm the selection
310
425
Row (
311
426
children: < Widget > [
312
- if (_isVisible)
313
- Column (
314
- children: < Widget > [
315
- Text (
316
- 'Image Visibility' ,
317
- style: DefaultTextStyle .of (context).style.apply (
318
- fontSizeFactor: 1.5 ,
319
- ),
320
- ),
321
- const SizedBox (height: 10 ),
322
- Slider (
323
- value: imageVisibility,
324
- onChanged: (double value) {
325
- setState (() {
326
- imageVisibility = value;
327
- });
328
- },
329
- ),
330
- Text (
331
- imageVisibility.toStringAsFixed (2 ),
332
- style: DefaultTextStyle .of (context)
333
- .style
334
- .apply (fontSizeFactor: 1.5 ),
335
- ),
336
- ],
337
- ),
338
427
const Spacer (),
339
428
Align (
340
429
alignment: Alignment .bottomRight,
341
- child: ElevatedButton (
342
- onPressed: _isEnabled
343
- ? () {
344
- setState (() {
345
- if (! _isVisible &&
346
- _startPoint != null &&
347
- _endPoint != null &&
348
- _isDrawing) {
349
- _isVisible = true ;
350
- checkAnswer ();
351
- }
352
- });
353
- }
354
- : null ,
355
- child: const Text ('Confirm Selection' ),
430
+ child: SizedBox (
431
+ height: 50 ,
432
+ width: 200 ,
433
+ child: FilledButton (
434
+ onPressed: _isEnabled
435
+ ? () {
436
+ setState (() {
437
+ if (! _isVisible &&
438
+ _startPoint != null &&
439
+ _endPoint != null &&
440
+ _isDrawing) {
441
+ _isVisible = true ;
442
+ checkAnswer ();
443
+ }
444
+ });
445
+ }
446
+ : null ,
447
+ child: const Text ('Confirm Selection' ),
448
+ ),
356
449
),
357
450
),
358
451
],
0 commit comments