ajout correction de distotion d'image

This commit is contained in:
2026-01-18 21:32:42 +01:00
parent 6b0cb8f837
commit f1a8eefdc3
3 changed files with 543 additions and 3 deletions

View File

@@ -16,6 +16,7 @@ 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';
enum AnalysisState { initial, loading, success, error }
@@ -24,6 +25,7 @@ class AnalysisProvider extends ChangeNotifier {
final ScoreCalculatorService _scoreCalculatorService;
final GroupingAnalyzerService _groupingAnalyzerService;
final SessionRepository _sessionRepository;
final DistortionCorrectionService _distortionService;
final Uuid _uuid = const Uuid();
AnalysisProvider({
@@ -31,10 +33,12 @@ class AnalysisProvider extends ChangeNotifier {
required ScoreCalculatorService scoreCalculatorService,
required GroupingAnalyzerService groupingAnalyzerService,
required SessionRepository sessionRepository,
DistortionCorrectionService? distortionService,
}) : _detectionService = detectionService,
_scoreCalculatorService = scoreCalculatorService,
_groupingAnalyzerService = groupingAnalyzerService,
_sessionRepository = sessionRepository;
_sessionRepository = sessionRepository,
_distortionService = distortionService ?? DistortionCorrectionService();
AnalysisState _state = AnalysisState.initial;
String? _errorMessage;
@@ -62,6 +66,11 @@ class AnalysisProvider extends ChangeNotifier {
List<Shot> _referenceImpacts = [];
ImpactCharacteristics? _learnedCharacteristics;
// Distortion correction
bool _distortionCorrectionEnabled = false;
DistortionParameters? _distortionParams;
String? _correctedImagePath;
// Getters
AnalysisState get state => _state;
String? get errorMessage => _errorMessage;
@@ -83,6 +92,16 @@ class AnalysisProvider extends ChangeNotifier {
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;
/// Analyze an image
Future<void> analyzeImage(String imagePath, TargetType targetType) async {
_state = AnalysisState.loading;
@@ -346,6 +365,46 @@ class AnalysisProvider extends ChangeNotifier {
notifyListeners();
}
/// 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();
}
}
int _calculateShotScore(double x, double y) {
if (_targetType == TargetType.concentric) {
return _scoreCalculatorService.calculateConcentricScore(
@@ -433,6 +492,9 @@ class AnalysisProvider extends ChangeNotifier {
_groupingResult = null;
_referenceImpacts = [];
_learnedCharacteristics = null;
_distortionCorrectionEnabled = false;
_distortionParams = null;
_correctedImagePath = null;
notifyListeners();
}
}

View File

@@ -316,6 +316,61 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
),
],
),
const Divider(color: Colors.white24, height: 16),
// Distortion correction row
Row(
children: [
const Icon(Icons.lens_blur, color: Colors.white, size: 20),
const SizedBox(width: 8),
const Expanded(
child: Text('Correction distorsion:', style: TextStyle(color: Colors.white)),
),
if (provider.distortionParams == null)
ElevatedButton.icon(
onPressed: () {
provider.calculateDistortion();
},
icon: const Icon(Icons.calculate, size: 16),
label: const Text('Calculer'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
),
)
else ...[
if (provider.correctedImagePath == null)
ElevatedButton.icon(
onPressed: () {
provider.applyDistortionCorrection();
},
icon: const Icon(Icons.auto_fix_high, size: 16),
label: const Text('Appliquer'),
style: ElevatedButton.styleFrom(
backgroundColor: AppTheme.primaryColor,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
),
)
else
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.check_circle, color: Colors.green, size: 16),
const SizedBox(width: 4),
const Text('Corrigée', style: TextStyle(color: Colors.green, fontSize: 12)),
const SizedBox(width: 8),
Switch(
value: provider.distortionCorrectionEnabled,
onChanged: (value) => provider.setDistortionCorrectionEnabled(value),
activeTrackColor: AppTheme.primaryColor.withValues(alpha: 0.5),
activeThumbColor: AppTheme.primaryColor,
),
],
),
],
],
),
],
),
),
@@ -465,7 +520,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
fit: StackFit.expand,
children: [
Image.file(
File(provider.imagePath!),
File(provider.displayImagePath!),
fit: BoxFit.fill,
key: _imageKey,
),
@@ -534,7 +589,7 @@ class _AnalysisScreenContentState extends State<_AnalysisScreenContent> {
fit: StackFit.expand,
children: [
Image.file(
File(provider.imagePath!),
File(provider.displayImagePath!),
fit: BoxFit.fill,
key: _imageKey,
),