ajout correction de distotion d'image
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user