diff --git a/src/main/java/com/github/mfl28/boundingboxeditor/model/io/YOLOLoadStrategy.java b/src/main/java/com/github/mfl28/boundingboxeditor/model/io/YOLOLoadStrategy.java
index e151f3d..2d4b748 100644
--- a/src/main/java/com/github/mfl28/boundingboxeditor/model/io/YOLOLoadStrategy.java
+++ b/src/main/java/com/github/mfl28/boundingboxeditor/model/io/YOLOLoadStrategy.java
@@ -38,8 +38,9 @@
import java.util.stream.Stream;
/**
- * Loads rectangular bounding-box annotations in the YOLO-format described at
- * ...
+ * Loads rectangular bounding-box annotations and instance-segmentation annotations in the YOLO-format described at
+ * ... and
+ * ...
*/
public class YOLOLoadStrategy implements ImageAnnotationLoadStrategy {
public static final String INVALID_BOUNDING_BOX_COORDINATES_MESSAGE = "Invalid bounding-box coordinates on line ";
@@ -66,18 +67,18 @@ public ImageAnnotationImportResult load(Path path, Set filesToLoad,
try {
loadObjectCategories(path);
- } catch(Exception e) {
+ } catch (Exception e) {
unParsedFileErrorMessages.add(new IOErrorInfoEntry(OBJECT_DATA_FILE_NAME, e.getMessage()));
return new ImageAnnotationImportResult(0, unParsedFileErrorMessages, ImageAnnotationData.empty());
}
- if(categories.isEmpty()) {
+ if (categories.isEmpty()) {
unParsedFileErrorMessages
.add(new IOErrorInfoEntry(OBJECT_DATA_FILE_NAME, "Does not contain any category names."));
return new ImageAnnotationImportResult(0, unParsedFileErrorMessages, ImageAnnotationData.empty());
}
- try(Stream fileStream = Files.walk(path, INCLUDE_SUBDIRECTORIES ? Integer.MAX_VALUE : 1)) {
+ try (Stream fileStream = Files.walk(path, INCLUDE_SUBDIRECTORIES ? Integer.MAX_VALUE : 1)) {
List annotationFiles = fileStream
.filter(pathItem -> pathItem.getFileName().toString().endsWith(".txt"))
.map(Path::toFile).toList();
@@ -86,25 +87,25 @@ public ImageAnnotationImportResult load(Path path, Set filesToLoad,
AtomicInteger nrProcessedFiles = new AtomicInteger(0);
List imageAnnotations = annotationFiles.parallelStream()
- .map(file -> {
- progress.set(1.0 * nrProcessedFiles
- .incrementAndGet() / totalNrOfFiles);
-
- try {
- return loadAnnotationFromFile(file);
- } catch(InvalidAnnotationFormatException |
- AnnotationToNonExistentImageException |
- AnnotationAssociationException |
- IOException e) {
- unParsedFileErrorMessages
- .add(new IOErrorInfoEntry(
- file.getName(),
- e.getMessage()));
- return null;
- }
- })
- .filter(Objects::nonNull)
- .toList();
+ .map(file -> {
+ progress.set(1.0 * nrProcessedFiles
+ .incrementAndGet() / totalNrOfFiles);
+
+ try {
+ return loadAnnotationFromFile(file);
+ } catch (InvalidAnnotationFormatException |
+ AnnotationToNonExistentImageException |
+ AnnotationAssociationException |
+ IOException e) {
+ unParsedFileErrorMessages
+ .add(new IOErrorInfoEntry(
+ file.getName(),
+ e.getMessage()));
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .toList();
return new ImageAnnotationImportResult(
imageAnnotations.size(),
@@ -115,18 +116,18 @@ public ImageAnnotationImportResult load(Path path, Set filesToLoad,
}
private void loadObjectCategories(Path root) throws IOException {
- if(!root.resolve(OBJECT_DATA_FILE_NAME).toFile().exists()) {
+ if (!root.resolve(OBJECT_DATA_FILE_NAME).toFile().exists()) {
throw new InvalidAnnotationFormatException(
"Does not exist in annotation folder \"" + root.getFileName().toString() + "\".");
}
- try(BufferedReader fileReader = Files.newBufferedReader(root.resolve(OBJECT_DATA_FILE_NAME))) {
+ try (BufferedReader fileReader = Files.newBufferedReader(root.resolve(OBJECT_DATA_FILE_NAME))) {
String line;
- while((line = fileReader.readLine()) != null) {
+ while ((line = fileReader.readLine()) != null) {
line = line.strip();
- if(!line.isBlank()) {
+ if (!line.isBlank()) {
categories.add(line);
}
}
@@ -137,30 +138,32 @@ private ImageAnnotation loadAnnotationFromFile(File file) throws IOException {
final List annotatedImageFiles = baseFileNameToImageFileMap.get(
FilenameUtils.getBaseName(file.getName()));
- if(annotatedImageFiles == null) {
+ if (annotatedImageFiles == null) {
throw new AnnotationToNonExistentImageException(
"No associated image file.");
- } else if(annotatedImageFiles.size() > 1) {
+ } else if (annotatedImageFiles.size() > 1) {
throw new AnnotationAssociationException(
"More than one associated image file.");
}
- final String annotatedImageFileName = annotatedImageFiles.get(0);
+ final String annotatedImageFileName = annotatedImageFiles.getFirst();
- try(BufferedReader fileReader = Files.newBufferedReader(file.toPath())) {
+ try (BufferedReader fileReader = Files.newBufferedReader(file.toPath())) {
String line;
List boundingShapeDataList = new ArrayList<>();
int counter = 1;
- while((line = fileReader.readLine()) != null) {
+ while ((line = fileReader.readLine()) != null) {
line = line.strip();
- if(!line.isBlank()) {
+ if (!line.isBlank()) {
try {
- boundingShapeDataList.add(parseBoundingBoxData(line, counter));
- } catch(InvalidAnnotationFormatException e) {
+ final BoundingShapeData boundingShapeData = parseBoundingShapeData(line, counter);
+ boundingShapeDataList.add(boundingShapeData);
+ boundingShapeCountPerCategory.merge(boundingShapeData.getCategoryName(), 1, Integer::sum);
+ } catch (InvalidAnnotationFormatException e) {
unParsedFileErrorMessages.add(new IOErrorInfoEntry(file.getName(), e.getMessage()));
}
}
@@ -168,7 +171,7 @@ private ImageAnnotation loadAnnotationFromFile(File file) throws IOException {
++counter;
}
- if(boundingShapeDataList.isEmpty()) {
+ if (boundingShapeDataList.isEmpty()) {
return null;
}
@@ -177,95 +180,103 @@ private ImageAnnotation loadAnnotationFromFile(File file) throws IOException {
}
}
- private BoundingBoxData parseBoundingBoxData(String line, int lineNumber) {
+ private BoundingShapeData parseBoundingShapeData(String line, int lineNumber) {
Scanner scanner = new Scanner(line);
scanner.useLocale(Locale.ENGLISH);
int categoryId = parseCategoryIndex(scanner, lineNumber);
- double xMidRelative = parseRatio(scanner, lineNumber);
- double yMidRelative = parseRatio(scanner, lineNumber);
- double widthRelative = parseRatio(scanner, lineNumber);
- double heightRelative = parseRatio(scanner, lineNumber);
+ List entries = new ArrayList<>();
+ while (scanner.hasNextDouble()) {
+ double entry = scanner.nextDouble();
+
+ assertRatio(entry, "Bounds value not within interval [0, 1] on line " + lineNumber + ".");
+
+ entries.add(entry);
+ }
+
+ if (entries.size() == 4) {
+ return createBoundingBoxData(
+ categoryId, entries.get(0), entries.get(1), entries.get(2), entries.get(3), lineNumber);
+ } else if(entries.size() >= 6 && entries.size() % 2 == 0) {
+ return createBoundingPolygonData(categoryId, entries);
+ }
+
+ throw new InvalidAnnotationFormatException("Invalid number of bounds values on line " + lineNumber + ".");
+ }
+
+ private BoundingBoxData createBoundingBoxData(int categoryId, double xMidRelative, double yMidRelative,
+ double widthRelative, double heightRelative,
+ int lineNumber) {
double xMinRelative = xMidRelative - widthRelative / 2;
- if(xMinRelative < 0 && -xMinRelative < 1e-6) {
+ if (xMinRelative < 0 && -xMinRelative < 1e-6) {
xMinRelative = 0;
}
assertRatio(xMinRelative, INVALID_BOUNDING_BOX_COORDINATES_MESSAGE + lineNumber + ".");
double yMinRelative = yMidRelative - heightRelative / 2;
- if(yMinRelative < 0 && -yMinRelative < 1e-6) {
+ if (yMinRelative < 0 && -yMinRelative < 1e-6) {
yMinRelative = 0;
}
assertRatio(yMinRelative, INVALID_BOUNDING_BOX_COORDINATES_MESSAGE + lineNumber + ".");
double xMaxRelative = xMidRelative + widthRelative / 2;
- if(xMaxRelative > 1 && xMaxRelative - 1 < 1e-6) {
+ if (xMaxRelative > 1 && xMaxRelative - 1 < 1e-6) {
xMaxRelative = 1;
}
assertRatio(xMaxRelative, INVALID_BOUNDING_BOX_COORDINATES_MESSAGE + lineNumber + ".");
double yMaxRelative = yMidRelative + heightRelative / 2;
- if(yMaxRelative > 1 && yMaxRelative - 1 < 1e-6) {
+ if (yMaxRelative > 1 && yMaxRelative - 1 < 1e-6) {
yMaxRelative = 1;
}
assertRatio(yMaxRelative, INVALID_BOUNDING_BOX_COORDINATES_MESSAGE + lineNumber + ".");
String categoryName = categories.get(categoryId);
- ObjectCategory objectCategory = categoryNameToCategoryMap.computeIfAbsent(categoryName,
- key -> new ObjectCategory(key,
- ColorUtils
- .createRandomColor()));
+ ObjectCategory objectCategory = categoryNameToCategoryMap.computeIfAbsent(
+ categoryName,
+ key -> new ObjectCategory(key,
+ ColorUtils
+ .createRandomColor()));
// Note that there are no tags or parts in YOLO-format.
- BoundingBoxData boundingBoxData = new BoundingBoxData(objectCategory,
- xMinRelative, yMinRelative, xMaxRelative, yMaxRelative,
- Collections.emptyList());
-
- boundingShapeCountPerCategory.merge(categoryName, 1, Integer::sum);
-
- return boundingBoxData;
+ return new BoundingBoxData(objectCategory,
+ xMinRelative, yMinRelative, xMaxRelative, yMaxRelative,
+ Collections.emptyList());
}
- private double parseRatio(Scanner scanner, int lineNumber) {
- if(!scanner.hasNextDouble()) {
- throw new InvalidAnnotationFormatException(
- "Missing or invalid bounding-box bounds on line " + lineNumber + ".");
- }
-
- double ratio = scanner.nextDouble();
+ private BoundingPolygonData createBoundingPolygonData(int categoryId, List entries) {
+ String categoryName = categories.get(categoryId);
- assertRatio(ratio, lineNumber);
+ ObjectCategory objectCategory = categoryNameToCategoryMap.computeIfAbsent(categoryName,
+ key -> new ObjectCategory(key,
+ ColorUtils
+ .createRandomColor()));
- return ratio;
+ // Note that there are no tags or parts in YOLO-format.
+ return new BoundingPolygonData(objectCategory, entries, Collections.emptyList());
}
private int parseCategoryIndex(Scanner scanner, int lineNumber) {
- if(!scanner.hasNextInt()) {
+ if (!scanner.hasNextInt()) {
throw new InvalidAnnotationFormatException("Missing or invalid category index on line " + lineNumber + ".");
}
int categoryId = scanner.nextInt();
- if(categoryId < 0 || categoryId >= categories.size()) {
+ if (categoryId < 0 || categoryId >= categories.size()) {
throw new InvalidAnnotationFormatException("Invalid category index " + categoryId
- + " (of " + categories.size() + " categories) on line " +
- lineNumber + ".");
+ + " (of " + categories.size() + " categories) on line " +
+ lineNumber + ".");
}
return categoryId;
}
- private void assertRatio(double ratio, int lineNumber) {
- if(ratio < 0 || ratio > 1) {
- throw new InvalidAnnotationFormatException("Bounds ratio not within [0, 1] on line " + lineNumber + ".");
- }
- }
-
private void assertRatio(double ratio, String message) {
- if(ratio < 0 || ratio > 1) {
+ if (ratio < 0 || ratio > 1) {
throw new InvalidAnnotationFormatException(message);
}
}
diff --git a/src/main/java/com/github/mfl28/boundingboxeditor/model/io/YOLOSaveStrategy.java b/src/main/java/com/github/mfl28/boundingboxeditor/model/io/YOLOSaveStrategy.java
index 630c82d..4493e8e 100644
--- a/src/main/java/com/github/mfl28/boundingboxeditor/model/io/YOLOSaveStrategy.java
+++ b/src/main/java/com/github/mfl28/boundingboxeditor/model/io/YOLOSaveStrategy.java
@@ -18,10 +18,7 @@
*/
package com.github.mfl28.boundingboxeditor.model.io;
-import com.github.mfl28.boundingboxeditor.model.data.BoundingBoxData;
-import com.github.mfl28.boundingboxeditor.model.data.BoundingShapeData;
-import com.github.mfl28.boundingboxeditor.model.data.ImageAnnotation;
-import com.github.mfl28.boundingboxeditor.model.data.ImageAnnotationData;
+import com.github.mfl28.boundingboxeditor.model.data.*;
import com.github.mfl28.boundingboxeditor.model.io.results.IOErrorInfoEntry;
import com.github.mfl28.boundingboxeditor.model.io.results.ImageAnnotationExportResult;
import javafx.beans.property.DoubleProperty;
@@ -36,10 +33,13 @@
import java.text.DecimalFormatSymbols;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
/**
- * Saves rectangular bounding-box annotations in the YOLO-format described at
- * ...
+ * Saves bounding-box and bounding-polygon annotations (with at least 3 nodes)
+ * in the YOLO-format described at
+ * ... and
+ * ...
*/
public class YOLOSaveStrategy implements ImageAnnotationSaveStrategy {
private static final DecimalFormat DECIMAL_FORMAT =
@@ -54,16 +54,16 @@ public ImageAnnotationExportResult save(ImageAnnotationData annotations, Path de
DoubleProperty progress) {
this.saveFolderPath = destination;
this.categories = annotations.categoryNameToBoundingShapeCountMap().entrySet().stream()
- .filter(stringIntegerEntry -> stringIntegerEntry.getValue() > 0)
- .map(Map.Entry::getKey)
- .sorted()
- .toList();
+ .filter(stringIntegerEntry -> stringIntegerEntry.getValue() > 0)
+ .map(Map.Entry::getKey)
+ .sorted()
+ .toList();
List unParsedFileErrorMessages = Collections.synchronizedList(new ArrayList<>());
try {
createObjectDataFile();
- } catch(IOException e) {
+ } catch (IOException e) {
unParsedFileErrorMessages.add(new IOErrorInfoEntry(OBJECT_DATA_FILE_NAME, e.getMessage()));
}
@@ -73,7 +73,7 @@ public ImageAnnotationExportResult save(ImageAnnotationData annotations, Path de
annotations.imageAnnotations().parallelStream().forEach(annotation -> {
try {
createAnnotationFile(annotation);
- } catch(IOException e) {
+ } catch (IOException e) {
unParsedFileErrorMessages
.add(new IOErrorInfoEntry(annotation.getImageFileName(), e.getMessage()));
}
@@ -88,15 +88,13 @@ public ImageAnnotationExportResult save(ImageAnnotationData annotations, Path de
}
private void createObjectDataFile() throws IOException {
- try(BufferedWriter fileWriter = Files.newBufferedWriter(saveFolderPath
- .resolve(OBJECT_DATA_FILE_NAME))) {
- for(int i = 0; i < categories.size() - 1; ++i) {
+ try (BufferedWriter fileWriter = Files.newBufferedWriter(
+ saveFolderPath.resolve(OBJECT_DATA_FILE_NAME))) {
+ for (int i = 0; i < categories.size(); ++i) {
fileWriter.write(categories.get(i));
- fileWriter.newLine();
- }
-
- if(!categories.isEmpty()) {
- fileWriter.write(categories.get(categories.size() - 1));
+ if (i != categories.size() - 1) {
+ fileWriter.newLine();
+ }
}
}
}
@@ -105,25 +103,27 @@ private void createAnnotationFile(ImageAnnotation annotation) throws IOException
String imageFileName = annotation.getImageFileName();
String imageFileNameWithoutExtension = imageFileName.substring(0, imageFileName.lastIndexOf('.'));
- try(BufferedWriter fileWriter = Files.newBufferedWriter(saveFolderPath
- .resolve(imageFileNameWithoutExtension +
- YOLO_ANNOTATION_FILE_EXTENSION))) {
+ try (BufferedWriter fileWriter = Files.newBufferedWriter(
+ saveFolderPath.resolve(imageFileNameWithoutExtension +
+ YOLO_ANNOTATION_FILE_EXTENSION))) {
List boundingShapeDataList = annotation.getBoundingShapeData();
- for(int i = 0; i < boundingShapeDataList.size() - 1; ++i) {
+ for (int i = 0; i < boundingShapeDataList.size(); ++i) {
BoundingShapeData boundingShapeData = boundingShapeDataList.get(i);
- if(boundingShapeData instanceof BoundingBoxData boundingBoxData) {
+ if (boundingShapeData instanceof BoundingBoxData boundingBoxData) {
fileWriter.write(createBoundingBoxDataEntry(boundingBoxData));
- fileWriter.newLine();
- }
- }
- if(!boundingShapeDataList.isEmpty()) {
- BoundingShapeData lastShapeData = boundingShapeDataList.get(boundingShapeDataList.size() - 1);
+ if (i != boundingShapeDataList.size() - 1) {
+ fileWriter.newLine();
+ }
+ } else if (boundingShapeData instanceof BoundingPolygonData boundingPolygonData
+ && boundingPolygonData.getRelativePointsInImage().size() >= 6) {
+ fileWriter.write(createBoundingPolygonDataEntry(boundingPolygonData));
- if(lastShapeData instanceof BoundingBoxData boundingBoxData) {
- fileWriter.write(createBoundingBoxDataEntry(boundingBoxData));
+ if (i != boundingShapeDataList.size() - 1) {
+ fileWriter.newLine();
+ }
}
}
}
@@ -141,4 +141,16 @@ private String createBoundingBoxDataEntry(BoundingBoxData boundingBoxData) {
return StringUtils.join(List.of(categoryIndex, xMidRelative, yMidRelative, widthRelative, heightRelative), " ");
}
+
+ private String createBoundingPolygonDataEntry(BoundingPolygonData boundingPolygonData) {
+ int categoryIndex = categories.indexOf(boundingPolygonData.getCategoryName());
+
+ List relativePoints = boundingPolygonData.getRelativePointsInImage();
+
+ String relativePointsEntry = relativePoints.stream()
+ .map(DECIMAL_FORMAT::format)
+ .collect(Collectors.joining(" "));
+
+ return StringUtils.join(List.of(categoryIndex, relativePointsEntry), " ");
+ }
}
diff --git a/src/test/java/com/github/mfl28/boundingboxeditor/controller/ControllerTests.java b/src/test/java/com/github/mfl28/boundingboxeditor/controller/ControllerTests.java
index 29e53b5..5aa0187 100644
--- a/src/test/java/com/github/mfl28/boundingboxeditor/controller/ControllerTests.java
+++ b/src/test/java/com/github/mfl28/boundingboxeditor/controller/ControllerTests.java
@@ -64,7 +64,7 @@ class ControllerTests extends BoundingBoxEditorTestBase {
@Start
void start(Stage stage) {
super.onStart(stage);
- controller.loadImageFiles(new File(getClass().getResource(TEST_IMAGE_FOLDER_PATH_1).getFile()));
+ controller.loadImageFiles(new File(Objects.requireNonNull(getClass().getResource(TEST_IMAGE_FOLDER_PATH_1)).getFile()));
}
@Test
@@ -81,10 +81,10 @@ void onExportAnnotation_PVOC_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
verifyThat(model.isSaved(), Matchers.is(true), saveScreenshot(testinfo));
- final File referenceAnnotationFile = new File(getClass().getResource(referenceAnnotationFilePath).getFile());
+ final File referenceAnnotationFile = new File(Objects.requireNonNull(getClass().getResource(referenceAnnotationFilePath)).getFile());
timeOutClickOn(robot, "#file-menu", testinfo);
WaitForAsyncUtils.waitForFxEvents();
@@ -107,68 +107,68 @@ void onExportAnnotation_PVOC_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
Path actualDir = Files.createDirectory(tempDirectory.resolve("actual"));
Assertions.assertTrue(Files.isDirectory(actualDir),
- () -> saveScreenshotAndReturnMessage(testinfo, "Actual files " +
- "directory does not exist."));
+ () -> saveScreenshotAndReturnMessage(testinfo, "Actual files " +
+ "directory does not exist."));
final Map counts = model.getCategoryToAssignedBoundingShapesCountMap();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Objects.equals(counts.get("Boat"), 2) &&
- Objects.equals(counts.get("Sail"), 6) &&
- Objects.equals(counts.get("Flag"), 1)),
- () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
- "per-category-counts were not read within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Objects.equals(counts.get("Boat"), 2) &&
+ Objects.equals(counts.get("Sail"), 6) &&
+ Objects.equals(counts.get("Flag"), 1)),
+ () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
+ "per-category-counts were not read within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap().size(), Matchers.equalTo(3),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(model.getObjectCategories(), Matchers.hasSize(3), saveScreenshot(testinfo));
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> mainView.getImageFileListView()
- .getSelectionModel()
- .getSelectedItem()
- .isHasAssignedBoundingShapes()
- && mainView.getCurrentBoundingShapes()
- .stream()
- .filter(viewable -> viewable instanceof BoundingBoxView)
- .count() == 8
- && mainView.getCurrentBoundingShapes()
- .stream()
- .filter(viewable -> viewable instanceof BoundingPolygonView)
- .count() == 1),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Bounding shape counts did not match " +
- "within " + TIMEOUT_DURATION_IN_SEC +
- " sec."));
+ () -> mainView.getImageFileListView()
+ .getSelectionModel()
+ .getSelectedItem()
+ .isHasAssignedBoundingShapes()
+ && mainView.getCurrentBoundingShapes()
+ .stream()
+ .filter(viewable -> viewable instanceof BoundingBoxView)
+ .count() == 8
+ && mainView.getCurrentBoundingShapes()
+ .stream()
+ .filter(viewable -> viewable instanceof BoundingPolygonView)
+ .count() == 1),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Bounding shape counts did not match " +
+ "within " + TIMEOUT_DURATION_IN_SEC +
+ " sec."));
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> controller.getIoMetaData()
- .getDefaultAnnotationLoadingDirectory()
- .equals(referenceAnnotationFile
- .getParentFile())),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Expected default annotation loading " +
- "directory was not set within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> controller.getIoMetaData()
+ .getDefaultAnnotationLoadingDirectory()
+ .equals(referenceAnnotationFile
+ .getParentFile())),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Expected default annotation loading " +
+ "directory was not set within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
verifyThat(model.getImageFileNameToAnnotationMap().values().stream()
.allMatch(imageAnnotation -> imageAnnotation.getImageMetaData().hasDetails()),
- Matchers.equalTo(true), saveScreenshot(testinfo));
+ Matchers.equalTo(true), saveScreenshot(testinfo));
// Zoom a bit to change the image-view size.
robot.moveTo(mainView.getEditorImageView())
- .press(KeyCode.SHORTCUT)
- .scroll(-30)
- .release(KeyCode.SHORTCUT);
+ .press(KeyCode.SHORTCUT)
+ .scroll(-30)
+ .release(KeyCode.SHORTCUT);
WaitForAsyncUtils.waitForFxEvents();
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
verifyThat(model.isSaved(), Matchers.is(true), saveScreenshot(testinfo));
// Save the annotations to the temporary folder.
Platform.runLater(() -> controller.initiateAnnotationExport(actualDir.toFile(),
- ImageAnnotationSaveStrategy.Type.PASCAL_VOC));
+ ImageAnnotationSaveStrategy.Type.PASCAL_VOC));
WaitForAsyncUtils.waitForFxEvents();
timeOutAssertServiceSucceeded(controller.getAnnotationExportService(), testinfo);
@@ -179,36 +179,36 @@ void onExportAnnotation_PVOC_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
// Wait until the output-file actually exists. If the file was not created in
// the specified time-frame, a TimeoutException is thrown and the test fails.
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Files.exists(actualFilePath)),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Output-file was not created within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Files.exists(actualFilePath)),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Output-file was not created within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
// The output file should be exactly the same as the reference file.
- final File referenceFile = new File(getClass().getResource(referenceAnnotationFilePath).getFile());
+ final File referenceFile = new File(Objects.requireNonNull(getClass().getResource(referenceAnnotationFilePath)).getFile());
final byte[] referenceArray = Files.readAllBytes(referenceFile.toPath());
// Wait until the annotations were written to the output file and the file is equivalent to the reference file
// or throw a TimeoutException if this did not happen within the specified time-frame.
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Arrays.equals(referenceArray,
- Files.readAllBytes(
- actualFilePath))),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Expected annotation output-file " +
- "content was not created within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Arrays.equals(referenceArray,
+ Files.readAllBytes(
+ actualFilePath))),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Expected annotation output-file " +
+ "content was not created within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> controller.getIoMetaData()
- .getDefaultAnnotationSavingDirectory()
- .equals(actualDir.toFile())),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Expected default annotation saving " +
- "directory was no set within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> controller.getIoMetaData()
+ .getDefaultAnnotationSavingDirectory()
+ .equals(actualDir.toFile())),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Expected default annotation saving " +
+ "directory was no set within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
}
@Test
@@ -224,10 +224,10 @@ void onExportAnnotation_YOLO_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
final File referenceAnnotationFolder =
- new File(getClass().getResource(referenceAnnotationDirectoryPath).getFile());
+ new File(Objects.requireNonNull(getClass().getResource(referenceAnnotationDirectoryPath)).getFile());
timeOutClickOn(robot, "#file-menu", testinfo);
WaitForAsyncUtils.waitForFxEvents();
@@ -250,48 +250,50 @@ void onExportAnnotation_YOLO_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
Path actualDir = Files.createDirectory(tempDirectory.resolve("actual"));
Assertions.assertTrue(Files.isDirectory(actualDir),
- () -> saveScreenshotAndReturnMessage(testinfo, "Actual files " +
- "directory does not exist."));
+ () -> saveScreenshotAndReturnMessage(testinfo, "Actual files " +
+ "directory does not exist."));
final Map counts = model.getCategoryToAssignedBoundingShapesCountMap();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Objects.equals(counts.get("Boat"), 2) &&
- Objects.equals(counts.get("Sail"), 6) &&
- Objects.equals(counts.get("Flag"), 1)),
- () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
- "per-category-counts were not read within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Objects.equals(counts.get("Boat"), 2) &&
+ Objects.equals(counts.get("Sail"), 6) &&
+ Objects.equals(counts.get("Flag"), 1) &&
+ Objects.equals(counts.get("Test"), 1)),
+ () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding shape " +
+ "per-category-counts were not read within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
- verifyThat(model.getCategoryToAssignedBoundingShapesCountMap().size(), Matchers.equalTo(3),
- saveScreenshot(testinfo));
- verifyThat(model.getObjectCategories(), Matchers.hasSize(3), saveScreenshot(testinfo));
+ verifyThat(model.getCategoryToAssignedBoundingShapesCountMap().size(), Matchers.equalTo(4),
+ saveScreenshot(testinfo));
+ verifyThat(model.getObjectCategories(), Matchers.hasSize(4), saveScreenshot(testinfo));
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> mainView.getImageFileListView()
- .getSelectionModel()
- .getSelectedItem()
- .isHasAssignedBoundingShapes()
- && mainView.getCurrentBoundingShapes()
- .stream()
- .filter(viewable -> viewable instanceof BoundingBoxView)
- .count() == 9
- && mainView.getCurrentBoundingShapes()
- .stream().noneMatch(
- viewable -> viewable instanceof BoundingPolygonView)),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Bounding shape counts did not match " +
- "within " + TIMEOUT_DURATION_IN_SEC +
- " sec."));
+ () -> mainView.getImageFileListView()
+ .getSelectionModel()
+ .getSelectedItem()
+ .isHasAssignedBoundingShapes()
+ && mainView.getCurrentBoundingShapes()
+ .stream()
+ .filter(viewable -> viewable instanceof BoundingBoxView)
+ .count() == 9
+ && mainView.getCurrentBoundingShapes()
+ .stream()
+ .filter(viewable -> viewable instanceof BoundingPolygonView)
+ .count() == 1),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Bounding shape counts did not match " +
+ "within " + TIMEOUT_DURATION_IN_SEC +
+ " sec."));
// Zoom a bit to change the image-view size.
robot.moveTo(mainView.getEditorImageView())
- .press(KeyCode.SHORTCUT)
- .scroll(-30)
- .release(KeyCode.SHORTCUT);
+ .press(KeyCode.SHORTCUT)
+ .scroll(-30)
+ .release(KeyCode.SHORTCUT);
WaitForAsyncUtils.waitForFxEvents();
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
// Save the annotations to the temporary folder.
Platform.runLater(
@@ -306,11 +308,11 @@ void onExportAnnotation_YOLO_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
// Wait until the output-file actually exists. If the file was not created in
// the specified time-frame, a TimeoutException is thrown and the test fails.
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Files.exists(actualFilePath) &&
- Files.exists(actualObjectDataFilePath)),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Output-files were not created within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Files.exists(actualFilePath) &&
+ Files.exists(actualObjectDataFilePath)),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Output-files were not created within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
final File objectDataFile = referenceAnnotationFolder.toPath().resolve("object.data").toFile();
final byte[] objectDataFileArray = Files.readAllBytes(objectDataFile.toPath());
@@ -318,13 +320,13 @@ void onExportAnnotation_YOLO_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
// Wait until the annotations were written to the output file and the file is equivalent to the reference file
// or throw a TimeoutException if this did not happen within the specified time-frame.
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Arrays.equals(objectDataFileArray,
- Files.readAllBytes(
- actualObjectDataFilePath))),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Expected annotation output-file " +
- "content was not created within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Arrays.equals(objectDataFileArray,
+ Files.readAllBytes(
+ actualObjectDataFilePath))),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Expected annotation output-file " +
+ "content was not created within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
// The output file should be exactly the same as the reference file.
@@ -334,13 +336,13 @@ void onExportAnnotation_YOLO_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
// Wait until the annotations were written to the output file and the file is equivalent to the reference file
// or throw a TimeoutException if this did not happen within the specified time-frame.
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Arrays.equals(referenceArray,
- Files.readAllBytes(
- actualFilePath))),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Expected annotation output-file " +
- "content was not created within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Arrays.equals(referenceArray,
+ Files.readAllBytes(
+ actualFilePath))),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Expected annotation output-file " +
+ "content was not created within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
}
@Test
@@ -356,10 +358,10 @@ void onExportAnnotation_JSON_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
final File referenceAnnotationFile =
- new File(getClass().getResource(referenceAnnotationFilePath).getFile());
+ new File(Objects.requireNonNull(getClass().getResource(referenceAnnotationFilePath)).getFile());
timeOutClickOn(robot, "#file-menu", testinfo);
WaitForAsyncUtils.waitForFxEvents();
@@ -382,55 +384,55 @@ void onExportAnnotation_JSON_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
Path actualDir = Files.createDirectory(tempDirectory.resolve("actual"));
Assertions.assertTrue(Files.isDirectory(actualDir), () -> saveScreenshotAndReturnMessage(testinfo,
- "Actual " +
- "files " +
- "directory does not exist."));
+ "Actual " +
+ "files " +
+ "directory does not exist."));
final Map counts = model.getCategoryToAssignedBoundingShapesCountMap();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Objects.equals(counts.get("Boat"), 2) &&
- Objects.equals(counts.get("Sail"), 6) &&
- Objects.equals(counts.get("Flag"), 1)),
- () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
- "per-category-counts were not read within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Objects.equals(counts.get("Boat"), 2) &&
+ Objects.equals(counts.get("Sail"), 6) &&
+ Objects.equals(counts.get("Flag"), 1)),
+ () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
+ "per-category-counts were not read within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap().size(), Matchers.equalTo(3),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(model.getObjectCategories(), Matchers.hasSize(3), saveScreenshot(testinfo));
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> mainView.getImageFileListView()
- .getSelectionModel()
- .getSelectedItem()
- .isHasAssignedBoundingShapes()
- && mainView.getCurrentBoundingShapes()
- .stream()
- .filter(viewable -> viewable instanceof BoundingBoxView)
- .count() == 8
- && mainView.getCurrentBoundingShapes()
- .stream()
- .filter(viewable -> viewable instanceof BoundingPolygonView)
- .count() == 1),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Bounding shape counts did not match " +
- "within " + TIMEOUT_DURATION_IN_SEC +
- " sec."));
+ () -> mainView.getImageFileListView()
+ .getSelectionModel()
+ .getSelectedItem()
+ .isHasAssignedBoundingShapes()
+ && mainView.getCurrentBoundingShapes()
+ .stream()
+ .filter(viewable -> viewable instanceof BoundingBoxView)
+ .count() == 8
+ && mainView.getCurrentBoundingShapes()
+ .stream()
+ .filter(viewable -> viewable instanceof BoundingPolygonView)
+ .count() == 1),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Bounding shape counts did not match " +
+ "within " + TIMEOUT_DURATION_IN_SEC +
+ " sec."));
// Zoom a bit to change the image-view size.
robot.moveTo(mainView.getEditorImageView())
- .press(KeyCode.SHORTCUT)
- .scroll(-30)
- .release(KeyCode.SHORTCUT);
+ .press(KeyCode.SHORTCUT)
+ .scroll(-30)
+ .release(KeyCode.SHORTCUT);
WaitForAsyncUtils.waitForFxEvents();
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
// Save the annotations to the temporary folder.
Platform.runLater(
() -> controller.initiateAnnotationExport(actualDir.resolve(expectedAnnotationFileName).toFile(),
- ImageAnnotationSaveStrategy.Type.JSON));
+ ImageAnnotationSaveStrategy.Type.JSON));
WaitForAsyncUtils.waitForFxEvents();
timeOutAssertServiceSucceeded(controller.getAnnotationExportService(), testinfo);
@@ -440,10 +442,10 @@ void onExportAnnotation_JSON_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
// Wait until the output-file actually exists. If the file was not created in
// the specified time-frame, a TimeoutException is thrown and the test fails.
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Files.exists(actualFilePath)),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Output-files were not created within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Files.exists(actualFilePath)),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Output-files were not created within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
// The output file should be exactly the same as the reference file.
final byte[] referenceArray = Files.readAllBytes(referenceAnnotationFile.toPath());
@@ -451,13 +453,13 @@ void onExportAnnotation_JSON_WhenPreviouslyImportedAnnotation_ShouldProduceEquiv
// Wait until the annotations were written to the output file and the file is equivalent to the reference file
// or throw a TimeoutException if this did not happen within the specified time-frame.
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Arrays.equals(referenceArray,
- Files.readAllBytes(
- actualFilePath))),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Expected annotation output-file " +
- "content was not created within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Arrays.equals(referenceArray,
+ Files.readAllBytes(
+ actualFilePath))),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Expected annotation output-file " +
+ "content was not created within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
}
@Test
@@ -469,9 +471,9 @@ void onLoadAnnotation_YOLO_WhenObjectDataFileMissing_ShouldNotLoadAnnotations(Fx
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
- final File inputFile = new File(getClass().getResource(inputPath).getFile());
+ final File inputFile = new File(Objects.requireNonNull(getClass().getResource(inputPath)).getFile());
// Load bounding-boxes defined in annotation-file.
Platform.runLater(() -> controller.initiateAnnotationImport(inputFile, ImageAnnotationLoadStrategy.Type.YOLO));
@@ -485,26 +487,26 @@ void onLoadAnnotation_YOLO_WhenObjectDataFileMissing_ShouldNotLoadAnnotations(Fx
final String errorReportDialogContentReferenceText = "The source does not contain any valid annotations.";
final DialogPane errorReportDialog = (DialogPane) errorReportStage.getScene().getRoot();
verifyThat(errorReportDialog.getContentText(), Matchers.equalTo(errorReportDialogContentReferenceText),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(errorReportDialog.getExpandableContent(), Matchers.instanceOf(GridPane.class),
- saveScreenshot(testinfo));
- verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().get(0),
- Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
+ verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().getFirst(),
+ Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
final GridPane errorReportDialogContentPane = (GridPane) errorReportDialog.getExpandableContent();
- verifyThat(errorReportDialogContentPane.getChildren().get(0), Matchers.instanceOf(TableView.class),
- saveScreenshot(testinfo));
+ verifyThat(errorReportDialogContentPane.getChildren().getFirst(), Matchers.instanceOf(TableView.class),
+ saveScreenshot(testinfo));
@SuppressWarnings("unchecked") final TableView errorInfoTable =
- (TableView) errorReportDialogContentPane.getChildren().get(0);
+ (TableView) errorReportDialogContentPane.getChildren().getFirst();
final List errorInfoEntries = errorInfoTable.getItems();
verifyThat(errorInfoEntries, Matchers.hasSize(1), saveScreenshot(testinfo));
final IOErrorInfoEntry referenceErrorInfoEntry1 = new IOErrorInfoEntry("object.data",
- "Does not exist in annotation folder \"missing-classes-file\".");
+ "Does not exist in annotation folder \"missing-classes-file\".");
verifyThat(errorInfoEntries, Matchers.contains(referenceErrorInfoEntry1), saveScreenshot(testinfo));
@@ -521,7 +523,7 @@ void onLoadAnnotation_YOLO_WhenObjectDataFileMissing_ShouldNotLoadAnnotations(Fx
verifyThat(counts.size(), Matchers.equalTo(0), saveScreenshot(testinfo));
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
}
@Test
@@ -534,9 +536,9 @@ void onLoadAnnotation_YOLO_WhenAnnotationFileContainsErrors_ShouldNotLoadInvalid
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
- final File inputFile = new File(getClass().getResource(inputPath).getFile());
+ final File inputFile = new File(Objects.requireNonNull(getClass().getResource(inputPath)).getFile());
// Load bounding-boxes defined in annotation-file.
Platform.runLater(() -> controller.initiateAnnotationImport(inputFile, ImageAnnotationLoadStrategy.Type.YOLO));
@@ -551,19 +553,19 @@ void onLoadAnnotation_YOLO_WhenAnnotationFileContainsErrors_ShouldNotLoadInvalid
"Some bounding boxes could not be loaded from 4 image-annotations.";
final DialogPane errorReportDialog = (DialogPane) errorReportStage.getScene().getRoot();
verifyThat(errorReportDialog.getContentText(), Matchers.equalTo(errorReportDialogContentReferenceText),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(errorReportDialog.getExpandableContent(), Matchers.instanceOf(GridPane.class),
- saveScreenshot(testinfo));
- verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().get(0),
- Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
+ verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().getFirst(),
+ Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
final GridPane errorReportDialogContentPane = (GridPane) errorReportDialog.getExpandableContent();
- verifyThat(errorReportDialogContentPane.getChildren().get(0), Matchers.instanceOf(TableView.class),
- saveScreenshot(testinfo));
+ verifyThat(errorReportDialogContentPane.getChildren().getFirst(), Matchers.instanceOf(TableView.class),
+ saveScreenshot(testinfo));
@SuppressWarnings("unchecked") final TableView errorInfoTable =
- (TableView) errorReportDialogContentPane.getChildren().get(0);
+ (TableView) errorReportDialogContentPane.getChildren().getFirst();
final List errorInfoEntries = errorInfoTable.getItems();
@@ -571,27 +573,27 @@ void onLoadAnnotation_YOLO_WhenAnnotationFileContainsErrors_ShouldNotLoadInvalid
final IOErrorInfoEntry referenceErrorInfoEntry1 =
new IOErrorInfoEntry("austin-neill-685084-unsplash.txt",
- "Invalid category index 4 (of 4 categories) on line 1.");
+ "Invalid category index 4 (of 4 categories) on line 1.");
final IOErrorInfoEntry referenceErrorInfoEntry2 =
new IOErrorInfoEntry("caleb-george-316073-unsplash.txt",
- "Missing or invalid category index on line 1.");
+ "Missing or invalid category index on line 1.");
final IOErrorInfoEntry referenceErrorInfoEntry3 =
new IOErrorInfoEntry("nico-bhlr-1067059-unsplash.txt",
- "Missing or invalid bounding-box bounds on line 1.");
+ "Invalid number of bounds values on line 1.");
final IOErrorInfoEntry referenceErrorInfoEntry4 =
new IOErrorInfoEntry("tyler-nix-582593-unsplash.txt",
- "Bounds ratio not within [0, 1] on line 1.");
+ "Bounds value not within interval [0, 1] on line 1.");
final IOErrorInfoEntry referenceErrorInfoEntry5 =
new IOErrorInfoEntry("tyler-nix-582593-unsplash.txt",
- "Invalid bounding-box coordinates on line 2.");
+ "Invalid bounding-box coordinates on line 2.");
verifyThat(errorInfoEntries, Matchers.containsInAnyOrder(referenceErrorInfoEntry1, referenceErrorInfoEntry2,
- referenceErrorInfoEntry3, referenceErrorInfoEntry4,
- referenceErrorInfoEntry5), saveScreenshot(testinfo));
+ referenceErrorInfoEntry3, referenceErrorInfoEntry4,
+ referenceErrorInfoEntry5), saveScreenshot(testinfo));
WaitForAsyncUtils.waitForFxEvents();
@@ -606,10 +608,10 @@ void onLoadAnnotation_YOLO_WhenAnnotationFileContainsErrors_ShouldNotLoadInvalid
verifyThat(counts.get("Ship"), Matchers.equalTo(1), saveScreenshot(testinfo));
verifyThat(mainView.getCurrentBoundingShapes(), Matchers.hasSize(0), saveScreenshot(testinfo));
verifyThat(model.createImageAnnotationData().imageAnnotations(), Matchers.hasSize(1),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
}
@Test
@@ -621,7 +623,7 @@ void onLoadAnnotation_PVOC_WhenFileHasMissingNonCriticalElements_ShouldNotLoadIn
WaitForAsyncUtils.waitForFxEvents();
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
- final File referenceAnnotationFile = new File(getClass().getResource(inputFilePath).getFile());
+ final File referenceAnnotationFile = new File(Objects.requireNonNull(getClass().getResource(inputFilePath)).getFile());
// Load bounding-boxes defined in annotation-file.
Platform.runLater(() -> controller
@@ -637,19 +639,19 @@ void onLoadAnnotation_PVOC_WhenFileHasMissingNonCriticalElements_ShouldNotLoadIn
"Some bounding boxes could not be loaded from 1 image-annotation.";
final DialogPane errorReportDialog = (DialogPane) errorReportStage.getScene().getRoot();
verifyThat(errorReportDialog.getContentText(), Matchers.equalTo(errorReportDialogContentReferenceText),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(errorReportDialog.getExpandableContent(), Matchers.instanceOf(GridPane.class),
- saveScreenshot(testinfo));
- verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().get(0),
- Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
+ verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().getFirst(),
+ Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
final GridPane errorReportDialogContentPane = (GridPane) errorReportDialog.getExpandableContent();
- verifyThat(errorReportDialogContentPane.getChildren().get(0), Matchers.instanceOf(TableView.class),
- saveScreenshot(testinfo));
+ verifyThat(errorReportDialogContentPane.getChildren().getFirst(), Matchers.instanceOf(TableView.class),
+ saveScreenshot(testinfo));
@SuppressWarnings("unchecked") final TableView errorInfoTable =
- (TableView) errorReportDialogContentPane.getChildren().get(0);
+ (TableView) errorReportDialogContentPane.getChildren().getFirst();
final List errorInfoEntries = errorInfoTable.getItems();
@@ -657,12 +659,12 @@ void onLoadAnnotation_PVOC_WhenFileHasMissingNonCriticalElements_ShouldNotLoadIn
final IOErrorInfoEntry referenceErrorInfoEntry1 =
new IOErrorInfoEntry("annotation_with_missing_elements.xml",
- "Missing element: name");
+ "Missing element: name");
final IOErrorInfoEntry referenceErrorInfoEntry2 =
new IOErrorInfoEntry("annotation_with_missing_elements.xml",
- "Missing element: ymin");
+ "Missing element: ymin");
verifyThat(errorInfoEntries, Matchers.contains(referenceErrorInfoEntry1, referenceErrorInfoEntry2),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
WaitForAsyncUtils.waitForFxEvents();
@@ -673,15 +675,15 @@ void onLoadAnnotation_PVOC_WhenFileHasMissingNonCriticalElements_ShouldNotLoadIn
final Map counts = model.getCategoryToAssignedBoundingShapesCountMap();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Objects.equals(counts.get("Boat"), 1) &&
- Objects.equals(counts.get("Sail"), 6) &&
- counts.get("Flag") == null),
- () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
- "per-category-counts were not read within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Objects.equals(counts.get("Boat"), 1) &&
+ Objects.equals(counts.get("Sail"), 6) &&
+ counts.get("Flag") == null),
+ () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
+ "per-category-counts were not read within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully imported annotations for 1 image in"), saveScreenshot(testinfo));
}
@Test
@@ -693,7 +695,7 @@ void onLoadAnnotation_PVOC_WhenFileHasMissingCriticalElement_ShouldNotLoadAnyBou
WaitForAsyncUtils.waitForFxEvents();
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
- final File referenceAnnotationFile = new File(getClass().getResource(inputFilePath).getFile());
+ final File referenceAnnotationFile = new File(Objects.requireNonNull(getClass().getResource(inputFilePath)).getFile());
// Load bounding-boxes defined in annotation-file.
Platform.runLater(() -> controller
@@ -708,33 +710,33 @@ void onLoadAnnotation_PVOC_WhenFileHasMissingCriticalElement_ShouldNotLoadAnyBou
final String errorReportDialogContentReferenceText = "The source does not contain any valid annotations.";
final DialogPane errorReportDialog = (DialogPane) errorReportStage.getScene().getRoot();
verifyThat(errorReportDialog.getContentText(), Matchers.equalTo(errorReportDialogContentReferenceText),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(errorReportDialog.getExpandableContent(), Matchers.instanceOf(GridPane.class),
- saveScreenshot(testinfo));
- verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().get(0),
- Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
+ verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().getFirst(),
+ Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
final GridPane errorReportDialogContentPane = (GridPane) errorReportDialog.getExpandableContent();
- verifyThat(errorReportDialogContentPane.getChildren().get(0), Matchers.instanceOf(TableView.class),
- saveScreenshot(testinfo));
+ verifyThat(errorReportDialogContentPane.getChildren().getFirst(), Matchers.instanceOf(TableView.class),
+ saveScreenshot(testinfo));
@SuppressWarnings("unchecked") final TableView errorInfoTable =
- (TableView) errorReportDialogContentPane.getChildren().get(0);
+ (TableView) errorReportDialogContentPane.getChildren().getFirst();
final List errorInfoEntries = errorInfoTable.getItems();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> errorInfoTable.getItems().size() == 1),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Expected number of error info entries" +
- " not found in " +
- TIMEOUT_DURATION_IN_SEC +
- " sec."));
+ () -> errorInfoTable.getItems().size() == 1),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Expected number of error info entries" +
+ " not found in " +
+ TIMEOUT_DURATION_IN_SEC +
+ " sec."));
final IOErrorInfoEntry referenceErrorInfoEntry =
new IOErrorInfoEntry("annotation_with_missing_filename.xml",
- "Missing element: filename");
+ "Missing element: filename");
verifyThat(errorInfoEntries, Matchers.contains(referenceErrorInfoEntry), saveScreenshot(testinfo));
@@ -747,14 +749,14 @@ void onLoadAnnotation_PVOC_WhenFileHasMissingCriticalElement_ShouldNotLoadAnyBou
timeOutAssertTopModalStageClosed(robot, "Annotation Import Error Report", testinfo);
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap().isEmpty(), Matchers.is(true),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(model.getObjectCategories(), Matchers.empty(), saveScreenshot(testinfo));
verifyThat(model.createImageAnnotationData().imageAnnotations(), Matchers.empty(), saveScreenshot(testinfo));
verifyThat(mainView.getCurrentBoundingShapes(), Matchers.empty(), saveScreenshot(testinfo));
// Should not have changed the status message.
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
}
@Test
@@ -782,36 +784,36 @@ void onLoadAnnotation_PVOC_WhenAnnotationsPresent_ShouldAskForAndCorrectlyApplyU
WaitForAsyncUtils.waitForFxEvents();
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap(), Matchers.hasEntry("Test", 0),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
// Draw a bounding box.
moveRelativeToImageView(robot, new Point2D(0.25, 0.25), new Point2D(0.75, 0.75));
WaitForAsyncUtils.waitForFxEvents();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> mainView.getCurrentBoundingShapes()
- .size() == 1),
- () -> saveScreenshotAndReturnMessage(testinfo,
- "Expected number of bounding boxes not" +
- " found in " +
- TIMEOUT_DURATION_IN_SEC +
- " sec."));
+ () -> mainView.getCurrentBoundingShapes()
+ .size() == 1),
+ () -> saveScreenshotAndReturnMessage(testinfo,
+ "Expected number of bounding boxes not" +
+ " found in " +
+ TIMEOUT_DURATION_IN_SEC +
+ " sec."));
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap(), Matchers.hasEntry("Test", 1),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(mainView.getImageFileListView().getSelectionModel()
- .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(true),
- saveScreenshot(testinfo));
+ .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(true),
+ saveScreenshot(testinfo));
- verifyThat(mainView.getCurrentBoundingShapes().get(0), Matchers.instanceOf(BoundingBoxView.class),
- saveScreenshot(testinfo));
+ verifyThat(mainView.getCurrentBoundingShapes().getFirst(), Matchers.instanceOf(BoundingBoxView.class),
+ saveScreenshot(testinfo));
verifyThat(model.isSaved(), Matchers.is(true), saveScreenshot(testinfo));
verifyThat(mainView.getStatusBar().isSavedStatus(), Matchers.is(true), saveScreenshot(testinfo));
- final BoundingBoxView drawnBoundingBox = (BoundingBoxView) mainView.getCurrentBoundingShapes().get(0);
+ final BoundingBoxView drawnBoundingBox = (BoundingBoxView) mainView.getCurrentBoundingShapes().getFirst();
- final File annotationFile = new File(getClass().getResource(referenceAnnotationFilePath).getFile());
+ final File annotationFile = new File(Objects.requireNonNull(getClass().getResource(referenceAnnotationFilePath)).getFile());
// (1) User chooses Cancel:
userChoosesCancelOnAnnotationImportDialogSubtest(robot, drawnBoundingBox, annotationFile, testinfo);
@@ -833,9 +835,9 @@ void onLoadAnnotation_JSON_WhenFileHasMissingCriticalElements_ShouldNotLoadInval
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
- final File inputFile = new File(getClass().getResource(missingFileNameAnnotationFilePath).getFile());
+ final File inputFile = new File(Objects.requireNonNull(getClass().getResource(missingFileNameAnnotationFilePath)).getFile());
// Load bounding-boxes defined in annotation-file.
Platform.runLater(() -> controller.initiateAnnotationImport(inputFile, ImageAnnotationLoadStrategy.Type.JSON));
@@ -850,92 +852,92 @@ void onLoadAnnotation_JSON_WhenFileHasMissingCriticalElements_ShouldNotLoadInval
"image-annotation.";
final DialogPane errorReportDialog = (DialogPane) errorReportStage.getScene().getRoot();
verifyThat(errorReportDialog.getContentText(), Matchers.equalTo(errorReportDialogContentReferenceText),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(errorReportDialog.getExpandableContent(), Matchers.instanceOf(GridPane.class),
- saveScreenshot(testinfo));
- verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().get(0),
- Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
+ verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().getFirst(),
+ Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
final GridPane errorReportDialogContentPane = (GridPane) errorReportDialog.getExpandableContent();
- verifyThat(errorReportDialogContentPane.getChildren().get(0), Matchers.instanceOf(TableView.class),
- saveScreenshot(testinfo));
+ verifyThat(errorReportDialogContentPane.getChildren().getFirst(), Matchers.instanceOf(TableView.class),
+ saveScreenshot(testinfo));
@SuppressWarnings("unchecked") final TableView errorInfoTable =
- (TableView) errorReportDialogContentPane.getChildren().get(0);
+ (TableView) errorReportDialogContentPane.getChildren().getFirst();
final List errorInfoEntries = errorInfoTable.getItems();
verifyThat(errorInfoEntries, Matchers.hasSize(17), saveScreenshot(testinfo));
final IOErrorInfoEntry error1 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Invalid coordinate value for minX element" +
- " in bndbox element in annotation " +
- "for image " +
- "tyler-nix-582593-unsplash.jpg.");
+ "Invalid coordinate value for minX element" +
+ " in bndbox element in annotation " +
+ "for image " +
+ "tyler-nix-582593-unsplash.jpg.");
final IOErrorInfoEntry error2 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Invalid coordinate value for minY element" +
- " in bndbox element in annotation " +
- "for image " +
- "tyler-nix-582593-unsplash.jpg.");
+ "Invalid coordinate value for minY element" +
+ " in bndbox element in annotation " +
+ "for image " +
+ "tyler-nix-582593-unsplash.jpg.");
final IOErrorInfoEntry error3 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Missing category name element in " +
- "annotation for image " +
- "tyler-nix-582593-unsplash.jpg.");
+ "Missing category name element in " +
+ "annotation for image " +
+ "tyler-nix-582593-unsplash.jpg.");
final IOErrorInfoEntry error4 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Invalid coordinate value for maxX element" +
- " in bndbox element in annotation " +
- "for image " +
- "nico-bhlr-1067059-unsplash.jpg.");
+ "Invalid coordinate value for maxX element" +
+ " in bndbox element in annotation " +
+ "for image " +
+ "nico-bhlr-1067059-unsplash.jpg.");
final IOErrorInfoEntry error5 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Missing maxY element in bndbox element in" +
- " annotation for image " +
- "nico-bhlr-1067059-unsplash.jpg.");
+ "Missing maxY element in bndbox element in" +
+ " annotation for image " +
+ "nico-bhlr-1067059-unsplash.jpg.");
final IOErrorInfoEntry error6 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Invalid color element " +
- "in annotation for image " +
- "nico-bhlr-1067059-unsplash.jpg.");
+ "Invalid color element " +
+ "in annotation for image " +
+ "nico-bhlr-1067059-unsplash.jpg.");
final IOErrorInfoEntry error7 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Missing category element in bndbox " +
- "element in annotation for image nico-bhlr-1067059-unsplash.jpg.");
+ "Missing category element in bndbox " +
+ "element in annotation for image nico-bhlr-1067059-unsplash.jpg.");
final IOErrorInfoEntry error8 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Invalid tags value(s) in bndbox element " +
- "in annotation for image nico-bhlr-1067059-unsplash.jpg.");
+ "Invalid tags value(s) in bndbox element " +
+ "in annotation for image nico-bhlr-1067059-unsplash.jpg.");
final IOErrorInfoEntry error9 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Missing bndbox or polygon element in " +
- "annotation for image austin-neill-685084-unsplash.jpg.");
+ "Missing bndbox or polygon element in " +
+ "annotation for image austin-neill-685084-unsplash.jpg.");
final IOErrorInfoEntry error10 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Missing maxY element in bndbox element in" +
- " annotation for image austin-neill-685084-unsplash.jpg.");
+ "Missing maxY element in bndbox element in" +
+ " annotation for image austin-neill-685084-unsplash.jpg.");
final IOErrorInfoEntry error11 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Invalid parts value(s) in bndbox element " +
- "in annotation for image austin-neill-685084-unsplash.jpg.");
+ "Invalid parts value(s) in bndbox element " +
+ "in annotation for image austin-neill-685084-unsplash.jpg.");
final IOErrorInfoEntry error12 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Missing minY element" +
- " in bndbox element in annotation " +
- "for image " +
- "austin-neill-685084-unsplash.jpg.");
+ "Missing minY element" +
+ " in bndbox element in annotation " +
+ "for image " +
+ "austin-neill-685084-unsplash.jpg.");
final IOErrorInfoEntry error13 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Missing maxY element" +
- " in bndbox element in annotation " +
- "for image " +
- "austin-neill-685084-unsplash.jpg.");
+ "Missing maxY element" +
+ " in bndbox element in annotation " +
+ "for image " +
+ "austin-neill-685084-unsplash.jpg.");
final IOErrorInfoEntry error14 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Invalid number of coordinates in polygon " +
- "element in annotation for image caleb-george-316073-unsplash.jpg.");
+ "Invalid number of coordinates in polygon " +
+ "element in annotation for image caleb-george-316073-unsplash.jpg.");
final IOErrorInfoEntry error15 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Invalid coordinate value(s) in polygon " +
- "element in annotation for image caleb-george-316073-unsplash.jpg.");
+ "Invalid coordinate value(s) in polygon " +
+ "element in annotation for image caleb-george-316073-unsplash.jpg.");
final IOErrorInfoEntry error16 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Missing image fileName element.");
+ "Missing image fileName element.");
final IOErrorInfoEntry error17 = new IOErrorInfoEntry("missing_critical_elements.json",
- "Image nothere.jpg does not belong to " +
- "currently loaded image files.");
+ "Image nothere.jpg does not belong to " +
+ "currently loaded image files.");
verifyThat(errorInfoEntries,
- Matchers.containsInAnyOrder(error1, error2, error3, error4, error5, error6, error7,
- error8, error9, error10, error11, error12, error13, error14,
- error15, error16, error17), saveScreenshot(testinfo));
+ Matchers.containsInAnyOrder(error1, error2, error3, error4, error5, error6, error7,
+ error8, error9, error10, error11, error12, error13, error14,
+ error15, error16, error17), saveScreenshot(testinfo));
WaitForAsyncUtils.waitForFxEvents();
@@ -955,12 +957,12 @@ void onLoadAnnotation_JSON_WhenFileHasMissingCriticalElements_ShouldNotLoadInval
final List objectCategories = model.getObjectCategories();
verifyThat(objectCategories, Matchers.hasSize(4), saveScreenshot(testinfo));
verifyThat(objectCategories.stream().map(ObjectCategory::getName).collect(Collectors.toList()),
- Matchers.containsInAnyOrder("Car", "Sail", "Surfboard", "Boat"), saveScreenshot(testinfo));
+ Matchers.containsInAnyOrder("Car", "Sail", "Surfboard", "Boat"), saveScreenshot(testinfo));
verifyThat(mainView.getCurrentBoundingShapes(), Matchers.hasSize(4), saveScreenshot(testinfo));
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully imported annotations for 3 images in "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully imported annotations for 3 images in "), saveScreenshot(testinfo));
}
@Test
@@ -972,9 +974,9 @@ void onLoadAnnotation_JSON_WhenAnnotationFileIsEmpty_ShouldDisplayErrorDialog(Fx
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
- final File inputFile = new File(getClass().getResource(emptyAnnotationFilePath).getFile());
+ final File inputFile = new File(Objects.requireNonNull(getClass().getResource(emptyAnnotationFilePath)).getFile());
Platform.runLater(() -> controller.initiateAnnotationImport(inputFile, ImageAnnotationLoadStrategy.Type.JSON));
WaitForAsyncUtils.waitForFxEvents();
@@ -997,9 +999,9 @@ void onLoadAnnotation_JSON_WhenAnnotationFileIsCorrupt_ShouldDisplayErrorReport(
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
- final File inputFile = new File(getClass().getResource(corruptAnnotationFilePath).getFile());
+ final File inputFile = new File(Objects.requireNonNull(getClass().getResource(corruptAnnotationFilePath)).getFile());
Platform.runLater(() -> controller.initiateAnnotationImport(inputFile, ImageAnnotationLoadStrategy.Type.JSON));
WaitForAsyncUtils.waitForFxEvents();
@@ -1012,28 +1014,28 @@ void onLoadAnnotation_JSON_WhenAnnotationFileIsCorrupt_ShouldDisplayErrorReport(
final String errorReportDialogContentReferenceText = "The source does not contain any valid annotations.";
final DialogPane errorReportDialog = (DialogPane) errorReportStage.getScene().getRoot();
verifyThat(errorReportDialog.getContentText(), Matchers.equalTo(errorReportDialogContentReferenceText),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(errorReportDialog.getExpandableContent(), Matchers.instanceOf(GridPane.class),
- saveScreenshot(testinfo));
- verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().get(0),
- Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
+ verifyThat(((GridPane) errorReportDialog.getExpandableContent()).getChildren().getFirst(),
+ Matchers.instanceOf(TableView.class), saveScreenshot(testinfo));
final GridPane errorReportDialogContentPane = (GridPane) errorReportDialog.getExpandableContent();
- verifyThat(errorReportDialogContentPane.getChildren().get(0), Matchers.instanceOf(TableView.class),
- saveScreenshot(testinfo));
+ verifyThat(errorReportDialogContentPane.getChildren().getFirst(), Matchers.instanceOf(TableView.class),
+ saveScreenshot(testinfo));
@SuppressWarnings("unchecked") final TableView errorInfoTable =
- (TableView) errorReportDialogContentPane.getChildren().get(0);
+ (TableView) errorReportDialogContentPane.getChildren().getFirst();
final List errorInfoEntries = errorInfoTable.getItems();
verifyThat(errorInfoEntries, Matchers.hasSize(1), saveScreenshot(testinfo));
- verifyThat(errorInfoEntries.get(0).getSourceName(), Matchers.equalTo("corrupt.json"), saveScreenshot(testinfo));
- verifyThat(errorInfoEntries.get(0).getErrorDescription(), Matchers.startsWith("Unterminated array at line 2 " +
- "column 13"),
- saveScreenshot(testinfo));
+ verifyThat(errorInfoEntries.getFirst().getSourceName(), Matchers.equalTo("corrupt.json"), saveScreenshot(testinfo));
+ verifyThat(errorInfoEntries.getFirst().getErrorDescription(), Matchers.startsWith("Unterminated array at line 2 " +
+ "column 13"),
+ saveScreenshot(testinfo));
timeOutLookUpInStageAndClickOn(robot, errorReportStage, "OK", testinfo);
}
@@ -1049,13 +1051,13 @@ void onReloadAnnotations_afterImageFilesReopened_shouldCorrectlyDisplayBoundingS
timeOutAssertServiceSucceeded(controller.getImageMetaDataLoadingService(), testinfo);
verifyThat(controller.getStage().getTitle(), Matchers.matchesRegex("^Bounding Box Editor \\d\\.\\d\\.\\d - .*$"),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(mainView.getStatusBar().getCurrentEventMessage(),
- Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
+ Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
verifyThat(model.isSaved(), Matchers.is(true), saveScreenshot(testinfo));
- final File referenceAnnotationFile = new File(getClass().getResource(referenceAnnotationFilePath).getFile());
+ final File referenceAnnotationFile = new File(Objects.requireNonNull(getClass().getResource(referenceAnnotationFilePath)).getFile());
// Load bounding-boxes defined in the reference annotation-file.
Platform.runLater(() -> controller
@@ -1066,12 +1068,12 @@ void onReloadAnnotations_afterImageFilesReopened_shouldCorrectlyDisplayBoundingS
final Map counts = model.getCategoryToAssignedBoundingShapesCountMap();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Objects.equals(counts.get("Boat"), 2) &&
- Objects.equals(counts.get("Sail"), 6) &&
- Objects.equals(counts.get("Flag"), 1)),
- () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
- "per-category-counts were not read within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Objects.equals(counts.get("Boat"), 2) &&
+ Objects.equals(counts.get("Sail"), 6) &&
+ Objects.equals(counts.get("Flag"), 1)),
+ () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
+ "per-category-counts were not read within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
verifyThat(model.isSaved(), Matchers.is(true), saveScreenshot(testinfo));
@@ -1087,9 +1089,9 @@ void onReloadAnnotations_afterImageFilesReopened_shouldCorrectlyDisplayBoundingS
loadImageFolder(TEST_IMAGE_FOLDER_PATH_1);
Stage keepExistingCategoriesDialogStage = timeOutAssertDialogOpenedAndGetStage(robot,
- "Open Image Folder",
- "Keep existing categories?",
- testinfo);
+ "Open Image Folder",
+ "Keep existing categories?",
+ testinfo);
timeOutLookUpInStageAndClickOn(robot, keepExistingCategoriesDialogStage, "No", testinfo);
WaitForAsyncUtils.waitForFxEvents();
@@ -1104,8 +1106,8 @@ void onReloadAnnotations_afterImageFilesReopened_shouldCorrectlyDisplayBoundingS
verifyThat(model.getImageFileNameToAnnotationMap().size(), Matchers.equalTo(0), saveScreenshot(testinfo));
verifyThat(controller.lastLoadedImageUrl, Matchers.nullValue(), saveScreenshot(testinfo));
verifyThat(controller.getIoMetaData().getDefaultImageLoadingDirectory(),
- Matchers.equalTo(new File(getClass().getResource(TEST_IMAGE_FOLDER_PATH_1).getFile())),
- saveScreenshot(testinfo));
+ Matchers.equalTo(new File(Objects.requireNonNull(getClass().getResource(TEST_IMAGE_FOLDER_PATH_1)).getFile())),
+ saveScreenshot(testinfo));
// Reload bounding-boxes defined in the reference annotation-file.
Platform.runLater(() -> controller
@@ -1116,16 +1118,16 @@ void onReloadAnnotations_afterImageFilesReopened_shouldCorrectlyDisplayBoundingS
final Map countsReloaded = model.getCategoryToAssignedBoundingShapesCountMap();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Objects
- .equals(countsReloaded.get("Boat"), 2) &&
- Objects.equals(countsReloaded.get("Sail"),
- 6)
- &&
- Objects.equals(countsReloaded.get("Flag"),
- 1)),
- () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
- "per-category-counts were not read within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Objects
+ .equals(countsReloaded.get("Boat"), 2) &&
+ Objects.equals(countsReloaded.get("Sail"),
+ 6)
+ &&
+ Objects.equals(countsReloaded.get("Flag"),
+ 1)),
+ () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
+ "per-category-counts were not read within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
timeOutClickOn(robot, "#next-button", testinfo);
waitUntilCurrentImageIsLoaded(testinfo);
@@ -1136,8 +1138,7 @@ void onReloadAnnotations_afterImageFilesReopened_shouldCorrectlyDisplayBoundingS
}
@Test
- void onLoadAnnotation_YOLO_WhenAnnotationWithinYOLOPrecision_ShouldLoadBoundingBoxes(FxRobot robot,
- TestInfo testinfo) {
+ void onLoadAnnotation_YOLO_WhenAnnotationWithinYOLOPrecision_ShouldLoadBoundingBoxes(TestInfo testinfo) {
final String referenceAnnotationDirectoryPath = "/testannotations/yolo/precision";
@@ -1149,7 +1150,7 @@ void onLoadAnnotation_YOLO_WhenAnnotationWithinYOLOPrecision_ShouldLoadBoundingB
Matchers.startsWith("Successfully loaded 4 image-files from folder "), saveScreenshot(testinfo));
final File referenceAnnotationFolder =
- new File(getClass().getResource(referenceAnnotationDirectoryPath).getFile());
+ new File(Objects.requireNonNull(getClass().getResource(referenceAnnotationDirectoryPath)).getFile());
// Load bounding-boxes defined in the reference annotation-file.
Platform.runLater(() -> controller
@@ -1191,8 +1192,8 @@ private void userChoosesToSaveExistingAnnotationsOnAnnotationImport(FxRobot robo
verifyThat(mainView.getCurrentBoundingShapes().size(), Matchers.equalTo(1), saveScreenshot(testinfo));
verifyThat(mainView.getImageFileListView().getSelectionModel()
- .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(true),
- saveScreenshot(testinfo));
+ .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(true),
+ saveScreenshot(testinfo));
// Trying to import annotations updates annotation data and "saved" check
// (there are unsaved annotations):
verifyThat(model.isSaved(), Matchers.is(false), saveScreenshot(testinfo));
@@ -1214,28 +1215,28 @@ private void userChoosesNotToSaveExistingAnnotationsOnAnnotationImport(FxRobot r
// the newly imported ones should exist.
final Map counts = model.getCategoryToAssignedBoundingShapesCountMap();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Objects.equals(counts.get("Boat"), 2) &&
- Objects.equals(counts.get("Sail"), 6) &&
- Objects.equals(counts.get("Flag"), 1)),
- () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
- "per-category-counts were not read within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Objects.equals(counts.get("Boat"), 2) &&
+ Objects.equals(counts.get("Sail"), 6) &&
+ Objects.equals(counts.get("Flag"), 1)),
+ () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
+ "per-category-counts were not read within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap().size(), Matchers.equalTo(3),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(model.getObjectCategories(), Matchers.hasSize(3), saveScreenshot(testinfo));
verifyThat(model.createImageAnnotationData().imageAnnotations(), Matchers.hasSize(1),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(mainView.getCurrentBoundingShapes(), Matchers.empty(), saveScreenshot(testinfo));
verifyThat(mainView.getObjectTree().getRoot().getChildren().size(), Matchers.equalTo(0),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(mainView.getImageFileListView().getSelectionModel()
- .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(false),
- saveScreenshot(testinfo));
+ .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(false),
+ saveScreenshot(testinfo));
- verifyThat(mainView.getImageFileListView().getItems().get(0).isHasAssignedBoundingShapes(),
- Matchers.is(true), saveScreenshot(testinfo));
+ verifyThat(mainView.getImageFileListView().getItems().getFirst().isHasAssignedBoundingShapes(),
+ Matchers.is(true), saveScreenshot(testinfo));
// Loading new annotations from existing annotation files
// should lead to a positive "saved" status:
@@ -1252,48 +1253,48 @@ private void userChoosesYesOnAnnotationImportDialogSubTest(FxRobot robot, Boundi
verifyThat(mainView.getCurrentBoundingShapes(), Matchers.hasItem(drawnBoundingBox), saveScreenshot(testinfo));
verifyThat(mainView.getImageFileListView().getSelectionModel()
- .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(true),
- saveScreenshot(testinfo));
+ .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(true),
+ saveScreenshot(testinfo));
// ... but there should be additional categories and bounding boxes in the model.
final Map counts = model.getCategoryToAssignedBoundingShapesCountMap();
Assertions.assertDoesNotThrow(() -> WaitForAsyncUtils.waitFor(TIMEOUT_DURATION_IN_SEC, TimeUnit.SECONDS,
- () -> Objects.equals(counts.get("Boat"), 2) &&
- Objects.equals(counts.get("Sail"), 6)
- &&
- Objects.equals(counts.get("Flag"), 1) &&
- Objects.equals(counts.get("Test"), 1)),
- () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
- "per-category-counts were not read within " +
- TIMEOUT_DURATION_IN_SEC + " sec."));
+ () -> Objects.equals(counts.get("Boat"), 2) &&
+ Objects.equals(counts.get("Sail"), 6)
+ &&
+ Objects.equals(counts.get("Flag"), 1) &&
+ Objects.equals(counts.get("Test"), 1)),
+ () -> saveScreenshotAndReturnMessage(testinfo, "Correct bounding box " +
+ "per-category-counts were not read within " +
+ TIMEOUT_DURATION_IN_SEC + " sec."));
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap().size(), Matchers.equalTo(4),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(model.getObjectCategories(), Matchers.hasSize(4), saveScreenshot(testinfo));
verifyThat(model.createImageAnnotationData().imageAnnotations(), Matchers.hasSize(2),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
- verifyThat(mainView.getImageFileListView().getItems().get(0).isHasAssignedBoundingShapes(),
- Matchers.is(true), saveScreenshot(testinfo));
+ verifyThat(mainView.getImageFileListView().getItems().getFirst().isHasAssignedBoundingShapes(),
+ Matchers.is(true), saveScreenshot(testinfo));
// Remove the imported Annotations manually to reset for next test.
timeOutClickOn(robot, "#previous-button", testinfo);
waitUntilCurrentImageIsLoaded(testinfo);
WaitForAsyncUtils.waitForFxEvents();
- robot.rightClickOn(mainView.getObjectTree().getRoot().getChildren().get(0).getGraphic())
- .clickOn("Delete");
+ robot.rightClickOn(mainView.getObjectTree().getRoot().getChildren().getFirst().getGraphic())
+ .clickOn("Delete");
WaitForAsyncUtils.waitForFxEvents();
- for(int i = 0; i != 3; ++i) {
+ for (int i = 0; i != 3; ++i) {
NodeQuery nodeQuery = robot.from(mainView.getObjectCategoryTable()).lookup("#delete-button").nth(1);
robot.clickOn((Node) nodeQuery.query(), MouseButton.PRIMARY);
}
verifyThat(mainView.getObjectCategoryTable(), TableViewMatchers.hasNumRows(1), saveScreenshot(testinfo));
- verifyThat(mainView.getObjectCategoryTable().getItems().get(0).getName(), Matchers.equalTo("Test"),
- saveScreenshot(testinfo));
+ verifyThat(mainView.getObjectCategoryTable().getItems().getFirst().getName(), Matchers.equalTo("Test"),
+ saveScreenshot(testinfo));
timeOutClickOn(robot, "#next-button", testinfo);
@@ -1312,13 +1313,13 @@ private void userChoosesCancelOnAnnotationImportDialogSubtest(FxRobot robot,
verifyThat(mainView.getCurrentBoundingShapes().size(), Matchers.equalTo(1), saveScreenshot(testinfo));
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap().size(), Matchers.equalTo(1),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(model.getCategoryToAssignedBoundingShapesCountMap(), Matchers.hasEntry("Test", 1),
- saveScreenshot(testinfo));
+ saveScreenshot(testinfo));
verifyThat(mainView.getCurrentBoundingShapes(), Matchers.hasItem(drawnBoundingBox), saveScreenshot(testinfo));
verifyThat(mainView.getImageFileListView().getSelectionModel()
- .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(true),
- saveScreenshot(testinfo));
+ .getSelectedItem().isHasAssignedBoundingShapes(), Matchers.is(true),
+ saveScreenshot(testinfo));
// Trying to import annotations updates annotation data and "saved" check
// (there are unsaved annotations):
verifyThat(model.isSaved(), Matchers.is(false), saveScreenshot(testinfo));
diff --git a/src/test/resources/testannotations/yolo/reference/austin-neill-685084-unsplash.txt b/src/test/resources/testannotations/yolo/reference/austin-neill-685084-unsplash.txt
index 54efce6..a28ce5e 100644
--- a/src/test/resources/testannotations/yolo/reference/austin-neill-685084-unsplash.txt
+++ b/src/test/resources/testannotations/yolo/reference/austin-neill-685084-unsplash.txt
@@ -6,4 +6,5 @@
2 0.483448 0.350107 0.127639 0.261242
2 0.476105 0.194325 0.033887 0.163812
2 0.471587 0.522484 0.044052 0.256959
-2 0.469611 0.79015 0.040099 0.147752
\ No newline at end of file
+2 0.469611 0.79015 0.040099 0.147752
+3 0.75 0.5 0.8 0.6 0.82 0.4
\ No newline at end of file
diff --git a/src/test/resources/testannotations/yolo/reference/object.data b/src/test/resources/testannotations/yolo/reference/object.data
index 4806953..3bacb63 100644
--- a/src/test/resources/testannotations/yolo/reference/object.data
+++ b/src/test/resources/testannotations/yolo/reference/object.data
@@ -1,3 +1,4 @@
Boat
Flag
-Sail
\ No newline at end of file
+Sail
+Test
\ No newline at end of file