Naikin gitignore
This commit is contained in:
parent
9fb6661156
commit
1a5cc31678
|
@ -0,0 +1,114 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Example: bash build-app.sh -b=apk -e=staging/.env --add-args=--release --add-args=--target=lib/main_staging.dart
|
||||||
|
# Example prod: bash build-app.sh -b=apk -e=production/.env --add-args=--release --add-args=--target=lib/main_production.dart
|
||||||
|
# Example aab: bash build-app.sh -b=appbundle -e=production/.env --add-args=--release --add-args=--target=lib/main_production.dart
|
||||||
|
|
||||||
|
# Example get Env : String.fromEnvironment, bool.fromEnvironment, int.fromEnvironment, and double.fromEnvironment
|
||||||
|
|
||||||
|
# --build-number
|
||||||
|
# On Android it is used as "versionCode".
|
||||||
|
# On Xcode builds it is used as "CFBundleVersion".
|
||||||
|
|
||||||
|
#--obfuscate --split-debug-info=./debug_symbols
|
||||||
|
|
||||||
|
# --build-name
|
||||||
|
# On Android it is used as "versionName".
|
||||||
|
# On Xcode builds it is used as "CFBundleShortVersionString".
|
||||||
|
|
||||||
|
# for window run on Git Bash/ Bash For Window
|
||||||
|
|
||||||
|
# Read user input for a specific argument
|
||||||
|
read_argument() {
|
||||||
|
read -p "Enter $1: " input
|
||||||
|
echo "$input"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse command-line arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
|
||||||
|
-e=*|--env=*)
|
||||||
|
env_file="${1#*=}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-b=*|--bundle=*)
|
||||||
|
bundle="${1#*=}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--add-args=*)
|
||||||
|
add_args+=" ${1#*=}"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid argument: $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Validation Environment
|
||||||
|
if [[ -z "$env_file" ]]; then
|
||||||
|
env_file=$(read_argument "env file path")
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Validation Bundle
|
||||||
|
if [[ -z "$bundle" ]]; then
|
||||||
|
bundle=$(read_argument "bundle (aar, apk, appbundle, ios, ipa)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$bundle" != "aar" && "$bundle" != "apk" && "$bundle" != "appbundle" && "$bundle" != "ios" && "$bundle" != "ipa" ]]; then
|
||||||
|
echo "Invalid bundle option: $bundle"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate dart define
|
||||||
|
generate_dart_define_args() {
|
||||||
|
env_file="$1"
|
||||||
|
dart_define_args=""
|
||||||
|
while IFS= read -r line; do
|
||||||
|
# Ignore lines starting with '#' and lines with only whitespace
|
||||||
|
if [[ ! -z "$line" && "$line" != "#"* && ! "$line" =~ ^[[:space:]]*$ ]]; then
|
||||||
|
key=$(echo "$line" | cut -d '=' -f 1)
|
||||||
|
value=$(echo "$line" | cut -d '=' -f 2-)
|
||||||
|
dart_define_args+="--dart-define=$key=$value "
|
||||||
|
fi
|
||||||
|
done < "$env_file"
|
||||||
|
echo "$dart_define_args"
|
||||||
|
}
|
||||||
|
|
||||||
|
dart_define_args=$(generate_dart_define_args "$env_file")
|
||||||
|
dart_define_args+="$add_args"
|
||||||
|
|
||||||
|
echo "Arguments:"
|
||||||
|
echo "> Platform: $platform"
|
||||||
|
echo "> Env: $env_file"
|
||||||
|
echo "> Build: $build_type"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "Running flutter clean"
|
||||||
|
|
||||||
|
flutter clean
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Remove pubspec.lock if it exists
|
||||||
|
if [ -f "pubspec.lock" ]; then
|
||||||
|
echo "Removing pubspec.lock"
|
||||||
|
echo ""
|
||||||
|
rm pubspec.lock
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running flutter pub get"
|
||||||
|
flutter pub get
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Add obfuscation for APK and AAB
|
||||||
|
if [[ "$bundle" == "apk" || "$bundle" == "appbundle" ]]; then
|
||||||
|
dart_define_args+=" --obfuscate --split-debug-info=./debug_symbols "
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running flutter build $bundle $dart_define_args"
|
||||||
|
echo ""
|
||||||
|
flutter build $bundle $dart_define_args
|
||||||
|
|
||||||
|
echo "Flutter build $bundle finished"
|
|
@ -0,0 +1,28 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'detection_model.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
DetectionModel _$DetectionModelFromJson(Map<String, dynamic> json) =>
|
||||||
|
DetectionModel(
|
||||||
|
finalClasses: (json['finalClasses'] as List<dynamic>)
|
||||||
|
.map((e) => (e as num).toInt())
|
||||||
|
.toList(),
|
||||||
|
finalBboxes: (json['finalBboxes'] as List<dynamic>)
|
||||||
|
.map((e) =>
|
||||||
|
(e as List<dynamic>).map((e) => (e as num).toDouble()).toList())
|
||||||
|
.toList(),
|
||||||
|
finalScores: (json['finalScores'] as List<dynamic>)
|
||||||
|
.map((e) => (e as num).toDouble())
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$DetectionModelToJson(DetectionModel instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'finalClasses': instance.finalClasses,
|
||||||
|
'finalBboxes': instance.finalBboxes,
|
||||||
|
'finalScores': instance.finalScores,
|
||||||
|
};
|
|
@ -44,6 +44,10 @@ class DetectionResultWidget extends GetView<RecipeDetectionViewModel> {
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text('Bahan yang terdeteksi:', style: TTCommonsTextStyles.textMd.textBold(),),
|
child: Text('Bahan yang terdeteksi:', style: TTCommonsTextStyles.textMd.textBold(),),
|
||||||
),
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
|
child: Obx(() => Text(this.controller.detectionTime.value, style: TTCommonsTextStyles.textMd.textBold(),)),
|
||||||
|
),
|
||||||
Obx(() => ListView.builder(
|
Obx(() => ListView.builder(
|
||||||
itemCount: this.controller.detectedIngredients.length,
|
itemCount: this.controller.detectedIngredients.length,
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
|
|
|
@ -108,6 +108,7 @@ class RecipeDetectionView extends BaseView<RecipeDetectionViewModel> {
|
||||||
for (int i = 0; i < controller.bboxes.length; i++) {
|
for (int i = 0; i < controller.bboxes.length; i++) {
|
||||||
final box = controller.bboxes[i];
|
final box = controller.bboxes[i];
|
||||||
final boxClass = controller.classes[i];
|
final boxClass = controller.classes[i];
|
||||||
|
print("boxClass ${boxClass}");
|
||||||
bboxesWidgets.add(
|
bboxesWidgets.add(
|
||||||
Bbox(
|
Bbox(
|
||||||
box[0] * resizeFactor,
|
box[0] * resizeFactor,
|
||||||
|
|
|
@ -11,11 +11,15 @@ import 'package:snap_and_cook_mobile/routes/routes/main_route.dart';
|
||||||
import 'package:snap_and_cook_mobile/utils/detection/labels.dart';
|
import 'package:snap_and_cook_mobile/utils/detection/labels.dart';
|
||||||
|
|
||||||
import '../../../components/camera/custom_camera.dart';
|
import '../../../components/camera/custom_camera.dart';
|
||||||
|
import '../../../domain/use_case/utensils/utensil_use_case.dart';
|
||||||
import '../../../utils/detection/yolo.dart';
|
import '../../../utils/detection/yolo.dart';
|
||||||
import '../../base/base_view_model.dart';
|
import '../../base/base_view_model.dart';
|
||||||
|
|
||||||
class RecipeDetectionViewModel extends BaseViewModel {
|
class RecipeDetectionViewModel extends BaseViewModel {
|
||||||
RxList<Map<String, dynamic>> modelResults = RxList();
|
RxList<Map<String, dynamic>> modelResults = RxList();
|
||||||
|
final _utensilUseCase = UtensilUseCase();
|
||||||
|
|
||||||
|
|
||||||
Rxn<File> imageFile = Rxn<File>();
|
Rxn<File> imageFile = Rxn<File>();
|
||||||
RxnInt imageHeight = RxnInt();
|
RxnInt imageHeight = RxnInt();
|
||||||
RxnInt imageWidth = RxnInt();
|
RxnInt imageWidth = RxnInt();
|
||||||
|
@ -31,23 +35,21 @@ class RecipeDetectionViewModel extends BaseViewModel {
|
||||||
|
|
||||||
double maxImageWidgetHeight = 400;
|
double maxImageWidgetHeight = 400;
|
||||||
|
|
||||||
double confidenceThreshold = 0.20;
|
double confidenceThreshold = 0.25;
|
||||||
double iouThreshold = 0.1;
|
double iouThreshold = 0.40;
|
||||||
|
|
||||||
RxList<List<double>> inferenceOutput = RxList();
|
RxList<List<double>> inferenceOutput = RxList();
|
||||||
RxList<int> classes = RxList();
|
RxList<int> classes = RxList();
|
||||||
RxList<List<double>> bboxes = RxList();
|
RxList<List<double>> bboxes = RxList();
|
||||||
RxList<double> scores = RxList();
|
RxList<double> scores = RxList();
|
||||||
|
RxString detectionTime = RxString("");
|
||||||
// int? imageWidth;
|
|
||||||
// int? imageHeight;
|
|
||||||
|
|
||||||
Rxn<Uint8List> imageBytes = Rxn<Uint8List>();
|
Rxn<Uint8List> imageBytes = Rxn<Uint8List>();
|
||||||
DraggableScrollableController draggableScrollableController =
|
DraggableScrollableController draggableScrollableController =
|
||||||
DraggableScrollableController();
|
DraggableScrollableController();
|
||||||
|
|
||||||
final YoloModel model = YoloModel(
|
final YoloModel model = YoloModel(
|
||||||
'assets/yolov8.tflite',
|
'assets/yolov8s_snapcook.tflite',
|
||||||
inModelWidth,
|
inModelWidth,
|
||||||
inModelHeight,
|
inModelHeight,
|
||||||
numClasses,
|
numClasses,
|
||||||
|
@ -71,6 +73,11 @@ class RecipeDetectionViewModel extends BaseViewModel {
|
||||||
scores.clear();
|
scores.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> _isUtensilEmpty() async {
|
||||||
|
var utensils = await _utensilUseCase.fetchSelectedUtensils();
|
||||||
|
return utensils.isEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> updatePostProcess() async {
|
Future<void> updatePostProcess() async {
|
||||||
detectedIngredients.clear();
|
detectedIngredients.clear();
|
||||||
if (inferenceOutput.isEmpty) {
|
if (inferenceOutput.isEmpty) {
|
||||||
|
@ -128,6 +135,12 @@ class RecipeDetectionViewModel extends BaseViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> pickImage() async {
|
Future<void> pickImage() async {
|
||||||
|
var isEmpty = await _isUtensilEmpty();
|
||||||
|
if (isEmpty){
|
||||||
|
Get.snackbar("Peringatan", "Kamu belum memilih alat memasak");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
File? data = await Navigator.of(Get.context!).push(
|
File? data = await Navigator.of(Get.context!).push(
|
||||||
MaterialPageRoute<File>(
|
MaterialPageRoute<File>(
|
||||||
builder: (BuildContext context) =>
|
builder: (BuildContext context) =>
|
||||||
|
@ -153,7 +166,10 @@ class RecipeDetectionViewModel extends BaseViewModel {
|
||||||
|
|
||||||
imageHeight.value = image.height;
|
imageHeight.value = image.height;
|
||||||
imageWidth.value = image.width;
|
imageWidth.value = image.width;
|
||||||
|
int predictionTimeStart = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
|
||||||
inferenceOutput.value = await model.inferenceImage(image);
|
inferenceOutput.value = await model.inferenceImage(image);
|
||||||
|
detectionTime.value = "Prediction time: ${DateTime.now().millisecondsSinceEpoch - predictionTimeStart} ms";
|
||||||
closeLoadingDialog();
|
closeLoadingDialog();
|
||||||
|
|
||||||
updatePostProcess();
|
updatePostProcess();
|
||||||
|
@ -227,6 +243,8 @@ class RecipeDetectionViewModel extends BaseViewModel {
|
||||||
void removeIngredient(int index) {
|
void removeIngredient(int index) {
|
||||||
detectedIngredients.removeAt(index);
|
detectedIngredients.removeAt(index);
|
||||||
detectedIngredients.refresh();
|
detectedIngredients.refresh();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Future<Uint8List> drawOnImage(List<Map<String, dynamic>> modelResults) async {
|
// Future<Uint8List> drawOnImage(List<Map<String, dynamic>> modelResults) async {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
(List<int>, List<List<double>>, List<double>) nms(List<List<double>> rawOutput,
|
(List<int>, List<List<double>>, List<double>) nms(List<List<double>> rawOutput,
|
||||||
{double confidenceThreshold = 0.7, double iouThreshold = 0.4}) {
|
{double confidenceThreshold = 0.25, double iouThreshold = 0.4}) {
|
||||||
List<int> bestClasses = [];
|
List<int> bestClasses = [];
|
||||||
List<double> bestScores = [];
|
List<double> bestScores = [];
|
||||||
|
|
||||||
|
|
|
@ -75,8 +75,8 @@ class YoloModel {
|
||||||
List<List<double>> unfilteredBboxes,
|
List<List<double>> unfilteredBboxes,
|
||||||
int imageWidth,
|
int imageWidth,
|
||||||
int imageHeight, {
|
int imageHeight, {
|
||||||
double confidenceThreshold = 0.7,
|
double confidenceThreshold = 0.25,
|
||||||
double iouThreshold = 0.1,
|
double iouThreshold = 0.4,
|
||||||
}) async {
|
}) async {
|
||||||
List<int> classes;
|
List<int> classes;
|
||||||
List<List<double>> bboxes;
|
List<List<double>> bboxes;
|
||||||
|
@ -97,17 +97,4 @@ class YoloModel {
|
||||||
}
|
}
|
||||||
return (classes, bboxes, scores);
|
return (classes, bboxes, scores);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (List<int>, List<List<double>>, List<double>) inferAndPostprocess(
|
|
||||||
// Image image, {
|
|
||||||
// double confidenceThreshold = 0.7,
|
|
||||||
// double iouThreshold = 0.1,
|
|
||||||
// }) =>
|
|
||||||
// postprocess(
|
|
||||||
// infer(image),
|
|
||||||
// image.width,
|
|
||||||
// image.height,
|
|
||||||
// confidenceThreshold: confidenceThreshold,
|
|
||||||
// iouThreshold: iouThreshold,
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue