Skip to content

Commit

Permalink
Update Disease Detection function
Browse files Browse the repository at this point in the history
- Add confidence score to Diagnosis class
- Move confidence score to DiseaseCardItem
- Modify UI
- Remove unnecessary code
  • Loading branch information
rayjasson98 committed Jan 12, 2021
1 parent cd656ef commit ba4f088
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 235 deletions.
51 changes: 17 additions & 34 deletions lib/data/diseases/classifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,18 @@ import 'package:tflite_flutter_helper/tflite_flutter_helper.dart';
abstract class Classifier {
Interpreter interpreter;
InterpreterOptions _interpreterOptions;

var logger = Logger();

List<int> _inputShape;
List<int> _outputShape;

TensorImage _inputImage;
TensorBuffer _outputBuffer;

TfLiteType _outputType = TfLiteType.uint8;

final String _labelsFileName = 'assets/dict.txt';

final int _labelsLength = 6;

var _probabilityProcessor;

List<String> labels;

String get modelName;

NormalizeOp get preProcessNormalizeOp;
NormalizeOp get postProcessNormalizeOp;

Expand All @@ -39,21 +30,19 @@ abstract class Classifier {
if (numThreads != null) {
_interpreterOptions.threads = numThreads;
}

loadModel();
loadLabels();
}

Future<void> loadModel() async {
try {
interpreter =
await Interpreter.fromAsset(modelName, options: _interpreterOptions);
print('Interpreter Created Successfully');

interpreter = await Interpreter.fromAsset(
modelName,
options: _interpreterOptions,
);
_inputShape = interpreter.getInputTensor(0).shape;
_outputShape = interpreter.getOutputTensor(0).shape;
_outputType = interpreter.getOutputTensor(0).type;

_outputBuffer = TensorBuffer.createFixedSize(_outputShape, _outputType);
_probabilityProcessor =
TensorProcessorBuilder().add(postProcessNormalizeOp).build();
Expand All @@ -75,36 +64,31 @@ abstract class Classifier {
int cropSize = min(_inputImage.height, _inputImage.width);
return ImageProcessorBuilder()
.add(ResizeWithCropOrPadOp(cropSize, cropSize))
.add(ResizeOp(
_inputShape[1], _inputShape[2], ResizeMethod.NEAREST_NEIGHBOUR))
.add(
ResizeOp(
_inputShape[1],
_inputShape[2],
ResizeMethod.NEAREST_NEIGHBOUR,
),
)
.add(preProcessNormalizeOp)
.build()
.process(_inputImage);
}

Category predict(Image image) {
if (interpreter == null) {
throw StateError('Cannot run inference, Intrepreter is null');
throw StateError('Cannot run inference, Interpreter is null');
}
final pres = DateTime.now().millisecondsSinceEpoch;
_inputImage = TensorImage.fromImage(image);
_inputImage = _preProcess();
final pre = DateTime.now().millisecondsSinceEpoch - pres;

print('Time to load image: $pre ms');

final runs = DateTime.now().millisecondsSinceEpoch;
interpreter.run(_inputImage.buffer, _outputBuffer.getBuffer());
final run = DateTime.now().millisecondsSinceEpoch - runs;

print('Time to run inference: $run ms');

Map<String, double> labeledProb = TensorLabel.fromList(
labels, _probabilityProcessor.process(_outputBuffer))
.getMapWithFloatValue();
final pred = getTopProbability(labeledProb);

return Category(pred.key, pred.value);
labels,
_probabilityProcessor.process(_outputBuffer),
).getMapWithFloatValue();
final prediction = getTopProbability(labeledProb);
return Category(prediction.key, prediction.value);
}

void close() {
Expand All @@ -117,7 +101,6 @@ abstract class Classifier {
MapEntry<String, double> getTopProbability(Map<String, double> labeledProb) {
var pq = PriorityQueue<MapEntry<String, double>>(compare);
pq.addAll(labeledProb.entries);

return pq.first;
}

Expand Down
7 changes: 5 additions & 2 deletions lib/ui/diseases/diagnosis.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import 'package:flutter/foundation.dart';

class Diagnosis extends ChangeNotifier {
String _disease;
String _confidence;

String get getDisease => _disease;
String get disease => _disease;
String get confidence => _confidence;

void update(String disease) {
void update(String disease, String confidence) {
_disease = disease.toUpperCase();
_confidence = confidence;
notifyListeners();
}
}
63 changes: 42 additions & 21 deletions lib/ui/diseases/disease_card.dart
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
import 'package:farmassist/app_theme.dart';
import 'package:farmassist/ui/diseases/diagnosis.dart';
import 'package:farmassist/ui/diseases/disease_card_item.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class DiseaseCard extends StatelessWidget {
const DiseaseCard({Key key, this.diseaseItem, this.getDisease})
: super(key: key);

final DiseaseCardItem diseaseItem;
final Diagnosis getDisease;
const DiseaseCard({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
String disease = context.watch<Diagnosis>().getDisease;
Diagnosis diagnosis = context.watch<Diagnosis>();
String disease = diagnosis.disease;
String confidence = diagnosis.confidence;
int i = 0;

if (disease == null) {
disease = 'DISEASE';
} else {
for (int j = 0; j < 8; j++) {
if (DiseaseCardItem.diseaseItem[j].diseaseName == disease) i = j;
}
for (int j = 0; j < 8; j++) {
if (DiseaseCardItem.diseaseItem[j].diseaseName == disease) i = j;
}

return Container(
Expand Down Expand Up @@ -87,6 +80,40 @@ class DiseaseCard extends StatelessWidget {
),
),
),
Container(
child: confidence == null
? null
: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: FractionallySizedBox(
widthFactor: 0.9,
child: Container(
alignment: Alignment.center,
height: 60,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(18),
color: AppTheme.white.withOpacity(0.4),
),
child: Padding(
padding: const EdgeInsets.only(
right: 6.0,
left: 6.0,
top: 12,
bottom: 12,
),
child: Text(
'Confidence: $confidence%',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
letterSpacing: 0.18,
),
),
),
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: FractionallySizedBox(
Expand All @@ -113,14 +140,8 @@ class DiseaseCard extends StatelessWidget {
widthFactor: 0.9,
child: Text(
DiseaseCardItem.diseaseItem[i].treatment,
textAlign: TextAlign.justify,
style: TextStyle(
fontFamily: AppTheme.fontName,
fontWeight: FontWeight.normal,
fontSize: 16,
letterSpacing: 0.0,
color: AppTheme.dark_grey,
),
textAlign: TextAlign.left,
style: AppTheme.bodyText1,
),
),
),
Expand Down
56 changes: 14 additions & 42 deletions lib/ui/diseases/disease_card_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class DiseaseCardItem {
static List<DiseaseCardItem> diseaseItem = [
DiseaseCardItem(
diseaseName: 'DISEASE',
action: 'Action/Treament Information',
action: 'Action/Treatment Information',
treatment: 'Snap or choose an image now for disease detection!',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
Expand All @@ -29,50 +29,35 @@ class DiseaseCardItem {
DiseaseCardItem(
diseaseName: 'TOMATO LEAF MOLD',
action: 'Treatment:',
treatment: 'Method 1: Let the plants air out or expose to dry air conditions.' +
'\n'
'Method 2: Spray the plants with fungicide sprays (Recommended: Calcium chloride sprays) and '
'make sure to cover all parts of the plant that is above ground, focusing specifically on the underside of leaves.',
treatment:
'Method 1:\nLet the plants air out or expose to dry air conditions.\n\nMethod 2:\nSpray the plants with fungicide sprays (Recommended: Calcium chloride sprays) and make sure to cover all parts of the plant that is above ground, focusing specifically on the underside of leaves.',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
imagePath: 'assets/images/treatment.png',
),
DiseaseCardItem(
diseaseName: 'STRAWBERRY LEAF SCORCH',
action: 'Treatment:',
treatment: 'Method 1: Let the plant dry out by altering the watering practices and allowing for dryer conditions.' +
'\n'
'Method 2: Treat the plant with organic fungicides. (Captan 50 WP & Copper compounds)' +
'\n'
'Note: Can be prevented most effectively with the use of resistant varieties. (Allstar, Jewell, Midway & etc.)',
treatment:
'Method 1:\nLet the plant dry out by altering the watering practices and allowing for dryer conditions.\n\nMethod 2:\nTreat the plant with organic fungicides. (Captan 50 WP & Copper compounds)\n\nNote:\nCan be prevented most effectively with the use of resistant varieties. (Allstar, Jewell, Midway & etc.)',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
imagePath: 'assets/images/treatment.png',
),
DiseaseCardItem(
diseaseName: 'TOMATO MOSAIC VIRUS',
action: 'Actions:',
treatment: '*Note that there is NO cure for this viral disease!' +
'\n'
'1. Remove and destroy all infected plant.' +
'\n'
'2. Spot treat with least-toxic, natural pest control products (Safer Soap & Bon-Neem) to reduce the disease carrying insects.' +
'\n'
'3. Plant resistant varieties or purchase transplants from a reputable source.' +
'\n'
'4. Wash your hands frequently and disinfect garden tools and equipment to reduce contamination risk.',
treatment:
'Note that there is NO cure for this viral disease!\n\nAction 1:\nRemove and destroy all infected plant.\n\nAction 2:\nSpot treat with least-toxic, natural pest control products (Safer Soap & Bon-Neem) to reduce the disease carrying insects.\n\nAction 3:\nPlant resistant varieties or purchase transplants from a reputable source.\n\nAction 4:\nWash your hands frequently and disinfect garden tools and equipment to reduce contamination risk.',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
imagePath: 'assets/images/treatment.png',
),
DiseaseCardItem(
diseaseName: 'CORN COMMON RUST',
action: 'Treatment:',
treatment: 'Method 1: Plant resistant hybrids such as commercial corn.' +
'\n'
'Method 2: Go for tillage and crop rotation' +
'\n'
'Method 3: Treat with fungicide such as foliar, Quilt and Quadris.',
treatment:
'Method 1:\nPlant resistant hybrids such as commercial corn.\n\nMethod 2:\nGo for tillage and crop rotation\n\nMethod 3:\nTreat with fungicide such as foliar, Quilt and Quadris.',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
imagePath: 'assets/images/treatment.png',
Expand All @@ -81,38 +66,25 @@ class DiseaseCardItem {
diseaseName: 'CORN GRAY LEAF SPOT',
action: 'Treatment:',
treatment:
'Method 1: Go for crop rotation and tillage will help to reduce inoculum levels in surface residues.' +
'\n'
'Method 2: Plant resistant varieties.' +
'\n'
'Method 3: Treat with fungicide such as azoxystrobin with propiconazole, pyraclostrobin and prothioconazole.' +
'\n',
'Method 1:\nGo for crop rotation and tillage will help to reduce inoculum levels in surface residues.\n\nMethod 2:\nPlant resistant varieties.\n\nMethod 3:\nTreat with fungicide such as azoxystrobin with propiconazole, pyraclostrobin and prothioconazole.\n',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
imagePath: 'assets/images/treatment.png',
),
DiseaseCardItem(
diseaseName: 'POTATO EARLY BLIGHT',
action: 'Actions:',
treatment: '*Note that there is NO cure for blight on plants.' +
'\n'
'1. Remove and destroy all infected plant.' +
'\n'
'2. Disinfect garden tools and equipment to prevent further spread of blight.' +
'\n'
'3. Plant resistant varieties or practice crop rotation to prevent blight.' +
'\n'
'4. For best control, apply copper-based fungicides earlier before wet weather condition happens.',
treatment:
'Note that there is NO cure for blight on plants.\n\nAction 1:\nRemove and destroy all infected plant.\n\nAction 2:\nDisinfect garden tools and equipment to prevent further spread of blight.\n\nAction 3:\nPlant resistant varieties or practice crop rotation to prevent blight.\n\nAction 4:\nFor best control, apply copper-based fungicides earlier before wet weather condition happens.',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
imagePath: 'assets/images/treatment.png',
),
DiseaseCardItem(
diseaseName: 'HEALTHY',
action: 'Condition:',
treatment: 'Your plant is healthy!' +
'\n'
'However, do remember to practice good farming habits as prevention is the best cure diseases!',
treatment:
'Your plant is healthy!\nHowever, do remember to practice good farming habits as prevention is the best cure diseases!',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
imagePath: 'assets/images/healthy.png',
Expand Down
31 changes: 4 additions & 27 deletions lib/ui/diseases/disease_detection_page.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:farmassist/ui/diseases/diagnosis.dart';
import 'package:farmassist/ui/diseases/disease_card.dart';
import 'package:farmassist/ui/diseases/disease_card_item.dart';
import 'package:farmassist/ui/diseases/view_image_region.dart';
import 'package:farmassist/ui/widgets/tab_page.dart';
import 'package:flutter/material.dart';
Expand All @@ -15,41 +14,19 @@ class DiseaseDetectionPage extends TabPage {
}

class _DiseaseDetectionPageState extends TabPageState<DiseaseDetectionPage> {
final List<DiseaseCardItem> _diseaseItem = DiseaseCardItem.diseaseItem;
Diagnosis _disease = Diagnosis();
Diagnosis _diagnosis = Diagnosis();

void initState() {
tabListView.add(ViewImageRegion(
getDisease: _disease,
));

tabListView.add(DiseaseCard(
diseaseItem: DiseaseCardItem(
diseaseName: 'DISEASE',
action: 'Action/Treament Information',
treatment: 'Snap or choose an image now for disease detection!',
color1: const Color(0XFFFFF176),
color2: const Color(0XFF69F0AE),
imagePath: 'assets/images/treatment.png',
),
getDisease: _disease,
));
print('_disease!!!!!');
print(Diagnosis().getDisease);

tabListView.add(ViewImageRegion(diagnosis: _diagnosis));
tabListView.add(DiseaseCard());
super.initState();
}

@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Diagnosis>.value(
value: _disease,
value: _diagnosis,
child: super.build(context),
);
}

@override
Widget buildTabListView() {
return super.buildTabListView();
}
}
Loading

0 comments on commit ba4f088

Please sign in to comment.