1919package com .github .mfl28 .boundingboxeditor .controller ;
2020
2121import com .github .mfl28 .boundingboxeditor .model .Model ;
22- import com .github .mfl28 .boundingboxeditor .model .data .ImageAnnotation ;
23- import com .github .mfl28 .boundingboxeditor .model .data .ImageMetaData ;
24- import com .github .mfl28 .boundingboxeditor .model .data .IoMetaData ;
25- import com .github .mfl28 .boundingboxeditor .model .data .ObjectCategory ;
26- import com .github .mfl28 .boundingboxeditor .model .io .FileChangeWatcher ;
27- import com .github .mfl28 .boundingboxeditor .model .io .ImageAnnotationLoadStrategy ;
28- import com .github .mfl28 .boundingboxeditor .model .io .ImageAnnotationSaveStrategy ;
22+ import com .github .mfl28 .boundingboxeditor .model .data .*;
23+ import com .github .mfl28 .boundingboxeditor .model .io .*;
24+ import com .github .mfl28 .boundingboxeditor .model .io .results .BoundingBoxPredictionResult ;
2925import com .github .mfl28 .boundingboxeditor .model .io .results .IOResult ;
3026import com .github .mfl28 .boundingboxeditor .model .io .results .ImageAnnotationImportResult ;
3127import com .github .mfl28 .boundingboxeditor .model .io .results .ImageMetaDataLoadingResult ;
28+ import com .github .mfl28 .boundingboxeditor .model .io .services .BoundingBoxPredictorService ;
3229import com .github .mfl28 .boundingboxeditor .model .io .services .ImageAnnotationExportService ;
3330import com .github .mfl28 .boundingboxeditor .model .io .services .ImageAnnotationImportService ;
3431import com .github .mfl28 .boundingboxeditor .model .io .services .ImageMetaDataLoadingService ;
3532import com .github .mfl28 .boundingboxeditor .ui .*;
33+ import com .github .mfl28 .boundingboxeditor .ui .statusevents .BoundingBoxPredictionSuccessfulEvent ;
3634import com .github .mfl28 .boundingboxeditor .ui .statusevents .ImageAnnotationsImportingSuccessfulEvent ;
3735import com .github .mfl28 .boundingboxeditor .ui .statusevents .ImageAnnotationsSavingSuccessfulEvent ;
3836import com .github .mfl28 .boundingboxeditor .ui .statusevents .ImageFilesLoadingSuccessfulEvent ;
@@ -99,13 +97,9 @@ public class Controller {
9997 private static final String SAVE_IMAGE_ANNOTATIONS_ERROR_DIALOG_TITLE = "Save Error" ;
10098 private static final String NO_IMAGE_ANNOTATIONS_TO_SAVE_ERROR_DIALOG_CONTENT =
10199 "There are no image annotations to save." ;
102- private static final String SAVING_ANNOTATIONS_PROGRESS_DIALOG_TITLE = "Saving Annotations" ;
103- private static final String SAVING_ANNOTATIONS_PROGRESS_DIALOGUE_HEADER = "Saving in progress..." ;
104100 private static final String ANNOTATION_IMPORT_ERROR_TITLE = "Annotation Import Error" ;
105101 private static final String ANNOTATION_IMPORT_ERROR_NO_VALID_FILES_CONTENT =
106102 "The source does not contain any valid annotations." ;
107- private static final String LOADING_ANNOTATIONS_DIALOG_TITLE = "Loading" ;
108- private static final String LOADING_ANNOTATIONS_DIALOG_HEADER = "Loading annotations..." ;
109103 private static final String OPEN_IMAGE_FOLDER_OPTION_DIALOG_TITLE = "Open image folder" ;
110104 private static final String OPEN_IMAGE_FOLDER_OPTION_DIALOG_CONTENT =
111105 "Opening a new image folder will remove any existing annotation data. " +
@@ -136,15 +130,15 @@ public class Controller {
136130 private static final String IMAGE_IMPORT_ERROR_ALERT_TITLE = "Image Import Error" ;
137131 private static final String IMAGE_IMPORT_ERROR_ALERT_CONTENT =
138132 "The folder does not contain any valid image files." ;
139- private static final String IMAGE_FILES_LOADING_DIALOG_TITLE = "Loading images" ;
140- private static final String IMAGE_FILES_LOADING_DIALOG_HEADER = "Loading image meta-data" ;
141133 private static final String IMAGE_FILES_CHANGED_ERROR_TITLE = "Image files changed" ;
142134 private static final String IMAGE_FILES_CHANGED_ERROR_CONTENT =
143135 "Image files were changed externally, will reload folder." ;
144136 private static final String IMAGE_FILE_CHANGE_WATCHER_THREAD_NAME = "ImageFileChangeWatcher" ;
137+
145138 private final ImageAnnotationExportService annotationExportService = new ImageAnnotationExportService ();
146139 private final ImageAnnotationImportService annotationImportService = new ImageAnnotationImportService ();
147140 private final ImageMetaDataLoadingService imageMetaDataLoadingService = new ImageMetaDataLoadingService ();
141+ private final BoundingBoxPredictorService boundingBoxPredictorService = new BoundingBoxPredictorService ();
148142 private final Stage stage ;
149143 private final MainView view = new MainView ();
150144 private final Model model = new Model ();
@@ -179,6 +173,15 @@ public Controller(final Stage mainStage) {
179173 view .connectToController (this );
180174 setUpModelListeners ();
181175 setUpServices ();
176+ connectServicesToView ();
177+ }
178+
179+ private void connectServicesToView () {
180+ view .connectAnnotationImportService (annotationImportService );
181+ view .connectAnnotationExportService (annotationExportService );
182+ view .connectImageMetaDataLoadingService (imageMetaDataLoadingService );
183+ view .connectBoundingBoxPredictorService (boundingBoxPredictorService );
184+ view .setUpProgressDialogs ();
182185 }
183186
184187 /**
@@ -194,6 +197,14 @@ public void onRegisterOpenImageFolderAction() {
194197 }
195198 }
196199
200+ public void onRegisterPerformCurrentImageBoundingBoxPredictionAction () {
201+ if (model .containsImageFiles ()) {
202+ initiateBoundingBoxPrediction (model .getCurrentImageFile ());
203+ } else {
204+ // TODO: Error handling
205+ }
206+ }
207+
197208 /**
198209 * Initiates the loading of image files from a provided folder.
199210 *
@@ -305,6 +316,11 @@ public void initiateAnnotationImport(File source, ImageAnnotationLoadStrategy.Ty
305316 startAnnotationImportService (source , loadFormat );
306317 }
307318
319+ public void initiateBoundingBoxPrediction (File imageFile ) {
320+ updateModelFromView ();
321+ startBoundingBoxPredictionService (imageFile );
322+ }
323+
308324 /**
309325 * Handles the event of the user adding a new object category.
310326 */
@@ -555,6 +571,35 @@ public Model getModel() {
555571 return model ;
556572 }
557573
574+ private void onBoundingBoxPredictionSucceeded (WorkerStateEvent event ) {
575+ final BoundingBoxPredictionResult predictionResult = boundingBoxPredictorService .getValue ();
576+
577+ if (predictionResult .getNrSuccessfullyProcessedItems () != 0 ) {
578+ model .updateFromImageAnnotationData (predictionResult .getImageAnnotationData ());
579+ view .getStatusBar ().setStatusEvent (new BoundingBoxPredictionSuccessfulEvent (predictionResult ));
580+ }
581+
582+ updateViewFileExplorerFileInfoElements ();
583+
584+ final ImageAnnotation annotation = model .getCurrentImageAnnotation ();
585+
586+ if (annotation != null ) {
587+ view .getObjectTree ().reset ();
588+ view .getCurrentBoundingShapes ().removeListener (boundingShapeCountPerCategoryListener );
589+ view .loadBoundingShapeViewsFromAnnotation (annotation );
590+ view .getCurrentBoundingShapes ().addListener (boundingShapeCountPerCategoryListener );
591+ view .getObjectCategoryTable ().refresh ();
592+ view .getObjectTree ().refresh ();
593+ }
594+
595+ if (!predictionResult .getErrorTableEntries ().isEmpty ()) {
596+ MainView .displayIOResultErrorInfoAlert (predictionResult );
597+ } else if (predictionResult .getNrSuccessfullyProcessedItems () == 0 ) {
598+ MainView .displayErrorAlert ("Bounding Box Prediction Error" ,
599+ "Could not predict any bounding boxes." );
600+ }
601+ }
602+
558603 IoMetaData getIoMetaData () {
559604 return ioMetaData ;
560605 }
@@ -578,13 +623,11 @@ Stage getStage() {
578623 void initiateAnnotationExport (File destination ,
579624 ImageAnnotationSaveStrategy .Type exportFormat ,
580625 Runnable chainedOperation ) {
626+ annotationExportService .reset ();
581627 annotationExportService .setDestination (destination );
582628 annotationExportService .setExportFormat (exportFormat );
583629 annotationExportService .setAnnotationData (model .createImageAnnotationData ());
584630 annotationExportService .setChainedOperation (chainedOperation );
585- annotationExportService .reset ();
586- MainView .displayServiceProgressDialog (annotationExportService , SAVING_ANNOTATIONS_PROGRESS_DIALOG_TITLE ,
587- SAVING_ANNOTATIONS_PROGRESS_DIALOGUE_HEADER );
588631 annotationExportService .restart ();
589632 }
590633
@@ -598,10 +641,6 @@ private void startAnnotationImportService(File source, ImageAnnotationLoadStrate
598641 annotationImportService .setImportFormat (importFormat );
599642 annotationImportService .setImportableFileNames (model .getImageFileNameSet ());
600643 annotationImportService .setCategoryNameToCategoryMap (model .getCategoryNameToCategoryMap ());
601-
602- MainView .displayServiceProgressDialog (annotationImportService , LOADING_ANNOTATIONS_DIALOG_TITLE ,
603- LOADING_ANNOTATIONS_DIALOG_HEADER );
604-
605644 annotationImportService .restart ();
606645 }
607646
@@ -610,12 +649,23 @@ private void startImageMetaDataLoadingService(File source, List<File> imageFiles
610649 imageMetaDataLoadingService .setSource (source );
611650 imageMetaDataLoadingService .setImageFiles (imageFiles );
612651 imageMetaDataLoadingService .setReload (reload );
613- MainView .displayServiceProgressDialog (imageMetaDataLoadingService , IMAGE_FILES_LOADING_DIALOG_TITLE ,
614- IMAGE_FILES_LOADING_DIALOG_HEADER );
615-
616652 imageMetaDataLoadingService .restart ();
617653 }
618654
655+ private void startBoundingBoxPredictionService (File imageFile ) {
656+ boundingBoxPredictorService .reset ();
657+ boundingBoxPredictorService .setImageFile (imageFile );
658+ boundingBoxPredictorService .setCategoryNameToCategoryMap (model .getCategoryNameToCategoryMap ());
659+ boundingBoxPredictorService .setImageMetaData (model .getImageFileNameToMetaDataMap ().get (imageFile .getName ()));
660+ boundingBoxPredictorService .setBoundingBoxPredictorConfig (model .getBoundingBoxPredictorConfig ());
661+
662+ model .getBoundingBoxPredictorClientConfig ().setInferenceModelName ("fastrcnn" );
663+
664+ boundingBoxPredictorService .setPredictorClient (BoundingBoxPredictorClient .create (model .getBoundingBoxPredictorClientConfig ()));
665+
666+ boundingBoxPredictorService .restart ();
667+ }
668+
619669 private void setUpServices () {
620670 annotationExportService .setOnSucceeded (this ::onAnnotationExportSucceeded );
621671 annotationExportService .setOnFailed (this ::onIoServiceFailed );
@@ -625,6 +675,9 @@ private void setUpServices() {
625675
626676 imageMetaDataLoadingService .setOnSucceeded (this ::onImageMetaDataLoadingSucceeded );
627677 imageMetaDataLoadingService .setOnFailed (this ::onIoServiceFailed );
678+
679+ boundingBoxPredictorService .setOnSucceeded (this ::onBoundingBoxPredictionSucceeded );
680+ boundingBoxPredictorService .setOnFailed (this ::onIoServiceFailed );
628681 }
629682
630683 private void onImageMetaDataLoadingSucceeded (WorkerStateEvent workerStateEvent ) {
0 commit comments