Skip to content

Commit d33d84d

Browse files
committed
Add solidity filter
1 parent 8d1c950 commit d33d84d

2 files changed

Lines changed: 31 additions & 8 deletions

File tree

core/src/main/java/edu/wpi/grip/core/operations/composite/ContoursReport.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66

77
import java.util.Optional;
88

9-
import static org.bytedeco.javacpp.opencv_core.MatVector;
10-
import static org.bytedeco.javacpp.opencv_core.Rect;
11-
import static org.bytedeco.javacpp.opencv_imgproc.boundingRect;
12-
import static org.bytedeco.javacpp.opencv_imgproc.contourArea;
9+
import static org.bytedeco.javacpp.opencv_core.*;
10+
import static org.bytedeco.javacpp.opencv_imgproc.*;
1311

1412
/**
1513
* The output of {@link FindContoursOperation}. This stores a list of contours (which is basically a list of points) in
@@ -113,4 +111,15 @@ public synchronized double[] getHeights() {
113111
}
114112
return heights;
115113
}
114+
115+
@NTValue(key = "solidity")
116+
public synchronized double[] getSolidity() {
117+
final double[] solidities = new double[(int) contours.size()];
118+
Mat hull = new Mat();
119+
for (int i = 0; i < contours.size(); i++) {
120+
convexHull(contours.get(i), hull);
121+
solidities[i] = contourArea(contours.get(i)) / contourArea(hull);
122+
}
123+
return solidities;
124+
}
116125
}

core/src/main/java/edu/wpi/grip/core/operations/composite/FilterContoursOperation.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import edu.wpi.grip.core.*;
55

66
import java.io.InputStream;
7+
import java.util.List;
78
import java.util.Optional;
89

910
import static org.bytedeco.javacpp.opencv_core.*;
@@ -41,6 +42,9 @@ public class FilterContoursOperation implements Operation {
4142
private final SocketHint<Number> maxHeightHint =
4243
SocketHints.Inputs.createNumberSpinnerSocketHint("Max Height", 1000, 0, Integer.MAX_VALUE);
4344

45+
private final SocketHint<List> solidityHint =
46+
SocketHints.Inputs.createNumberListRangeSocketHint("Solidity", 0, 100);
47+
4448
@Override
4549
public String getName() {
4650
return "Filter Contours";
@@ -66,6 +70,7 @@ public InputSocket<?>[] createInputSockets(EventBus eventBus) {
6670
new InputSocket<>(eventBus, maxWidthHint),
6771
new InputSocket<>(eventBus, minHeightHint),
6872
new InputSocket<>(eventBus, maxHeightHint),
73+
new InputSocket<>(eventBus, solidityHint),
6974
};
7075
}
7176

@@ -84,22 +89,31 @@ public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs) {
8489
final double maxWidth = ((Number) inputs[4].getValue().get()).doubleValue();
8590
final double minHeight = ((Number) inputs[5].getValue().get()).doubleValue();
8691
final double maxHeight = ((Number) inputs[6].getValue().get()).doubleValue();
92+
final double minSolidity = ((List<Number>) inputs[7].getValue().get()).get(0).doubleValue();
93+
final double maxSolidity = ((List<Number>) inputs[7].getValue().get()).get(1).doubleValue();
8794

8895
final MatVector inputContours = inputSocket.getValue().get().getContours();
8996
final MatVector outputContours = new MatVector(inputContours.size());
97+
final Mat hull = new Mat();
9098

9199
// Add contours from the input vector to the output vector only if they pass all of the criteria (minimum
92-
// area, minimum perimeter, width, and height)
100+
// area, minimum perimeter, width, and height, etc...)
93101
int filteredContourCount = 0;
94102
for (int i = 0; i < inputContours.size(); i++) {
95103
final Mat contour = inputContours.get(i);
96-
final Rect bb = boundingRect(contour);
97104

98-
if (contourArea(contour) < minArea) continue;
99-
if (arcLength(contour, true) < minPerimeter) continue;
105+
final Rect bb = boundingRect(contour);
100106
if (bb.width() < minWidth || bb.width() > maxWidth) continue;
101107
if (bb.height() < minHeight || bb.height() > maxHeight) continue;
102108

109+
final double area = contourArea(contour);
110+
if (area < minArea) continue;
111+
if (arcLength(contour, true) < minPerimeter) continue;
112+
113+
convexHull(contour, hull);
114+
final double solidity = 100 * area / contourArea(hull);
115+
if (solidity < minSolidity || solidity > maxSolidity) continue;
116+
103117
outputContours.put(filteredContourCount++, contour);
104118
}
105119

0 commit comments

Comments
 (0)