From cfe6c8aae4ca3b54b6b5a8d195a31163ab0a9c5d Mon Sep 17 00:00:00 2001 From: Toby Macaluso Date: Mon, 18 Jul 2016 10:28:00 -0400 Subject: [PATCH 1/9] Fixes Filter contours to use double division instead of integer devision for calculating the ratio. --- .../grip/core/operations/composite/FilterContoursOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java index 20db252038..e208caaebf 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java @@ -191,7 +191,7 @@ public void perform() { continue; } - final double ratio = bb.width() / bb.height(); + final double ratio = (double) bb.width() / bb.height(); if (ratio < minRatio || ratio > maxRatio) { continue; } From 12d5f55ca8c2fed08f000fc9bfc8e93b15d08c67 Mon Sep 17 00:00:00 2001 From: Toby Macaluso Date: Tue, 19 Jul 2016 14:17:47 -0400 Subject: [PATCH 2/9] Split filter contours into two separate operations for ease of use. --- .../wpi/grip/core/operations/Operations.java | 9 +- ...a => AdvancedFilterContoursOperation.java} | 35 ++++-- .../SimpleFilterContoursOperation.java | 119 ++++++++++++++++++ 3 files changed, 150 insertions(+), 13 deletions(-) rename core/src/main/java/edu/wpi/grip/core/operations/composite/{FilterContoursOperation.java => AdvancedFilterContoursOperation.java} (86%) create mode 100644 core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java diff --git a/core/src/main/java/edu/wpi/grip/core/operations/Operations.java b/core/src/main/java/edu/wpi/grip/core/operations/Operations.java index 7056f7e5fe..a05f193981 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/Operations.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/Operations.java @@ -3,13 +3,13 @@ import edu.wpi.grip.core.FileManager; import edu.wpi.grip.core.OperationMetaData; import edu.wpi.grip.core.events.OperationAddedEvent; +import edu.wpi.grip.core.operations.composite.AdvancedFilterContoursOperation; import edu.wpi.grip.core.operations.composite.BlobsReport; import edu.wpi.grip.core.operations.composite.BlurOperation; import edu.wpi.grip.core.operations.composite.ContoursReport; import edu.wpi.grip.core.operations.composite.ConvexHullsOperation; import edu.wpi.grip.core.operations.composite.DesaturateOperation; import edu.wpi.grip.core.operations.composite.DistanceTransformOperation; -import edu.wpi.grip.core.operations.composite.FilterContoursOperation; import edu.wpi.grip.core.operations.composite.FilterLinesOperation; import edu.wpi.grip.core.operations.composite.FindBlobsOperation; import edu.wpi.grip.core.operations.composite.FindContoursOperation; @@ -23,6 +23,7 @@ import edu.wpi.grip.core.operations.composite.RGBThresholdOperation; import edu.wpi.grip.core.operations.composite.ResizeOperation; import edu.wpi.grip.core.operations.composite.SaveImageOperation; +import edu.wpi.grip.core.operations.composite.SimpleFilterContoursOperation; import edu.wpi.grip.core.operations.composite.SwitchOperation; import edu.wpi.grip.core.operations.composite.ThresholdMoving; import edu.wpi.grip.core.operations.composite.ValveOperation; @@ -85,8 +86,10 @@ public class Operations { () -> new DesaturateOperation(isf, osf)), new OperationMetaData(DistanceTransformOperation.DESCRIPTION, () -> new DistanceTransformOperation(isf, osf)), - new OperationMetaData(FilterContoursOperation.DESCRIPTION, - () -> new FilterContoursOperation(isf, osf)), + new OperationMetaData(SimpleFilterContoursOperation.DESCRIPTION, + () -> new SimpleFilterContoursOperation(isf, osf)), + new OperationMetaData(AdvancedFilterContoursOperation.DESCRIPTION, + () -> new AdvancedFilterContoursOperation(isf, osf)), new OperationMetaData(FilterLinesOperation.DESCRIPTION, () -> new FilterLinesOperation(isf, osf)), new OperationMetaData(FindBlobsOperation.DESCRIPTION, diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java similarity index 86% rename from core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java rename to core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java index e208caaebf..31140b9652 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java @@ -28,11 +28,11 @@ * small objects, as well as contours that do not meet the expected characteristics of the feature * we're actually looking for. So, this operation can help narrow them down. */ -public class FilterContoursOperation implements Operation { +public class AdvancedFilterContoursOperation implements Operation { public static final OperationDescription DESCRIPTION = OperationDescription.builder() - .name("Filter Contours") + .name("Advanced Filter Contours") .summary("Find contours matching certain criteria") .category(OperationDescription.Category.FEATURE_DETECTION) .icon(Icon.iconStream("find-contours")) @@ -45,9 +45,16 @@ public class FilterContoursOperation implements Operation { private final SocketHint minAreaHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Min Area", 0, 0, Integer.MAX_VALUE); + private final SocketHint maxAreaHint = + SocketHints.Inputs.createNumberSpinnerSocketHint("Max Area", 10000, 0, Integer.MAX_VALUE); + private final SocketHint minPerimeterHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Min Perimeter", 0, 0, Integer.MAX_VALUE); + private final SocketHint maxPerimeterHint = + SocketHints.Inputs.createNumberSpinnerSocketHint("Max Perimeter", 10000, 0, + Integer.MAX_VALUE); + private final SocketHint minWidthHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Min Width", 0, 0, Integer.MAX_VALUE); @@ -79,7 +86,9 @@ public class FilterContoursOperation implements Operation { private final InputSocket contoursSocket; private final InputSocket minAreaSocket; + private final InputSocket maxAreaSocket; private final InputSocket minPerimeterSocket; + private final InputSocket maxPerimeterSocket; private final InputSocket minWidthSocket; private final InputSocket maxWidthSocket; private final InputSocket minHeightSocket; @@ -93,11 +102,13 @@ public class FilterContoursOperation implements Operation { private final OutputSocket outputSocket; @SuppressWarnings("JavadocMethod") - public FilterContoursOperation(InputSocket.Factory inputSocketFactory, OutputSocket.Factory - outputSocketFactory) { + public AdvancedFilterContoursOperation(InputSocket.Factory inputSocketFactory, + OutputSocket.Factory outputSocketFactory) { this.contoursSocket = inputSocketFactory.create(contoursHint); this.minAreaSocket = inputSocketFactory.create(minAreaHint); + this.maxAreaSocket = inputSocketFactory.create(maxAreaHint); this.minPerimeterSocket = inputSocketFactory.create(minPerimeterHint); + this.maxPerimeterSocket = inputSocketFactory.create(maxPerimeterHint); this.minWidthSocket = inputSocketFactory.create(minWidthHint); this.maxWidthSocket = inputSocketFactory.create(maxWidthHint); this.minHeightSocket = inputSocketFactory.create(minHeightHint); @@ -116,16 +127,18 @@ public List getInputSockets() { return ImmutableList.of( contoursSocket, minAreaSocket, + maxAreaSocket, minPerimeterSocket, + maxPerimeterSocket, minWidthSocket, maxWidthSocket, minHeightSocket, maxHeightSocket, - soliditySocket, - maxVertexSocket, minVertexSocket, + maxVertexSocket, minRatioSocket, - maxRatioSocket + maxRatioSocket, + soliditySocket ); } @@ -141,7 +154,9 @@ public List getOutputSockets() { public void perform() { final InputSocket inputSocket = contoursSocket; final double minArea = minAreaSocket.getValue().get().doubleValue(); + final double maxArea = maxAreaSocket.getValue().get().doubleValue(); final double minPerimeter = minPerimeterSocket.getValue().get().doubleValue(); + final double maxPerimeter = maxPerimeterSocket.getValue().get().doubleValue(); final double minWidth = minWidthSocket.getValue().get().doubleValue(); final double maxWidth = maxWidthSocket.getValue().get().doubleValue(); final double minHeight = minHeightSocket.getValue().get().doubleValue(); @@ -174,10 +189,10 @@ public void perform() { } final double area = contourArea(contour); - if (area < minArea) { + if (area < minArea || area > maxArea) { continue; } - if (arcLength(contour, true) < minPerimeter) { + if (arcLength(contour, true) < minPerimeter || arcLength(contour, true) > minPerimeter) { continue; } @@ -204,4 +219,4 @@ public void perform() { outputSocket.setValue(new ContoursReport(outputContours, inputSocket.getValue().get().getRows(), inputSocket.getValue().get().getCols())); } -} +} \ No newline at end of file diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java new file mode 100644 index 0000000000..d1c9ae2130 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java @@ -0,0 +1,119 @@ +package edu.wpi.grip.core.operations.composite; + +import edu.wpi.grip.core.Operation; +import edu.wpi.grip.core.OperationDescription; +import edu.wpi.grip.core.sockets.InputSocket; +import edu.wpi.grip.core.sockets.OutputSocket; +import edu.wpi.grip.core.sockets.SocketHint; +import edu.wpi.grip.core.sockets.SocketHints; +import edu.wpi.grip.core.util.Icon; + +import com.google.common.collect.ImmutableList; + +import java.util.List; + +import static org.bytedeco.javacpp.opencv_core.Mat; +import static org.bytedeco.javacpp.opencv_core.MatVector; +import static org.bytedeco.javacpp.opencv_core.Rect; +import static org.bytedeco.javacpp.opencv_imgproc.arcLength; +import static org.bytedeco.javacpp.opencv_imgproc.boundingRect; +import static org.bytedeco.javacpp.opencv_imgproc.contourArea; + +/** + * An {@link Operation} that takes in a list of contours and outputs a list of any contours in the + * input that match all of several criteria. Right now, the user can specify a minimum area, + * minimum perimeter, and ranges for width and height. This is useful because running a Find + * Contours on a real-life image typically leads to many small undesirable contours from noise and + * small objects, as well as contours that do not meet the expected characteristics of the feature + * we're actually looking for. So, this operation can help narrow them down. + */ +public class SimpleFilterContoursOperation implements Operation { + + public static final OperationDescription DESCRIPTION = + OperationDescription.builder() + .name("Simple Filter Contours") + .summary("Find contours matching certain criteria") + .category(OperationDescription.Category.FEATURE_DETECTION) + .icon(Icon.iconStream("find-contours")) + .build(); + + private final SocketHint contoursHint = new SocketHint.Builder<>(ContoursReport + .class) + .identifier("Contours").initialValueSupplier(ContoursReport::new).build(); + + private final SocketHint minAreaHint = + SocketHints.Inputs.createNumberSpinnerSocketHint("Min Area", 0, 0, Integer.MAX_VALUE); + + private final SocketHint minPerimeterHint = + SocketHints.Inputs.createNumberSpinnerSocketHint("Min Perimeter", 0, 0, Integer.MAX_VALUE); + + + private final InputSocket contoursSocket; + private final InputSocket minAreaSocket; + private final InputSocket minPerimeterSocket; + + private final OutputSocket outputSocket; + + @SuppressWarnings("JavadocMethod") + public SimpleFilterContoursOperation(InputSocket.Factory inputSocketFactory, OutputSocket.Factory + outputSocketFactory) { + this.contoursSocket = inputSocketFactory.create(contoursHint); + this.minAreaSocket = inputSocketFactory.create(minAreaHint); + this.minPerimeterSocket = inputSocketFactory.create(minPerimeterHint); + + this.outputSocket = outputSocketFactory.create(contoursHint); + } + + @Override + public List getInputSockets() { + return ImmutableList.of( + contoursSocket, + minAreaSocket, + minPerimeterSocket + ); + } + + @Override + public List getOutputSockets() { + return ImmutableList.of( + outputSocket + ); + } + + @Override + @SuppressWarnings("unchecked") + public void perform() { + final InputSocket inputSocket = contoursSocket; + final double minArea = minAreaSocket.getValue().get().doubleValue(); + final double minPerimeter = minPerimeterSocket.getValue().get().doubleValue(); + + + final MatVector inputContours = inputSocket.getValue().get().getContours(); + final MatVector outputContours = new MatVector(inputContours.size()); + final Mat hull = new Mat(); + + // Add contours from the input vector to the output vector only if they pass all of the + // criteria (minimum + // area, minimum perimeter, width, and height, etc...) + int filteredContourCount = 0; + for (int i = 0; i < inputContours.size(); i++) { + final Mat contour = inputContours.get(i); + + final Rect bb = boundingRect(contour); + + final double area = contourArea(contour); + if (area < minArea) { + continue; + } + if (arcLength(contour, true) < minPerimeter) { + continue; + } + outputContours.put(filteredContourCount++, contour); + } + + outputContours.resize(filteredContourCount); + + outputSocket.setValue(new ContoursReport(outputContours, + inputSocket.getValue().get().getRows(), inputSocket.getValue().get().getCols())); + } +} From f299c47665c78ff4ef83b07dd026f0df0ecc5679 Mon Sep 17 00:00:00 2001 From: Toby Macaluso Date: Tue, 19 Jul 2016 14:44:34 -0400 Subject: [PATCH 3/9] Cleanup. --- .../composite/SimpleFilterContoursOperation.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java index d1c9ae2130..e9ffd366c2 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java @@ -14,9 +14,7 @@ import static org.bytedeco.javacpp.opencv_core.Mat; import static org.bytedeco.javacpp.opencv_core.MatVector; -import static org.bytedeco.javacpp.opencv_core.Rect; import static org.bytedeco.javacpp.opencv_imgproc.arcLength; -import static org.bytedeco.javacpp.opencv_imgproc.boundingRect; import static org.bytedeco.javacpp.opencv_imgproc.contourArea; /** @@ -90,17 +88,13 @@ public void perform() { final MatVector inputContours = inputSocket.getValue().get().getContours(); final MatVector outputContours = new MatVector(inputContours.size()); - final Mat hull = new Mat(); // Add contours from the input vector to the output vector only if they pass all of the - // criteria (minimum - // area, minimum perimeter, width, and height, etc...) + // criteria (minimum area, minimum perimeter) int filteredContourCount = 0; for (int i = 0; i < inputContours.size(); i++) { final Mat contour = inputContours.get(i); - final Rect bb = boundingRect(contour); - final double area = contourArea(contour); if (area < minArea) { continue; From c009f1f6cc855a0f6b83c3d74bffa38e26a45198 Mon Sep 17 00:00:00 2001 From: Toby Macaluso Date: Thu, 21 Jul 2016 10:09:22 -0400 Subject: [PATCH 4/9] Added a best fit rectangles option to advanced filter contours. --- .../AdvancedFilterContoursOperation.java | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java index 31140b9652..4721113f9c 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java @@ -10,6 +10,8 @@ import com.google.common.collect.ImmutableList; +import org.bytedeco.javacpp.opencv_core; + import java.util.List; import static org.bytedeco.javacpp.opencv_core.Mat; @@ -19,6 +21,7 @@ import static org.bytedeco.javacpp.opencv_imgproc.boundingRect; import static org.bytedeco.javacpp.opencv_imgproc.contourArea; import static org.bytedeco.javacpp.opencv_imgproc.convexHull; +import static org.bytedeco.javacpp.opencv_imgproc.minAreaRect; /** * An {@link Operation} that takes in a list of contours and outputs a list of any contours in the @@ -51,6 +54,9 @@ public class AdvancedFilterContoursOperation implements Operation { private final SocketHint minPerimeterHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Min Perimeter", 0, 0, Integer.MAX_VALUE); + private final SocketHint rotatedRectHint = + SocketHints.createBooleanSocketHint("Best Fit Rectangles", false); + private final SocketHint maxPerimeterHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Max Perimeter", 10000, 0, Integer.MAX_VALUE); @@ -89,6 +95,7 @@ public class AdvancedFilterContoursOperation implements Operation { private final InputSocket maxAreaSocket; private final InputSocket minPerimeterSocket; private final InputSocket maxPerimeterSocket; + private final InputSocket rotatedRectSocket; private final InputSocket minWidthSocket; private final InputSocket maxWidthSocket; private final InputSocket minHeightSocket; @@ -109,6 +116,7 @@ public AdvancedFilterContoursOperation(InputSocket.Factory inputSocketFactory, this.maxAreaSocket = inputSocketFactory.create(maxAreaHint); this.minPerimeterSocket = inputSocketFactory.create(minPerimeterHint); this.maxPerimeterSocket = inputSocketFactory.create(maxPerimeterHint); + this.rotatedRectSocket = inputSocketFactory.create(rotatedRectHint); this.minWidthSocket = inputSocketFactory.create(minWidthHint); this.maxWidthSocket = inputSocketFactory.create(maxWidthHint); this.minHeightSocket = inputSocketFactory.create(minHeightHint); @@ -130,6 +138,7 @@ public List getInputSockets() { maxAreaSocket, minPerimeterSocket, maxPerimeterSocket, + rotatedRectSocket, minWidthSocket, maxWidthSocket, minHeightSocket, @@ -157,6 +166,7 @@ public void perform() { final double maxArea = maxAreaSocket.getValue().get().doubleValue(); final double minPerimeter = minPerimeterSocket.getValue().get().doubleValue(); final double maxPerimeter = maxPerimeterSocket.getValue().get().doubleValue(); + final boolean rotatedRect = rotatedRectSocket.getValue().get().booleanValue(); final double minWidth = minWidthSocket.getValue().get().doubleValue(); final double maxWidth = maxWidthSocket.getValue().get().doubleValue(); final double minHeight = minHeightSocket.getValue().get().doubleValue(); @@ -180,11 +190,33 @@ public void perform() { for (int i = 0; i < inputContours.size(); i++) { final Mat contour = inputContours.get(i); - final Rect bb = boundingRect(contour); - if (bb.width() < minWidth || bb.width() > maxWidth) { + double width; + double height; + if (rotatedRect) { + final opencv_core.RotatedRect bb = minAreaRect(contour); + opencv_core.Point2f points = new opencv_core.Point2f(4); + bb.points(points); + final double rotatedWidth = Math.sqrt( Math.pow(points.position(0).x() - points.position(1) + .x(), 2) + Math.pow(points.position(0).y() - points.position(1).y(), 2)); + final double rotatedHeight = Math.sqrt( Math.pow(points.position(1).x() - points.position(2) + .x(), 2) + Math.pow(points.position(1).y() - points.position(2).y(), 2)); + if (Math.abs(bb.angle()) >= 45) { + width = rotatedWidth; + height = rotatedHeight; + } else { + width = rotatedHeight; + height = rotatedWidth; + } + } else { + final Rect normbb = boundingRect(contour); + width = normbb.width(); + height = normbb.height(); + } + + if (width < minWidth || width > maxWidth) { continue; } - if (bb.height() < minHeight || bb.height() > maxHeight) { + if (width < minHeight || width > maxHeight) { continue; } @@ -192,7 +224,7 @@ public void perform() { if (area < minArea || area > maxArea) { continue; } - if (arcLength(contour, true) < minPerimeter || arcLength(contour, true) > minPerimeter) { + if (arcLength(contour, true) < minPerimeter || arcLength(contour, true) > maxPerimeter) { continue; } @@ -206,7 +238,7 @@ public void perform() { continue; } - final double ratio = (double) bb.width() / bb.height(); + final double ratio = width / height; if (ratio < minRatio || ratio > maxRatio) { continue; } From a51ead0977844cc91b9820b6173386c619dfde9d Mon Sep 17 00:00:00 2001 From: Toby Macaluso Date: Mon, 25 Jul 2016 10:04:32 -0400 Subject: [PATCH 5/9] A bit more cleanup. --- .../composite/AdvancedFilterContoursOperation.java | 2 +- .../composite/SimpleFilterContoursOperation.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java index 4721113f9c..f6c6d9695f 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java @@ -55,7 +55,7 @@ public class AdvancedFilterContoursOperation implements Operation { SocketHints.Inputs.createNumberSpinnerSocketHint("Min Perimeter", 0, 0, Integer.MAX_VALUE); private final SocketHint rotatedRectHint = - SocketHints.createBooleanSocketHint("Best Fit Rectangles", false); + SocketHints.createBooleanSocketHint("Rotated Rectangles", false); private final SocketHint maxPerimeterHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Max Perimeter", 10000, 0, diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java index e9ffd366c2..ce445678e8 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java @@ -19,11 +19,11 @@ /** * An {@link Operation} that takes in a list of contours and outputs a list of any contours in the - * input that match all of several criteria. Right now, the user can specify a minimum area, - * minimum perimeter, and ranges for width and height. This is useful because running a Find - * Contours on a real-life image typically leads to many small undesirable contours from noise and - * small objects, as well as contours that do not meet the expected characteristics of the feature - * we're actually looking for. So, this operation can help narrow them down. + * input that match all of several criteria. The user can specify a minimum area and perimeter. + * This is useful because running a FindContours on a real-life image typically leads to many small + * undesirable contours from noise and small objects, as well as contours that do not meet the + * expected characteristics of the feature we're actually looking for. So, this operation can + * help narrow them down. */ public class SimpleFilterContoursOperation implements Operation { From ed9e1dfbb992a1c85a0122844f0c35efadc0a1c5 Mon Sep 17 00:00:00 2001 From: Toby Macaluso Date: Mon, 25 Jul 2016 11:42:14 -0400 Subject: [PATCH 6/9] Modified a some testing and the orders of a few lines for clarity. --- .../AdvancedFilterContoursOperation.java | 10 +++--- .../edu/wpi/grip/projects/testALL.grip | 33 +++++++++++++++---- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java index f6c6d9695f..950e09baf7 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java @@ -54,13 +54,13 @@ public class AdvancedFilterContoursOperation implements Operation { private final SocketHint minPerimeterHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Min Perimeter", 0, 0, Integer.MAX_VALUE); - private final SocketHint rotatedRectHint = - SocketHints.createBooleanSocketHint("Rotated Rectangles", false); - private final SocketHint maxPerimeterHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Max Perimeter", 10000, 0, Integer.MAX_VALUE); + private final SocketHint rotatedRectHint = + SocketHints.createBooleanSocketHint("Rotated Rectangles", false); + private final SocketHint minWidthHint = SocketHints.Inputs.createNumberSpinnerSocketHint("Min Width", 0, 0, Integer.MAX_VALUE); @@ -100,11 +100,11 @@ public class AdvancedFilterContoursOperation implements Operation { private final InputSocket maxWidthSocket; private final InputSocket minHeightSocket; private final InputSocket maxHeightSocket; - private final InputSocket> soliditySocket; private final InputSocket minVertexSocket; private final InputSocket maxVertexSocket; private final InputSocket minRatioSocket; private final InputSocket maxRatioSocket; + private final InputSocket> soliditySocket; private final OutputSocket outputSocket; @@ -121,11 +121,11 @@ public AdvancedFilterContoursOperation(InputSocket.Factory inputSocketFactory, this.maxWidthSocket = inputSocketFactory.create(maxWidthHint); this.minHeightSocket = inputSocketFactory.create(minHeightHint); this.maxHeightSocket = inputSocketFactory.create(maxHeightHint); - this.soliditySocket = inputSocketFactory.create(solidityHint); this.minVertexSocket = inputSocketFactory.create(minVertexHint); this.maxVertexSocket = inputSocketFactory.create(maxVertexHint); this.minRatioSocket = inputSocketFactory.create(minRatioHint); this.maxRatioSocket = inputSocketFactory.create(maxRatioHint); + this.soliditySocket = inputSocketFactory.create(solidityHint); this.outputSocket = outputSocketFactory.create(contoursHint); } diff --git a/core/src/test/resources/edu/wpi/grip/projects/testALL.grip b/core/src/test/resources/edu/wpi/grip/projects/testALL.grip index 092c0c3ee9..8269b09ac1 100644 --- a/core/src/test/resources/edu/wpi/grip/projects/testALL.grip +++ b/core/src/test/resources/edu/wpi/grip/projects/testALL.grip @@ -108,27 +108,48 @@ - + 2.0 - 3.0 + 10000.0 - 1.0 + 3.0 1000.0 - - 3.0 + + true - 20.0 + 1.0 + 10000.0 + + + 3.0 + + + 10000.0 + + + 20.0 + + + 20.0 + + + 20.0 + + + 20.0 + + 0 100 From 1499526e418014c9edda8d57be748f3123b94294 Mon Sep 17 00:00:00 2001 From: Toby Macaluso Date: Wed, 27 Jul 2016 10:12:11 -0400 Subject: [PATCH 7/9] Cleanup --- .../AdvancedFilterContoursOperation.java | 18 ++++++++++-------- .../SimpleFilterContoursOperation.java | 14 ++++++++------ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java index 950e09baf7..f481e146c8 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java @@ -10,13 +10,13 @@ import com.google.common.collect.ImmutableList; -import org.bytedeco.javacpp.opencv_core; - import java.util.List; import static org.bytedeco.javacpp.opencv_core.Mat; import static org.bytedeco.javacpp.opencv_core.MatVector; +import static org.bytedeco.javacpp.opencv_core.Point2f; import static org.bytedeco.javacpp.opencv_core.Rect; +import static org.bytedeco.javacpp.opencv_core.RotatedRect; import static org.bytedeco.javacpp.opencv_imgproc.arcLength; import static org.bytedeco.javacpp.opencv_imgproc.boundingRect; import static org.bytedeco.javacpp.opencv_imgproc.contourArea; @@ -193,13 +193,15 @@ public void perform() { double width; double height; if (rotatedRect) { - final opencv_core.RotatedRect bb = minAreaRect(contour); - opencv_core.Point2f points = new opencv_core.Point2f(4); + final RotatedRect bb = minAreaRect(contour); + Point2f points = new Point2f(4); bb.points(points); - final double rotatedWidth = Math.sqrt( Math.pow(points.position(0).x() - points.position(1) - .x(), 2) + Math.pow(points.position(0).y() - points.position(1).y(), 2)); - final double rotatedHeight = Math.sqrt( Math.pow(points.position(1).x() - points.position(2) - .x(), 2) + Math.pow(points.position(1).y() - points.position(2).y(), 2)); + final double rotatedWidth = Math.sqrt(Math.pow(points.position(0).x() + - points.position(1).x(), 2) + + Math.pow(points.position(0).y() - points.position(1).y(), 2)); + final double rotatedHeight = Math.sqrt( Math.pow(points.position(1).x() + - points.position(2).x(), 2) + + Math.pow(points.position(1).y() - points.position(2).y(), 2)); if (Math.abs(bb.angle()) >= 45) { width = rotatedWidth; height = rotatedHeight; diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java index ce445678e8..37fff85d6c 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/SimpleFilterContoursOperation.java @@ -35,8 +35,8 @@ public class SimpleFilterContoursOperation implements Operation { .icon(Icon.iconStream("find-contours")) .build(); - private final SocketHint contoursHint = new SocketHint.Builder<>(ContoursReport - .class) + private final SocketHint contoursHint = + new SocketHint.Builder<>(ContoursReport.class) .identifier("Contours").initialValueSupplier(ContoursReport::new).build(); private final SocketHint minAreaHint = @@ -53,8 +53,8 @@ public class SimpleFilterContoursOperation implements Operation { private final OutputSocket outputSocket; @SuppressWarnings("JavadocMethod") - public SimpleFilterContoursOperation(InputSocket.Factory inputSocketFactory, OutputSocket.Factory - outputSocketFactory) { + public SimpleFilterContoursOperation( + InputSocket.Factory inputSocketFactory, OutputSocket.Factory outputSocketFactory) { this.contoursSocket = inputSocketFactory.create(contoursHint); this.minAreaSocket = inputSocketFactory.create(minAreaHint); this.minPerimeterSocket = inputSocketFactory.create(minPerimeterHint); @@ -107,7 +107,9 @@ public void perform() { outputContours.resize(filteredContourCount); - outputSocket.setValue(new ContoursReport(outputContours, - inputSocket.getValue().get().getRows(), inputSocket.getValue().get().getCols())); + outputSocket.setValue(new ContoursReport( + outputContours, + inputSocket.getValue().get().getRows(), + inputSocket.getValue().get().getCols())); } } From 50922b10611cc533be176e6dc664fde3ef4ab386 Mon Sep 17 00:00:00 2001 From: Toby Macaluso Date: Wed, 10 Aug 2016 10:01:46 -0400 Subject: [PATCH 8/9] Fixup after merge. --- .../operations/composite/AdvancedFilterContoursOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java index f481e146c8..944c5600a2 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java @@ -253,4 +253,4 @@ public void perform() { outputSocket.setValue(new ContoursReport(outputContours, inputSocket.getValue().get().getRows(), inputSocket.getValue().get().getCols())); } -} \ No newline at end of file +} From 394cd58ab460ef7c9149723f8923a4ea22a2192e Mon Sep 17 00:00:00 2001 From: Patrick Date: Sat, 27 Aug 2016 13:33:02 -0400 Subject: [PATCH 9/9] Added alias from Filter Contours to Advanced Filter Contours --- .../operations/composite/AdvancedFilterContoursOperation.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java index 944c5600a2..734862c11c 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/composite/AdvancedFilterContoursOperation.java @@ -39,6 +39,7 @@ public class AdvancedFilterContoursOperation implements Operation { .summary("Find contours matching certain criteria") .category(OperationDescription.Category.FEATURE_DETECTION) .icon(Icon.iconStream("find-contours")) + .aliases("Filter Contours") .build(); private final SocketHint contoursHint = new SocketHint.Builder<>(ContoursReport