chore: suppression du code mort (détection auto, distorsion, ML Kit)
- Supprime 5 services inatteignables depuis l'UI (~3 000 lignes) : distortion_correction, image_processing, target_detection, opencv_impact_detection, target_rectify - AnalysisProvider allégé (835 -> ~360 lignes) : retrait de la détection par références, de la détection auto d'impacts, du workflow distorsion et du doublon moveShot - Retire les dépendances inutilisées google_mlkit_object_detection et google_mlkit_document_scanner du pubspec - Le bouton ↻ du Plotting efface désormais tous les impacts en un clic (clearShots) sans relancer la détection auto ni toucher la calibration - Nettoie les paramètres morts de TargetOverlay (referenceImpacts, onAddShot), le flag _isSelectingReferences, _buildActionButtons vide et le résidu _detectionTimer de capture_screen - Supprime le dossier tests/ (brouillons d'expérimentation OpenCV) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
/// Gestionnaire d'état pour l'analyse des cibles (ChangeNotifier).
|
||||
///
|
||||
/// Gère le workflow complet d'analyse : chargement d'image, détection de cible,
|
||||
/// gestion des impacts (manuels et automatiques), calcul des scores,
|
||||
/// analyse de groupement et sauvegarde des sessions.
|
||||
/// Gère le workflow complet d'analyse : chargement d'image, gestion des
|
||||
/// impacts placés manuellement, calcul des scores, analyse de groupement
|
||||
/// et sauvegarde des sessions.
|
||||
library;
|
||||
|
||||
import 'dart:io';
|
||||
@@ -13,37 +13,25 @@ import '../../data/models/target_analysis.dart';
|
||||
import '../../data/models/shot.dart';
|
||||
import '../../data/models/target_type.dart';
|
||||
import '../../data/repositories/session_repository.dart';
|
||||
import '../../services/target_detection_service.dart';
|
||||
import '../../services/score_calculator_service.dart';
|
||||
import '../../services/grouping_analyzer_service.dart';
|
||||
import '../../services/distortion_correction_service.dart';
|
||||
import '../../services/opencv_target_service.dart';
|
||||
import '../../services/ai_export_service.dart';
|
||||
|
||||
enum AnalysisState { initial, loading, success, error }
|
||||
|
||||
class AnalysisProvider extends ChangeNotifier {
|
||||
final TargetDetectionService _detectionService;
|
||||
final ScoreCalculatorService _scoreCalculatorService;
|
||||
final GroupingAnalyzerService _groupingAnalyzerService;
|
||||
final SessionRepository _sessionRepository;
|
||||
final DistortionCorrectionService _distortionService;
|
||||
final OpenCVTargetService _opencvTargetService;
|
||||
final Uuid _uuid = const Uuid();
|
||||
|
||||
AnalysisProvider({
|
||||
required TargetDetectionService detectionService,
|
||||
required ScoreCalculatorService scoreCalculatorService,
|
||||
required GroupingAnalyzerService groupingAnalyzerService,
|
||||
required SessionRepository sessionRepository,
|
||||
DistortionCorrectionService? distortionService,
|
||||
OpenCVTargetService? opencvTargetService,
|
||||
}) : _detectionService = detectionService,
|
||||
_scoreCalculatorService = scoreCalculatorService,
|
||||
}) : _scoreCalculatorService = scoreCalculatorService,
|
||||
_groupingAnalyzerService = groupingAnalyzerService,
|
||||
_sessionRepository = sessionRepository,
|
||||
_distortionService = distortionService ?? DistortionCorrectionService(),
|
||||
_opencvTargetService = opencvTargetService ?? OpenCVTargetService();
|
||||
_sessionRepository = sessionRepository;
|
||||
|
||||
AnalysisState _state = AnalysisState.initial;
|
||||
String? _errorMessage;
|
||||
@@ -53,7 +41,7 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
// AJOUT PROTECTION DU PLOTTING : Stockage permanent de la rotation du Crop
|
||||
double _cropRotation = 0.0;
|
||||
|
||||
// Target detection results
|
||||
// Target calibration
|
||||
double _targetCenterX = 0.5;
|
||||
double _targetCenterY = 0.5;
|
||||
double _targetRadius = 0.4;
|
||||
@@ -71,15 +59,6 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
// Grouping results
|
||||
GroupingResult? _groupingResult;
|
||||
|
||||
// Reference-based detection
|
||||
List<Shot> _referenceImpacts = [];
|
||||
ImpactCharacteristics? _learnedCharacteristics;
|
||||
|
||||
// Distortion correction
|
||||
bool _distortionCorrectionEnabled = false;
|
||||
DistortionParameters? _distortionParams;
|
||||
String? _correctedImagePath;
|
||||
|
||||
// Getters
|
||||
AnalysisState get state => _state;
|
||||
String? get errorMessage => _errorMessage;
|
||||
@@ -100,21 +79,6 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
|
||||
int get totalScore => _scoreResult?.totalScore ?? 0;
|
||||
int get shotCount => _shots.length;
|
||||
List<Shot> get referenceImpacts => List.unmodifiable(_referenceImpacts);
|
||||
ImpactCharacteristics? get learnedCharacteristics => _learnedCharacteristics;
|
||||
bool get hasLearnedCharacteristics => _learnedCharacteristics != null;
|
||||
|
||||
// Distortion correction getters
|
||||
bool get distortionCorrectionEnabled => _distortionCorrectionEnabled;
|
||||
DistortionParameters? get distortionParams => _distortionParams;
|
||||
String? get correctedImagePath => _correctedImagePath;
|
||||
bool get hasDistortion => _distortionParams?.needsCorrection ?? false;
|
||||
|
||||
/// Retourne le chemin de l'image à afficher (corrigée si activée, originale sinon)
|
||||
String? get displayImagePath =>
|
||||
_distortionCorrectionEnabled && _correctedImagePath != null
|
||||
? _correctedImagePath
|
||||
: _imagePath;
|
||||
|
||||
/// Modifie et mémorise la rotation de l'image pour le Plotting
|
||||
void setCropRotation(double rotation) {
|
||||
@@ -122,16 +86,13 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Analyze an image
|
||||
///
|
||||
/// [autoAnalyze] determines if we should run automatic detection immediately.
|
||||
/// If false, only the image is loaded and default target parameters are set.
|
||||
/// Charge l'image et initialise les paramètres de cible par défaut.
|
||||
/// Le placement des impacts et la calibration se font ensuite manuellement.
|
||||
Future<void> analyzeImage(
|
||||
String imagePath,
|
||||
TargetType targetType, {
|
||||
bool autoAnalyze = true,
|
||||
Offset? manualCenter,
|
||||
}) async {
|
||||
String imagePath,
|
||||
TargetType targetType, {
|
||||
Offset? manualCenter,
|
||||
}) async {
|
||||
_state = AnalysisState.loading;
|
||||
_imagePath = imagePath;
|
||||
_targetType = targetType;
|
||||
@@ -147,54 +108,12 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
_imageAspectRatio = frame.image.width / frame.image.height;
|
||||
frame.image.dispose();
|
||||
|
||||
if (!autoAnalyze) {
|
||||
// Just setup default values without running detection
|
||||
_targetCenterX = manualCenter?.dx ?? 0.5;
|
||||
_targetCenterY = manualCenter?.dy ?? 0.5;
|
||||
_targetRadius = 0.4;
|
||||
_targetInnerRadius = 0.04;
|
||||
_targetCenterX = manualCenter?.dx ?? 0.5;
|
||||
_targetCenterY = manualCenter?.dy ?? 0.5;
|
||||
_targetRadius = 0.4;
|
||||
_targetInnerRadius = 0.04;
|
||||
|
||||
// Initialize empty shots list
|
||||
_shots = [];
|
||||
|
||||
_state = AnalysisState.success;
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
|
||||
final result = await _detectionService.detectTargetAsync(
|
||||
imagePath,
|
||||
targetType,
|
||||
);
|
||||
|
||||
if (!result.success) {
|
||||
_state = AnalysisState.error;
|
||||
_errorMessage = result.errorMessage;
|
||||
notifyListeners();
|
||||
return;
|
||||
}
|
||||
|
||||
_targetCenterX = result.centerX;
|
||||
_targetCenterY = result.centerY;
|
||||
_targetRadius = result.radius;
|
||||
_targetInnerRadius = result.radius * 0.1;
|
||||
|
||||
// Create shots from detected impacts
|
||||
_shots = result.impacts.map((impact) {
|
||||
return Shot(
|
||||
id: _uuid.v4(),
|
||||
x: impact.x,
|
||||
y: impact.y,
|
||||
score: impact.suggestedScore,
|
||||
analysisId: '',
|
||||
);
|
||||
}).toList();
|
||||
|
||||
// Calculate scores
|
||||
_recalculateScores();
|
||||
|
||||
// Calculate grouping
|
||||
_recalculateGrouping();
|
||||
_shots = [];
|
||||
|
||||
_state = AnalysisState.success;
|
||||
notifyListeners();
|
||||
@@ -216,22 +135,18 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Remove a shot
|
||||
void removeShot(String shotId) {
|
||||
_shots.removeWhere((shot) => shot.id == shotId);
|
||||
/// Efface tous les impacts en un clic (bouton ↻ de l'écran Plotting).
|
||||
/// La calibration (centre, rayon, anneaux) n'est pas touchée.
|
||||
void clearShots() {
|
||||
_shots.clear();
|
||||
_recalculateScores();
|
||||
_recalculateGrouping();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Move a shot to a new position
|
||||
void moveShot(String shotId, double newX, double newY) {
|
||||
final index = _shots.indexWhere((shot) => shot.id == shotId);
|
||||
if (index == -1) return;
|
||||
|
||||
final newScore = _calculateShotScore(newX, newY);
|
||||
_shots[index] = _shots[index].copyWith(x: newX, y: newY, score: newScore);
|
||||
|
||||
/// Remove a shot
|
||||
void removeShot(String shotId) {
|
||||
_shots.removeWhere((shot) => shot.id == shotId);
|
||||
_recalculateScores();
|
||||
_recalculateGrouping();
|
||||
notifyListeners();
|
||||
@@ -247,276 +162,17 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Auto-detect impacts using image processing
|
||||
Future<int> autoDetectImpacts({
|
||||
int darkThreshold = 80,
|
||||
int minImpactSize = 20,
|
||||
int maxImpactSize = 500,
|
||||
double minCircularity = 0.6,
|
||||
double minFillRatio = 0.5,
|
||||
bool clearExisting = false,
|
||||
}) async {
|
||||
if (_imagePath == null || _targetType == null) return 0;
|
||||
|
||||
final settings = ImpactDetectionSettings(
|
||||
darkThreshold: darkThreshold,
|
||||
minImpactSize: minImpactSize,
|
||||
maxImpactSize: maxImpactSize,
|
||||
minCircularity: minCircularity,
|
||||
minFillRatio: minFillRatio,
|
||||
);
|
||||
|
||||
final detectedImpacts = _detectionService.detectImpactsOnly(
|
||||
_imagePath!,
|
||||
_targetType!,
|
||||
_targetCenterX,
|
||||
_targetCenterY,
|
||||
_targetRadius,
|
||||
_ringCount,
|
||||
settings,
|
||||
);
|
||||
|
||||
if (clearExisting) {
|
||||
_shots.clear();
|
||||
}
|
||||
|
||||
// Add detected impacts as shots
|
||||
for (final impact in detectedImpacts) {
|
||||
final score = _calculateShotScore(impact.x, impact.y);
|
||||
final shot = Shot(
|
||||
id: _uuid.v4(),
|
||||
x: impact.x,
|
||||
y: impact.y,
|
||||
score: score,
|
||||
analysisId: '',
|
||||
);
|
||||
_shots.add(shot);
|
||||
}
|
||||
|
||||
_recalculateScores();
|
||||
_recalculateGrouping();
|
||||
notifyListeners();
|
||||
|
||||
return detectedImpacts.length;
|
||||
}
|
||||
|
||||
/// Auto-detect impacts using OpenCV (Hough Circles + Contours)
|
||||
Future<int> autoDetectImpactsWithOpenCV({
|
||||
double cannyThreshold1 = 50,
|
||||
double cannyThreshold2 = 150,
|
||||
double minDist = 20,
|
||||
double param1 = 100,
|
||||
double param2 = 30,
|
||||
int minRadius = 5,
|
||||
int maxRadius = 50,
|
||||
int minSize = 5,
|
||||
int maxSize = 1000,
|
||||
int blurSize = 5,
|
||||
bool useContourDetection = true,
|
||||
double minCircularity = 0.6,
|
||||
double minContourArea = 50,
|
||||
double maxContourArea = 5000,
|
||||
bool clearExisting = false,
|
||||
}) async {
|
||||
if (_imagePath == null || _targetType == null) return 0;
|
||||
|
||||
final settings = OpenCVDetectionSettings(
|
||||
cannyThreshold1: cannyThreshold1,
|
||||
cannyThreshold2: cannyThreshold2,
|
||||
minDist: minDist,
|
||||
param1: param1,
|
||||
param2: param2,
|
||||
minRadius: minRadius,
|
||||
maxRadius: maxRadius,
|
||||
blurSize: blurSize,
|
||||
useContourDetection: useContourDetection,
|
||||
minCircularity: minCircularity,
|
||||
minContourArea: minContourArea,
|
||||
maxContourArea: maxContourArea,
|
||||
);
|
||||
|
||||
final detectedImpacts = _detectionService.detectImpactsWithOpenCV(
|
||||
_imagePath!,
|
||||
_targetType!,
|
||||
_targetCenterX,
|
||||
_targetCenterY,
|
||||
_targetRadius,
|
||||
_ringCount,
|
||||
settings: settings,
|
||||
);
|
||||
|
||||
if (clearExisting) {
|
||||
_shots.clear();
|
||||
}
|
||||
|
||||
// Add detected impacts as shots
|
||||
for (final impact in detectedImpacts) {
|
||||
final score = _calculateShotScore(impact.x, impact.y);
|
||||
final shot = Shot(
|
||||
id: _uuid.v4(),
|
||||
x: impact.x,
|
||||
y: impact.y,
|
||||
score: score,
|
||||
analysisId: '',
|
||||
);
|
||||
_shots.add(shot);
|
||||
}
|
||||
|
||||
_recalculateScores();
|
||||
_recalculateGrouping();
|
||||
notifyListeners();
|
||||
|
||||
return detectedImpacts.length;
|
||||
}
|
||||
|
||||
/// Detect impacts with OpenCV using reference points
|
||||
Future<int> detectFromReferencesWithOpenCV({
|
||||
double tolerance = 2.0,
|
||||
bool clearExisting = false,
|
||||
}) async {
|
||||
if (_imagePath == null ||
|
||||
_targetType == null ||
|
||||
_referenceImpacts.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convertir les références
|
||||
final references = _referenceImpacts
|
||||
.map((shot) => ReferenceImpact(x: shot.x, y: shot.y))
|
||||
.toList();
|
||||
|
||||
final detectedImpacts = _detectionService
|
||||
.detectImpactsWithOpenCVFromReferences(
|
||||
_imagePath!,
|
||||
_targetType!,
|
||||
_targetCenterX,
|
||||
_targetCenterY,
|
||||
_targetRadius,
|
||||
_ringCount,
|
||||
references,
|
||||
tolerance: tolerance,
|
||||
);
|
||||
|
||||
if (clearExisting) {
|
||||
_shots.clear();
|
||||
}
|
||||
|
||||
// Add detected impacts as shots
|
||||
for (final impact in detectedImpacts) {
|
||||
final score = _calculateShotScore(impact.x, impact.y);
|
||||
final shot = Shot(
|
||||
id: _uuid.v4(),
|
||||
x: impact.x,
|
||||
y: impact.y,
|
||||
score: score,
|
||||
analysisId: '',
|
||||
);
|
||||
_shots.add(shot);
|
||||
}
|
||||
|
||||
_recalculateScores();
|
||||
_recalculateGrouping();
|
||||
notifyListeners();
|
||||
|
||||
return detectedImpacts.length;
|
||||
}
|
||||
|
||||
/// Add a reference impact for calibrated detection
|
||||
void addReferenceImpact(double x, double y) {
|
||||
final score = _calculateShotScore(x, y);
|
||||
final shot = Shot(id: _uuid.v4(), x: x, y: y, score: score, analysisId: '');
|
||||
_referenceImpacts.add(shot);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Remove a reference impact
|
||||
void removeReferenceImpact(String shotId) {
|
||||
_referenceImpacts.removeWhere((shot) => shot.id == shotId);
|
||||
_learnedCharacteristics = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Clear all reference impacts
|
||||
void clearReferenceImpacts() {
|
||||
_referenceImpacts.clear();
|
||||
_learnedCharacteristics = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Learn characteristics from reference impacts
|
||||
bool learnFromReferences() {
|
||||
if (_imagePath == null || _referenceImpacts.length < 2) return false;
|
||||
|
||||
final references = _referenceImpacts
|
||||
.map((shot) => ReferenceImpact(x: shot.x, y: shot.y))
|
||||
.toList();
|
||||
|
||||
_learnedCharacteristics = _detectionService.analyzeReferenceImpacts(
|
||||
_imagePath!,
|
||||
references,
|
||||
);
|
||||
|
||||
notifyListeners();
|
||||
return _learnedCharacteristics != null;
|
||||
}
|
||||
|
||||
/// Auto-detect impacts using learned reference characteristics
|
||||
Future<int> detectFromReferences({
|
||||
double tolerance = 2.0,
|
||||
bool clearExisting = false,
|
||||
}) async {
|
||||
if (_imagePath == null ||
|
||||
_targetType == null ||
|
||||
_learnedCharacteristics == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final detectedImpacts = _detectionService.detectImpactsFromReferences(
|
||||
_imagePath!,
|
||||
_targetType!,
|
||||
_targetCenterX,
|
||||
_targetCenterY,
|
||||
_targetRadius,
|
||||
_ringCount,
|
||||
_learnedCharacteristics!,
|
||||
tolerance: tolerance,
|
||||
);
|
||||
|
||||
if (clearExisting) {
|
||||
_shots.clear();
|
||||
}
|
||||
|
||||
// Add detected impacts as shots
|
||||
for (final impact in detectedImpacts) {
|
||||
final score = _calculateShotScore(impact.x, impact.y);
|
||||
final shot = Shot(
|
||||
id: _uuid.v4(),
|
||||
x: impact.x,
|
||||
y: impact.y,
|
||||
score: score,
|
||||
analysisId: '',
|
||||
);
|
||||
_shots.add(shot);
|
||||
}
|
||||
|
||||
_recalculateScores();
|
||||
_recalculateGrouping();
|
||||
notifyListeners();
|
||||
|
||||
return detectedImpacts.length;
|
||||
}
|
||||
|
||||
/// Adjust target position
|
||||
void adjustTargetPosition(
|
||||
double centerX,
|
||||
double centerY,
|
||||
double innerRadius,
|
||||
double radius, {
|
||||
int? ringCount,
|
||||
List<double>? ringRadii,
|
||||
double zoomScale = 1.0,
|
||||
Offset offset = Offset.zero,
|
||||
}) {
|
||||
double centerX,
|
||||
double centerY,
|
||||
double innerRadius,
|
||||
double radius, {
|
||||
int? ringCount,
|
||||
List<double>? ringRadii,
|
||||
double zoomScale = 1.0,
|
||||
Offset offset = Offset.zero,
|
||||
}) {
|
||||
_targetCenterX = (centerX - offset.dx) / zoomScale;
|
||||
_targetCenterY = (centerY - offset.dy) / zoomScale;
|
||||
_targetRadius = radius / zoomScale;
|
||||
@@ -539,118 +195,6 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Auto-calibrate target using OpenCV
|
||||
Future<bool> autoCalibrateTarget() async {
|
||||
if (_imagePath == null) return false;
|
||||
|
||||
try {
|
||||
// 1. Attempt to correct perspective/distortion first
|
||||
final correctedPath = await _distortionService
|
||||
.correctPerspectiveWithConcentricMesh(_imagePath!);
|
||||
|
||||
if (correctedPath != _imagePath) {
|
||||
_imagePath = correctedPath;
|
||||
_correctedImagePath = correctedPath;
|
||||
_distortionCorrectionEnabled = true;
|
||||
_imageAspectRatio = 1.0;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
// 2. Detect the target on the straight/corrected image
|
||||
final result = await _opencvTargetService.detectTarget(_imagePath!);
|
||||
|
||||
if (result.success) {
|
||||
adjustTargetPosition(
|
||||
result.centerX,
|
||||
result.centerY,
|
||||
result.radius * 0.1,
|
||||
result.radius,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (e) {
|
||||
debugPrint('Auto-calibration error: $e');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Calcule les paramètres de distorsion basés sur la calibration actuelle
|
||||
void calculateDistortion() {
|
||||
_distortionParams = _distortionService.calculateDistortionFromCalibration(
|
||||
targetCenterX: _targetCenterX,
|
||||
targetCenterY: _targetCenterY,
|
||||
targetRadius: _targetRadius,
|
||||
imageAspectRatio: _imageAspectRatio,
|
||||
);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Applique la correction de distorsion à l'image
|
||||
/// Crée une nouvelle image corrigée et la sauvegarde
|
||||
Future<void> applyDistortionCorrection() async {
|
||||
if (_imagePath == null || _distortionParams == null) return;
|
||||
|
||||
try {
|
||||
_correctedImagePath = await _distortionService.applyCorrection(
|
||||
_imagePath!,
|
||||
_distortionParams!,
|
||||
);
|
||||
_distortionCorrectionEnabled = true;
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
_errorMessage = 'Erreur lors de la correction: $e';
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/// Active ou désactive l'affichage de l'image corrigée
|
||||
void setDistortionCorrectionEnabled(bool enabled) {
|
||||
if (enabled && _correctedImagePath == null && _distortionParams != null) {
|
||||
// Si on active mais pas encore d'image corrigée, la créer
|
||||
applyDistortionCorrection();
|
||||
} else {
|
||||
_distortionCorrectionEnabled = enabled;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
/// Calcule ET applique la correction pour un feedback immédiat
|
||||
Future<void> calculateAndApplyDistortion() async {
|
||||
// 1. Calcul des paramètres (votre code actuel)
|
||||
_distortionParams = _distortionService.calculateDistortionFromCalibration(
|
||||
targetCenterX: _targetCenterX,
|
||||
targetCenterY: _targetCenterY,
|
||||
targetRadius: _targetRadius,
|
||||
imageAspectRatio: _imageAspectRatio,
|
||||
);
|
||||
|
||||
// 2. Vérification si une correction est réellement nécessaire
|
||||
if (_distortionParams != null && _distortionParams!.needsCorrection) {
|
||||
// 3. Application immédiate de la transformation (méthode asynchrone)
|
||||
await applyDistortionCorrection();
|
||||
} else {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> runFullDistortionWorkflow() async {
|
||||
_state = AnalysisState.loading;
|
||||
notifyListeners();
|
||||
|
||||
try {
|
||||
calculateDistortion();
|
||||
await applyDistortionCorrection();
|
||||
_distortionCorrectionEnabled = true;
|
||||
_state = AnalysisState.success;
|
||||
} catch (e) {
|
||||
_errorMessage = "Erreur de rendu : $e";
|
||||
_state = AnalysisState.error;
|
||||
} finally {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
|
||||
int _calculateShotScore(double x, double y) {
|
||||
if (_targetType == TargetType.concentric) {
|
||||
return _scoreCalculatorService.calculateConcentricScore(
|
||||
@@ -807,11 +351,6 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
_shots = [];
|
||||
_scoreResult = null;
|
||||
_groupingResult = null;
|
||||
_referenceImpacts = [];
|
||||
_learnedCharacteristics = null;
|
||||
_distortionCorrectionEnabled = false;
|
||||
_distortionParams = null;
|
||||
_correctedImagePath = null;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -833,4 +372,4 @@ class AnalysisProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user