diff --git a/photon-client/src/views/PipelineViews/ContoursTab.vue b/photon-client/src/views/PipelineViews/ContoursTab.vue index 671f5fe2f..14c440ddc 100644 --- a/photon-client/src/views/PipelineViews/ContoursTab.vue +++ b/photon-client/src/views/PipelineViews/ContoursTab.vue @@ -51,7 +51,7 @@ name="Target Grouping" tooltip="Whether or not every two targets are paired with each other (good for e.g. 2019 targets)" :select-cols="largeBox" - :list="['Single','Dual']" + :list="['Single','Dual','2orMore']" @input="handlePipelineData('contourGroupingMode')" /> contours) { var points = new MatOfPoint(); for (var contour : contours) { diff --git a/photon-core/src/main/java/org/photonvision/vision/opencv/ContourGroupingMode.java b/photon-core/src/main/java/org/photonvision/vision/opencv/ContourGroupingMode.java index 2ae1a0eae..9e88a9288 100644 --- a/photon-core/src/main/java/org/photonvision/vision/opencv/ContourGroupingMode.java +++ b/photon-core/src/main/java/org/photonvision/vision/opencv/ContourGroupingMode.java @@ -18,7 +18,8 @@ package org.photonvision.vision.opencv; public enum ContourGroupingMode { Single(1), - Dual(2); + Dual(2), + TwoOrMore(2); public final int count; diff --git a/photon-core/src/main/java/org/photonvision/vision/pipe/impl/GroupContoursPipe.java b/photon-core/src/main/java/org/photonvision/vision/pipe/impl/GroupContoursPipe.java index e0519f0cb..9cb83b80d 100644 --- a/photon-core/src/main/java/org/photonvision/vision/pipe/impl/GroupContoursPipe.java +++ b/photon-core/src/main/java/org/photonvision/vision/pipe/impl/GroupContoursPipe.java @@ -41,6 +41,16 @@ public class GroupContoursPipe for (var contour : input) { m_targets.add(new PotentialTarget(contour)); } + } + // Check if we have at least 2 targets for 2 or more + // This will only ever return 1 contour! + else if (params.getGroup() == ContourGroupingMode.TwoOrMore + && input.size() >= ContourGroupingMode.TwoOrMore.count) { + // Just blob everything together + Contour groupedContour = Contour.combineContourList(input); + if (groupedContour != null) { + m_targets.add(new PotentialTarget(groupedContour, input)); + } } else { int groupingCount = params.getGroup().count; @@ -52,14 +62,12 @@ public class GroupContoursPipe for (int i = 0; i < input.size() - 1; i++) { // make a list of the desired count of contours to group - List groupingSet; + // (Just make sure we don't get an index out of bounds exception + if (i < 0 || i + groupingCount > input.size()) continue; + + // If we're in two or more mode, just try to group everything + List groupingSet = input.subList(i, i + groupingCount); - // TODO: are these try/catch avoidable? - try { - groupingSet = input.subList(i, i + groupingCount); - } catch (IndexOutOfBoundsException e) { - continue; - } try { // FYI: This method only takes 2 contours! Contour groupedContour = diff --git a/photon-core/src/main/java/org/photonvision/vision/pipeline/ColoredShapePipelineSettings.java b/photon-core/src/main/java/org/photonvision/vision/pipeline/ColoredShapePipelineSettings.java index 40a67a56c..979d35d71 100644 --- a/photon-core/src/main/java/org/photonvision/vision/pipeline/ColoredShapePipelineSettings.java +++ b/photon-core/src/main/java/org/photonvision/vision/pipeline/ColoredShapePipelineSettings.java @@ -21,10 +21,7 @@ import java.util.Objects; import org.photonvision.common.util.numbers.DoubleCouple; import org.photonvision.common.util.numbers.IntegerCouple; import org.photonvision.vision.calibration.CameraCalibrationCoefficients; -import org.photonvision.vision.opencv.ContourGroupingMode; -import org.photonvision.vision.opencv.ContourIntersectionDirection; import org.photonvision.vision.opencv.ContourShape; -import org.photonvision.vision.pipe.impl.CornerDetectionPipe; @JsonTypeName("ColoredShapePipelineSettings") public class ColoredShapePipelineSettings extends AdvancedPipelineSettings { @@ -37,23 +34,10 @@ public class ColoredShapePipelineSettings extends AdvancedPipelineSettings { public int minDist = 20; public int maxCannyThresh = 90; public int circleAccuracy = 20; - // how many contours to attempt to group (Single, Dual) - public ContourGroupingMode contourGroupingMode = ContourGroupingMode.Single; - - // the direction in which contours must intersect to be considered intersecting - public ContourIntersectionDirection contourIntersection = ContourIntersectionDirection.Up; // 3d settings public CameraCalibrationCoefficients cameraCalibration; - // Corner detection settings - public CornerDetectionPipe.DetectionStrategy cornerDetectionStrategy = - CornerDetectionPipe.DetectionStrategy.APPROX_POLY_DP_AND_EXTREME_CORNERS; - public boolean cornerDetectionUseConvexHulls = true; - public boolean cornerDetectionExactSideCount = false; - public int cornerDetectionSideCount = 4; - public double cornerDetectionAccuracyPercentage = 10; - public boolean erode = false; public boolean dilate = false; diff --git a/photon-core/src/main/java/org/photonvision/vision/pipeline/ReflectivePipelineSettings.java b/photon-core/src/main/java/org/photonvision/vision/pipeline/ReflectivePipelineSettings.java index 97a40da34..c70342f02 100644 --- a/photon-core/src/main/java/org/photonvision/vision/pipeline/ReflectivePipelineSettings.java +++ b/photon-core/src/main/java/org/photonvision/vision/pipeline/ReflectivePipelineSettings.java @@ -17,26 +17,9 @@ package org.photonvision.vision.pipeline; import com.fasterxml.jackson.annotation.JsonTypeName; -import org.photonvision.vision.opencv.ContourGroupingMode; -import org.photonvision.vision.opencv.ContourIntersectionDirection; -import org.photonvision.vision.pipe.impl.CornerDetectionPipe; @JsonTypeName("ReflectivePipelineSettings") public class ReflectivePipelineSettings extends AdvancedPipelineSettings { - // how many contours to attempt to group (Single, Dual) - public ContourGroupingMode contourGroupingMode = ContourGroupingMode.Single; - - // the direction in which contours must intersect to be considered intersecting - public ContourIntersectionDirection contourIntersection = ContourIntersectionDirection.Up; - - // Corner detection settings - public CornerDetectionPipe.DetectionStrategy cornerDetectionStrategy = - CornerDetectionPipe.DetectionStrategy.APPROX_POLY_DP_AND_EXTREME_CORNERS; - public boolean cornerDetectionUseConvexHulls = true; - public boolean cornerDetectionExactSideCount = false; - public int cornerDetectionSideCount = 4; - public double cornerDetectionAccuracyPercentage = 10; - public ReflectivePipelineSettings() { super(); pipelineType = PipelineType.Reflective; diff --git a/photon-server/src/main/java/org/photonvision/Main.java b/photon-server/src/main/java/org/photonvision/Main.java index ea2ba7478..4c4cae586 100644 --- a/photon-server/src/main/java/org/photonvision/Main.java +++ b/photon-server/src/main/java/org/photonvision/Main.java @@ -87,62 +87,100 @@ public class Main { } private static void addTestModeSources() { - var collectedSources = new ArrayList(); + ConfigManager.getInstance().load(); var camConf2019 = - new CameraConfiguration("WPI2019", TestUtils.getTestMode2019ImagePath().toString()); - camConf2019.FOV = TestUtils.WPI2019Image.FOV; - camConf2019.calibrations.add(TestUtils.get2019LifeCamCoeffs(true)); + ConfigManager.getInstance().getConfig().getCameraConfigurations().get("WPI2019"); + if (camConf2019 == null) { + camConf2019 = + new CameraConfiguration("WPI2019", TestUtils.getTestMode2019ImagePath().toString()); + camConf2019.FOV = TestUtils.WPI2019Image.FOV; + camConf2019.calibrations.add(TestUtils.get2019LifeCamCoeffs(true)); - var pipeline2019 = new ReflectivePipelineSettings(); - pipeline2019.pipelineNickname = "CargoShip"; - pipeline2019.targetModel = TargetModel.k2019DualTarget; - pipeline2019.outputShowMultipleTargets = true; - pipeline2019.contourGroupingMode = ContourGroupingMode.Dual; + var pipeline2019 = new ReflectivePipelineSettings(); + pipeline2019.pipelineNickname = "CargoShip"; + pipeline2019.targetModel = TargetModel.k2019DualTarget; + pipeline2019.outputShowMultipleTargets = true; + pipeline2019.contourGroupingMode = ContourGroupingMode.Dual; + pipeline2019.inputShouldShow = true; - var psList2019 = new ArrayList(); - psList2019.add(pipeline2019); - - var fvs2019 = new FileVisionSource(camConf2019); + var psList2019 = new ArrayList(); + psList2019.add(pipeline2019); + camConf2019.pipelineSettings = psList2019; + } var camConf2020 = - new CameraConfiguration("WPI2020", TestUtils.getTestMode2020ImagePath().toString()); - camConf2020.FOV = TestUtils.WPI2020Image.FOV; - camConf2019.calibrations.add(TestUtils.get2019LifeCamCoeffs(true)); + ConfigManager.getInstance().getConfig().getCameraConfigurations().get("WPI2020"); + if (camConf2020 == null) { + camConf2020 = + new CameraConfiguration("WPI2020", TestUtils.getTestMode2020ImagePath().toString()); + camConf2020.FOV = TestUtils.WPI2020Image.FOV; + camConf2020.calibrations.add(TestUtils.get2019LifeCamCoeffs(true)); - var pipeline2020 = new ReflectivePipelineSettings(); - pipeline2020.pipelineNickname = "OuterPort"; - pipeline2020.targetModel = TargetModel.k2020HighGoalOuter; - camConf2020.calibrations.add(TestUtils.get2020LifeCamCoeffs(true)); + var pipeline2020 = new ReflectivePipelineSettings(); + pipeline2020.pipelineNickname = "OuterPort"; + pipeline2020.targetModel = TargetModel.k2020HighGoalOuter; + camConf2020.calibrations.add(TestUtils.get2020LifeCamCoeffs(true)); + pipeline2020.inputShouldShow = true; - var psList2020 = new ArrayList(); - psList2020.add(pipeline2020); + var psList2020 = new ArrayList(); + psList2020.add(pipeline2020); + camConf2020.pipelineSettings = psList2020; + } - var fvs2020 = new FileVisionSource(camConf2020); + var camConf2022 = + ConfigManager.getInstance().getConfig().getCameraConfigurations().get("WPI2022"); + if (camConf2022 == null) { + camConf2022 = + new CameraConfiguration("WPI2022", TestUtils.getTestMode2022ImagePath().toString()); + camConf2022.FOV = TestUtils.WPI2022Image.FOV; + camConf2022.calibrations.add(TestUtils.get2019LifeCamCoeffs(true)); - fvs2019.getCameraConfiguration().pipelineSettings = psList2019; - fvs2020.getCameraConfiguration().pipelineSettings = psList2020; - collectedSources.add(fvs2019); - collectedSources.add(fvs2020); + var pipeline2022 = new ReflectivePipelineSettings(); + pipeline2022.pipelineNickname = "OuterPort"; + pipeline2022.targetModel = TargetModel.k2020HighGoalOuter; + pipeline2022.inputShouldShow = true; + // camConf2020.calibrations.add(TestUtils.get2020LifeCamCoeffs(true)); + + var psList2022 = new ArrayList(); + psList2022.add(pipeline2022); + camConf2022.pipelineSettings = psList2022; + } // Colored shape testing var camConfShape = - new CameraConfiguration( - "Shape", - TestUtils.getPowercellImagePath(TestUtils.PowercellTestImages.kPowercell_test_1, true) - .toString()); - var settings = new ColoredShapePipelineSettings(); - settings.hsvHue = new IntegerCouple(0, 35); - settings.hsvSaturation = new IntegerCouple(82, 255); - settings.hsvValue = new IntegerCouple(62, 255); - settings.contourShape = ContourShape.Triangle; - settings.outputShowMultipleTargets = true; - settings.circleAccuracy = 15; - camConfShape.addPipelineSetting(settings); - var fvsShape = new FileVisionSource(camConfShape); - collectedSources.add(fvsShape); + ConfigManager.getInstance().getConfig().getCameraConfigurations().get("Shape"); + + // If we haven't saved shape settings, create a new one + if (camConfShape == null) { + camConfShape = + new CameraConfiguration( + "Shape", + TestUtils.getPowercellImagePath(TestUtils.PowercellTestImages.kPowercell_test_1, true) + .toString()); + var settings = new ColoredShapePipelineSettings(); + settings.hsvHue = new IntegerCouple(0, 35); + settings.hsvSaturation = new IntegerCouple(82, 255); + settings.hsvValue = new IntegerCouple(62, 255); + settings.contourShape = ContourShape.Triangle; + settings.outputShowMultipleTargets = true; + settings.circleAccuracy = 15; + settings.inputShouldShow = true; + camConfShape.addPipelineSetting(settings); + } + + var collectedSources = new ArrayList(); + + var fvsShape = new FileVisionSource(camConfShape); + var fvs2019 = new FileVisionSource(camConf2019); + var fvs2020 = new FileVisionSource(camConf2020); + var fvs2022 = new FileVisionSource(camConf2022); + + collectedSources.add(fvs2022); + collectedSources.add(fvsShape); + collectedSources.add(fvs2020); + collectedSources.add(fvs2019); - // logger.info("Adding " + allSources.size() + " configs to VMM."); VisionModuleManager.getInstance().addSources(collectedSources).forEach(VisionModule::start); ConfigManager.getInstance().addCameraConfigurations(collectedSources); } diff --git a/test-resources/testimages/2022/WPI/Chute8ft6in.png b/test-resources/testimages/2022/WPI/Chute8ft6in.png new file mode 100644 index 000000000..407237ef9 Binary files /dev/null and b/test-resources/testimages/2022/WPI/Chute8ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/Details.txt b/test-resources/testimages/2022/WPI/Details.txt new file mode 100644 index 000000000..2c3143f55 --- /dev/null +++ b/test-resources/testimages/2022/WPI/Details.txt @@ -0,0 +1,11 @@ +All photos were taken with a Microsoft Lifecam 3000 at 1280x720 with reduced brightness and exposure and fixed white balance. +The camera was at a height of approximately 31.25in for all photos. +All distances represent an approximate measurement across the ground to the projection of the closest point on the target ring. + +Angle 1 Photos. The following sets were all taken at a single consistent camera angle +"Terminal" photos are taken approximately on the line between the center of the terminal and the center of the goal. +"Launchpad" photos taken approximately on the line between the center of the each Launchpad and the center of the goal + +Angle 2 Photos. The following sets were taken from a second higher angle. +"Tarmac Center" photos are taken approximately on a line perpendicular to the center of a fender +"Chute" photo is taken approximately on a line perpendicular to the center of a chute diff --git a/test-resources/testimages/2022/WPI/FarLaunchpad10ft10in.png b/test-resources/testimages/2022/WPI/FarLaunchpad10ft10in.png new file mode 100644 index 000000000..67928b26c Binary files /dev/null and b/test-resources/testimages/2022/WPI/FarLaunchpad10ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/FarLaunchpad13ft10in.png b/test-resources/testimages/2022/WPI/FarLaunchpad13ft10in.png new file mode 100644 index 000000000..b5e9664cd Binary files /dev/null and b/test-resources/testimages/2022/WPI/FarLaunchpad13ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/FarLaunchpad17ft2in.png b/test-resources/testimages/2022/WPI/FarLaunchpad17ft2in.png new file mode 100644 index 000000000..77eca7838 Binary files /dev/null and b/test-resources/testimages/2022/WPI/FarLaunchpad17ft2in.png differ diff --git a/test-resources/testimages/2022/WPI/FarLaunchpad6ft0in.png b/test-resources/testimages/2022/WPI/FarLaunchpad6ft0in.png new file mode 100644 index 000000000..0d17837ad Binary files /dev/null and b/test-resources/testimages/2022/WPI/FarLaunchpad6ft0in.png differ diff --git a/test-resources/testimages/2022/WPI/FarLaunchpad7ft10in.png b/test-resources/testimages/2022/WPI/FarLaunchpad7ft10in.png new file mode 100644 index 000000000..83b1fee58 Binary files /dev/null and b/test-resources/testimages/2022/WPI/FarLaunchpad7ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/NearLaunchpad10ft10in.png b/test-resources/testimages/2022/WPI/NearLaunchpad10ft10in.png new file mode 100644 index 000000000..bf9797e49 Binary files /dev/null and b/test-resources/testimages/2022/WPI/NearLaunchpad10ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/NearLaunchpad12ft10in.png b/test-resources/testimages/2022/WPI/NearLaunchpad12ft10in.png new file mode 100644 index 000000000..ff733c0db Binary files /dev/null and b/test-resources/testimages/2022/WPI/NearLaunchpad12ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/NearLaunchpad13ft6in.png b/test-resources/testimages/2022/WPI/NearLaunchpad13ft6in.png new file mode 100644 index 000000000..ea1a5127c Binary files /dev/null and b/test-resources/testimages/2022/WPI/NearLaunchpad13ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/NearLaunchpad5ft4in.png b/test-resources/testimages/2022/WPI/NearLaunchpad5ft4in.png new file mode 100644 index 000000000..b94e501ff Binary files /dev/null and b/test-resources/testimages/2022/WPI/NearLaunchpad5ft4in.png differ diff --git a/test-resources/testimages/2022/WPI/NearLaunchpad6ft10in.png b/test-resources/testimages/2022/WPI/NearLaunchpad6ft10in.png new file mode 100644 index 000000000..887dd15ea Binary files /dev/null and b/test-resources/testimages/2022/WPI/NearLaunchpad6ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/NearLaunchpad8ft10in.png b/test-resources/testimages/2022/WPI/NearLaunchpad8ft10in.png new file mode 100644 index 000000000..ac756ed68 Binary files /dev/null and b/test-resources/testimages/2022/WPI/NearLaunchpad8ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/TarmacCenter2ft10in.png b/test-resources/testimages/2022/WPI/TarmacCenter2ft10in.png new file mode 100644 index 000000000..f976a4b2a Binary files /dev/null and b/test-resources/testimages/2022/WPI/TarmacCenter2ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/TarmacCenter3ft10in.png b/test-resources/testimages/2022/WPI/TarmacCenter3ft10in.png new file mode 100644 index 000000000..9255efa92 Binary files /dev/null and b/test-resources/testimages/2022/WPI/TarmacCenter3ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/TarmacCenter4ft10in.png b/test-resources/testimages/2022/WPI/TarmacCenter4ft10in.png new file mode 100644 index 000000000..e6a34ea60 Binary files /dev/null and b/test-resources/testimages/2022/WPI/TarmacCenter4ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/TarmacCenter5ft10in.png b/test-resources/testimages/2022/WPI/TarmacCenter5ft10in.png new file mode 100644 index 000000000..f60d20dee Binary files /dev/null and b/test-resources/testimages/2022/WPI/TarmacCenter5ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/TarmacCenter6ft10in.png b/test-resources/testimages/2022/WPI/TarmacCenter6ft10in.png new file mode 100644 index 000000000..4a4bfd6a3 Binary files /dev/null and b/test-resources/testimages/2022/WPI/TarmacCenter6ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/TarmacCenter7ft10in.png b/test-resources/testimages/2022/WPI/TarmacCenter7ft10in.png new file mode 100644 index 000000000..c8c266d3a Binary files /dev/null and b/test-resources/testimages/2022/WPI/TarmacCenter7ft10in.png differ diff --git a/test-resources/testimages/2022/WPI/Terminal10ft6in.png b/test-resources/testimages/2022/WPI/Terminal10ft6in.png new file mode 100644 index 000000000..ae40903f9 Binary files /dev/null and b/test-resources/testimages/2022/WPI/Terminal10ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/Terminal12ft6in.png b/test-resources/testimages/2022/WPI/Terminal12ft6in.png new file mode 100644 index 000000000..cd212575b Binary files /dev/null and b/test-resources/testimages/2022/WPI/Terminal12ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/Terminal14ft6in.png b/test-resources/testimages/2022/WPI/Terminal14ft6in.png new file mode 100644 index 000000000..9754a9bb9 Binary files /dev/null and b/test-resources/testimages/2022/WPI/Terminal14ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/Terminal16ft6in.png b/test-resources/testimages/2022/WPI/Terminal16ft6in.png new file mode 100644 index 000000000..301729204 Binary files /dev/null and b/test-resources/testimages/2022/WPI/Terminal16ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/Terminal18ft6in.png b/test-resources/testimages/2022/WPI/Terminal18ft6in.png new file mode 100644 index 000000000..81ab4d7dd Binary files /dev/null and b/test-resources/testimages/2022/WPI/Terminal18ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/Terminal22ft6in.png b/test-resources/testimages/2022/WPI/Terminal22ft6in.png new file mode 100644 index 000000000..0c9875e3b Binary files /dev/null and b/test-resources/testimages/2022/WPI/Terminal22ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/Terminal5ft6in.png b/test-resources/testimages/2022/WPI/Terminal5ft6in.png new file mode 100644 index 000000000..263079f78 Binary files /dev/null and b/test-resources/testimages/2022/WPI/Terminal5ft6in.png differ diff --git a/test-resources/testimages/2022/WPI/Terminal8ft6in.png b/test-resources/testimages/2022/WPI/Terminal8ft6in.png new file mode 100644 index 000000000..d46e549bf Binary files /dev/null and b/test-resources/testimages/2022/WPI/Terminal8ft6in.png differ